fre*_*ing 6 xcode nsstring cgsize swift
我想计算一个矩形的最小边界,以满足一个特定字体的字符串(多行).
它应该看起来像这样:
FROM:
----------------------------------
|Sent when the application is about|
|to move from active to inactive |
|state. |
----------------------------------
TO:
-------------------------
|Sent when the application|
|is about to move from |
|active to inactive state.|
-------------------------
Run Code Online (Sandbox Code Playgroud)
如您所见,高度保持不变,宽度变为必要的最小值.
最初我虽然我可以使用boundingRectWithSize(约束到最大宽度)首先获得所需的最小高度,然后调用boundingRectWithSize(约束到计算的高度)得到宽度.但是在第二步计算宽度时会产生错误的结果.它不考虑最大高度,而是简单计算单个线串的宽度.
之后我找到了一种方法来获得正确的结果,但执行此代码需要很长时间,这对我没用:
首先计算约束宽度所需的rect:
var objectFrame = Class.sizeOfString(string, font: objectFont, width: Double(width), height: DBL_MAX)
Run Code Online (Sandbox Code Playgroud)
那么宽度:
objectFrame.size.width = Class.minWidthForHeight(string, font: objectFont, objectFrame.size.height)
Run Code Online (Sandbox Code Playgroud)
使用:
class func minWidthForHeight(string: NSString, font: UIFont, height: CGFloat) -> CGFloat
{
let deltaWidth: CGFloat = 5.0
let neededHeight: CGFloat = rect.size.height
var testingWidth: CGFloat = rect.size.width
var done = false
while (done == false)
{
testingWidth -= deltaWidth
var newSize = Class.sizeOfString(string, font: font, width: Double(testingWidth), height: DBL_MAX)
if (newSize.height > neededHeight)
{
testingWidth += deltaWidth
done = true
}
}
return testingWidth
}
class func sizeOfString(string: NSString, font: UIFont, width: Double, height: Double) -> CGRect
{
return string.boundingRectWithSize(CGSize(width: width, height: height),
options: NSStringDrawingOptions.UsesLineFragmentOrigin,
attributes: [NSFontAttributeName: font],
context: nil)
}
Run Code Online (Sandbox Code Playgroud)
它逐渐计算给定宽度的高度(每个新步长为5.0像素)并检查高度是否保持不变.一旦高度改变,它就会返回上一步的宽度.所以现在我们有一个边界矩形,其中某个字体的字符串完全适合,没有任何浪费的空间.
但正如我所说,这需要很长的时间来计算,特别是在同时为许多不同的字符串执行时.
有没有更好更快的方法呢?
fre*_*ing -1
所以下面的代码是我解决手头问题的最终方法。它非常快并且对我来说效果很好。感谢@Nero 让我走上正轨。
class func minFrameWidthForHeight(string: NSString, font: UIFont, rect: CGRect) -> CGFloat
{
if (string.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).count <= 1)
{
return rect.size.width
}
var minValue: CGFloat = rect.size.width / 2
var maxValue: CGFloat = rect.size.width
var testingWidth: CGFloat = rect.size.width
var lastTestingWidth: CGFloat = testingWidth
let neededHeight: CGFloat = rect.size.height
var newSize = rect
while (newSize.height <= neededHeight)
{
lastTestingWidth = testingWidth
testingWidth = (maxValue + minValue) / 2
newSize = CalculationHelper.sizeOfString(string, font: font, width: Double(testingWidth), height: DBL_MAX)
if (newSize.height <= neededHeight)
{
maxValue = testingWidth
}
else
{
minValue = testingWidth
}
}
return lastTestingWidth
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
795 次 |
| 最近记录: |