Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 字符串容器大小,计算给定最大高度的最小宽度_Objective C_String_Cocoa_Swift - Fatal编程技术网

Objective c 字符串容器大小,计算给定最大高度的最小宽度

Objective c 字符串容器大小,计算给定最大高度的最小宽度,objective-c,string,cocoa,swift,Objective C,String,Cocoa,Swift,大多数安装格式化字符串的需求都需要计算一个容器的高度,该容器给定字符串的最大宽度。cocoa API中的此类函数反映了这一点,例如 NSTextField.sizeThatFits() 此方法将最大宽度视为固定宽度,并调整高度以包含文本 你会如何做与上述相反的事情-给定高度限制,计算出包含文本的最小宽度 我首先想到的一种方法是,首先创建一个估计值,将一行文本的面积除以所需的高度,得到一个估计的宽度。但这永远是对高度的高估,因为单词会被包裹起来,推动其他单词前进和下降。该算法的下一阶段,获取该多

大多数安装格式化字符串的需求都需要计算一个容器的高度,该容器给定字符串的最大宽度。cocoa API中的此类函数反映了这一点,例如

NSTextField.sizeThatFits()
此方法将最大宽度视为固定宽度,并调整高度以包含文本

你会如何做与上述相反的事情-给定高度限制,计算出包含文本的最小宽度

我首先想到的一种方法是,首先创建一个估计值,将一行文本的面积除以所需的高度,得到一个估计的宽度。但这永远是对高度的高估,因为单词会被包裹起来,推动其他单词前进和下降。该算法的下一阶段,获取该多余高度并将其添加到虚拟矩形的末端,直到最大高度限制被打破,从而给出宽度的上下估计值。算法的最后部分通过一种二进制搜索收敛,直到达到某个像素容差。当我可以的时候,我会把这个作为一个答案发布


我觉得一定有更好的办法?ObjC或Swift

获取属性字符串的高度和宽度,然后找出字符串高度符合您的高度限制的多少倍,然后将字符串宽度除以,如下所示:

NSAttributedString *myString = /*an attributed string*/
NSSize rawSize = myString.size; /*imagine a size of h20w100*/
int heightLimit = 40; /*example height limit*/
int linesAvailable = heightLimit/rawSize.height; /*gets the max number of lines available for the text*/
int neededWidth = rawSize.width/linesAvailable; /*gets the width of field needed to fit the whole text in the available height*/
NSSize fieldSize = NSMakeSize(needeWidth,heightLimit);
这将为您提供一个具有正确宽度的文本字段,以适应高度有限的字符串。在这种情况下,您将有两行可用,因此需要50的宽度。

计算给定最大高度的文本宽度:

这是一个对我来说很好的代码,当公差设置为5时,它平均计算3或4个尺寸。您可以替换为您喜欢的任何大小的计算函数,例如上面的函数。根据所需的松紧程度设置公差。希望这会有所帮助-如果您牺牲可读性多一点,它肯定会得到优化

func setLabelSize {

    var max_height = CGFloat(200) //This is the maximum height
    var big_float = CGFloat(99999)
    var width_estimate = big_float //This is the initial estimate

    var old_size = label.sizeThatFits(NSSize(width: width_estimate, height: big_float))

    width_estimate = old_size.width * old_size.height / max_height

    var new_size = label.sizeThatFits(NSSize(width: width_estimate, height: big_float))
    var old_width_estimate = width_estimate

    //first estimate will always be short, so loop until upper bound is found
    while (new_size.height < max_height) {
        old_width_estimate = width_estimate
        old_size = new_size

        var surpless_area = (new_size.height - max_height) * width_estimate
        width_estimate += (surpless_area / new_size.height) 

        new_size = label.sizeThatFits(NSSize(width: width_estimate, height: big_float))
        println("estimate: \(width_estimate) old_estimate: \(old_width_estimate) new_size: \(new_size) old_size: \(old_size)")
    }

    //value is inbetween old_width_estimate and width_estimate
    //width_estimate should be lower estimate, old should be higher
    var upper_estimate = old_width_estimate
    var lower_estimate = width_estimate
    var upper_estimate_size = old_size
    var tolerance = CGFloat(5)

    while(true) {

        var diff = (upper_estimate - lower_estimate) / 2
        println("upper: \(upper_estimate) lower: \(lower_estimate) diff: \(diff)")
        if diff <= tolerance {
            break
        } else {
            var half_estimate = lower_estimate + diff
            new_size = label.sizeThatFits(NSSize(width: half_estimate, height: big_float))
            if new_size.height>max_height {
                lower_estimate = half_estimate
            } else {
                upper_estimate = half_estimate
                upper_estimate_size = new_size
            }
        }
    }

    println("Final size \(upper_estimate_size)")

    label.frame.size = upper_estimate_size
}

这是一个开始,但将是准确的,因为单词包装使一些行必然更长,我还检查了单个长度字符串的高度并没有准确地划分为高度限制,因为多行之间由于间隔而具有更大的高度。谢谢你的回答!