根据标签高度

时间:2016-11-23 08:20:41

标签: ios iphone autolayout xib uisegmentedcontrol

我的应用中有一个UISegmentControl。我添加了所有必需的约束,并将其高度约束设置为>= 40。控制有3个部分。问题是我从服务器获取段标题数据,它可以是任何长度。当段标题超过一行时,文本将被截断。

我通过添加以下代码解决了这个问题: -

[[UILabel appearanceWhenContainedIn:[UISegmentedControl class], nil] setNumberOfLines:0];

标题长度为2行时,它可以正常工作。真正的问题是在标题长度超过2行并且文本再次被截断时开始,理想情况下UISegmentControl应该通过检查其内容压缩属性来增加其高度以容纳更长的平铺,如UILabel。我尝试通过更改优先级的值来播放contentCompression抵抗属性但是徒劳无功。 UISegmentControl不会自动调整大小以容纳更大的文字。任何想法如何使用自动布局实现所需的行为。

1 个答案:

答案 0 :(得分:0)

我只会说Swift,所以我希望这有帮助。

要动态调整分段控件的高度,您需要做很多事情。

1.像这样对UILable进行扩展:

import Foundation
import UIKit

    extension UILabel{
        var defaultNumberOfLines: Int{
            get{return self.numberOfLines}
            set{self.numberOfLines = newValue}
        }

        var defaultFont: UIFont{
            get {return self.font}
            set{self.font = newValue}
        }
    }

2.计算将包含您的字符串的边界矩形。此矩形的高度将决定分段控件的高度。您可以使用NSString或NSAttributedString但不是String的实例来计算字符串的边界矩形。我在“getHeightForSegControl(withString:withWidth :)”方法中计算了边界矩形。

3.在计算字符串的边界矩形时,您还必须记住使用与UILabel相同的字体,否则您的文本会由于明显的差异而被截断...

4.在方法viewWillLayoutSubviews()中设置框架。这很重要,因为无论何时将新文本设置为段,都需要调用超级视图的setNeedsLayout()来计算生成的边界文本以及分段控件的相应大小。

在下面的代码中,如果您将实例成员“text”的值更改为任意长度的字符串,则分段控件将相应地更新其高度:

import UIKit

class ViewController: UIViewController {
    var segmentedControl: UISegmentedControl!
    var text = "This is a text that is supposed to dynamically change the height of an instance of UISegmentedControl"
    override func viewDidLoad() {
        super.viewDidLoad()
        setUpSegmentedControl()
        UILabel.appearance().defaultNumberOfLines = 0
        UILabel.appearance().defaultFont = UIFont.boldSystemFont(ofSize: 15)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func viewWillLayoutSubviews() {

        segmentedControl.frame = CGRect(x: view.bounds.size.width / 2 - 100, y: view.bounds.size.height / 2 - (getHeightForSegControl(withString: text, withLabelWidth: 100) / 2), width: 200, height: getHeightForSegControl(withString: text, withLabelWidth: 100))
    }

    func setUpSegmentedControl(){
        segmentedControl = UISegmentedControl(items: [text, "Oranges"])
        view.addSubview(segmentedControl)
    }

    func getHeightForSegControl(withString string: String, withLabelWidth width: CGFloat) -> CGFloat {
        let nsString: NSString = string as NSString
        let size: CGSize = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
        let boundingRectSize = nsString.boundingRect(with: size, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSFontAttributeName: UILabel.appearance().defaultFont], context: nil).size

        print(ceil(boundingRectSize.height))
        return ceil(boundingRectSize.height)
    }

}

结果:

enter image description here

P.S。这假设你想要一个固定的宽度。如果你还想要一个动态宽度...这是一个不同的故事。