6

文字列 (複数行) を特定のフォントに合わせるために必要な四角形の最小境界を計算したいと考えています。

次のようになります。

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.|
 -------------------------

ご覧のとおり、高さは同じままで、幅は必要な最小値に変更されます。

最初は、boundingRectWithSize(最大幅への制約)を使用して最初に必要な最小の高さを取得し、次にboundingRectWithSize(計算された高さへの制約)を呼び出して幅を取得することができました。しかし、これは 2 番目のステップで幅を計算するときに間違った結果をもたらします。最大高さは考慮されませんが、単一の線ストリングの幅が単純に計算されます。

その後、適切な結果を得る方法を見つけましたが、このコードの実行には非常に時間がかかるため、役に立ちません。

最初に、制約幅に必要な rect を計算します。

var objectFrame = Class.sizeOfString(string, font: objectFont, width: Double(width), height: DBL_MAX)

次に幅:

objectFrame.size.width = Class.minWidthForHeight(string, font: objectFont, objectFrame.size.height)

使用:

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)
}

指定された幅 (新しいステップごとに - 5.0 ピクセル) の高さを徐々に計算し、高さが同じかどうかをチェックします。高さが変わるとすぐに、前のステップの幅を返します。これで、特定のフォントの文字列が無駄なスペースなしで完全に収まる境界四角形ができました。

しかし、私が言ったように、これは計算に非常に長い時間がかかります。特に、多くの異なる文字列に対して同時に計算を行う場合はそうです。

これを行うためのより良い、より速い方法はありますか?

4

1 に答える 1

-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
}
于 2014-12-29T10:59:15.780 に答える