【问题标题】:Why doesn't sizeThatFits work with UILabel?为什么 sizeThatFits 不能与 UILabel 一起使用?
【发布时间】:2018-03-09 07:02:26
【问题描述】:

我有一个简单的类,它在堆栈中包含两个标签和一行:

class TestView: UIView
{
    let label_A     = UILabel()
    let label_B     = UILabel()

    override init(frame: CGRect)            { super.init(frame: frame);     setup() }
    required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder);  setup() }
    func setup()
    {
        let view_BG     = UIView()
        let view_LineH  = UIView()

        // Configure
        view_BG.backgroundColor = .white
        view_BG.layer.cornerRadius = 6

        view_LineH.backgroundColor = .gray

        label_A.numberOfLines = 0
        label_A.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.2)
        label_A.textColor = .red
        label_B.numberOfLines = 0
        label_B.textColor = .blue
        label_B.backgroundColor = UIColor(red: 0, green: 0, blue: 1, alpha: 0.2)

        label_A.text = "TestA"
        label_B.text = "Experiment with Swift standard library types and learn high-level concepts using visualizations and practical examples. Learn how the Swift standard library uses protocols and generics to express powerful constraints. Download the playground below to get started."

        // Assemble
        self.addSubview(view_BG)
        view_BG.addSubview(label_A)
        view_BG.addSubview(view_LineH)
        view_BG.addSubview(label_B)

        // Layout
        view_BG.constrain_edges(to: self)
        label_A.constrain_edges(to: view_BG, excludingEdge: .bottom)
        label_B.constrain_edges(to: view_BG, excludingEdge: .top)

        view_LineH.constrain_height(1)
        view_LineH.constrain_left(to: view_BG)
        view_LineH.constrain_right(to: view_BG)
        view_LineH.constrain_topToBottom(of: label_A)
        label_B.constrain_topToBottom(of: view_LineH)
    }
}

当我调用 sizeThatFits 时,它只会向我吐出高度:

let v = TestView()
let s = v.sizeThatFits(CGSize(width: 200, height: 10000))
// s is (200, 10000)

如何计算给定宽度的所需高度?

【问题讨论】:

  • 它给你回报是有道理的。 TestView 中的所有约束都被约束到边缘。但是你还没有设置TestView 的框架。因此,给定内部所有内容的未知帧大小,您如何确定包含所有内容的正确帧大小?你不能。
  • 那么在sizeThatFits中指定一个width和一个height有什么意义呢?如果我只指定一个,那将是模棱两可的。即使我在 sizeThatFits 调用之前添加类似: v.frame = CGRect(x: 0, y: 0, width: columnWidth, height: 100) ,结果也是一样的。

标签: ios swift uiview autolayout uilabel


【解决方案1】:

相信你想要.systemLayoutSizeFitting():

    let tv = TestView()

    let targSize = CGSize(width: 200, height: 10000)

    let fitSize = tv.systemLayoutSizeFitting(targSize, withHorizontalFittingPriority: 1000, verticalFittingPriority: 1)

    print(fitSize)

    // prints "(200.0, 245.0)" in my playground

我没有你用于.constrain_edges 的东西,所以这是我正在运行的实际视图类:

class TestView: UIView
{
    let label_A     = UILabel()
    let label_B     = UILabel()

    override init(frame: CGRect)            { super.init(frame: frame);     setup() }
    required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder);  setup() }
    func setup()
    {
        let view_BG     = UIView()
        let view_LineH  = UIView()

        // Configure
        view_BG.backgroundColor = .white
        view_BG.layer.cornerRadius = 6

        view_LineH.backgroundColor = .gray

        label_A.numberOfLines = 0
        label_A.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 0.2)
        label_A.textColor = .red
        label_B.numberOfLines = 0
        label_B.textColor = .blue
        label_B.backgroundColor = UIColor(red: 0, green: 0, blue: 1, alpha: 0.2)

        label_A.text = "TestA"
        label_B.text = "Experiment with Swift standard library types and learn high-level concepts using visualizations and practical examples. Learn how the Swift standard library uses protocols and generics to express powerful constraints. Download the playground below to get started."

        // Assemble
        self.addSubview(view_BG)
        view_BG.addSubview(label_A)
        view_BG.addSubview(view_LineH)
        view_BG.addSubview(label_B)

        view_BG.translatesAutoresizingMaskIntoConstraints = false
        label_A.translatesAutoresizingMaskIntoConstraints = false
        label_B.translatesAutoresizingMaskIntoConstraints = false
        view_LineH.translatesAutoresizingMaskIntoConstraints = false

        // Layout
        view_BG.topAnchor.constraint(equalTo: self.topAnchor, constant: 0.0).isActive = true
        view_BG.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 0.0).isActive = true
        view_BG.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 0.0).isActive = true
        view_BG.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0.0).isActive = true


        label_A.topAnchor.constraint(equalTo: view_BG.topAnchor, constant: 0.0).isActive = true
        label_A.leftAnchor.constraint(equalTo: view_BG.leftAnchor, constant: 0.0).isActive = true
        label_A.rightAnchor.constraint(equalTo: view_BG.rightAnchor, constant: 0.0).isActive = true

        label_B.leftAnchor.constraint(equalTo: view_BG.leftAnchor, constant: 0.0).isActive = true
        label_B.rightAnchor.constraint(equalTo: view_BG.rightAnchor, constant: 0.0).isActive = true
        label_B.bottomAnchor.constraint(equalTo: view_BG.bottomAnchor, constant: 0.0).isActive = true

        view_LineH.leftAnchor.constraint(equalTo: view_BG.leftAnchor, constant: 0.0).isActive = true
        view_LineH.rightAnchor.constraint(equalTo: view_BG.rightAnchor, constant: 0.0).isActive = true

        view_LineH.topAnchor.constraint(equalTo: label_A.bottomAnchor, constant: 0.0).isActive = true
        label_B.topAnchor.constraint(equalTo: view_LineH.bottomAnchor, constant: 0.0).isActive = true

        view_LineH.heightAnchor.constraint(equalToConstant: 1.0).isActive = true

    }
}

【讨论】:

  • 这很奇怪,它给了我 (0, 285.5)。为了使其编译,我必须将参数设置为: let fitSize = c.systemLayoutSizeFitting(targetSize, withHorizo​​ntalFittingPriority: .required, verticalFittingPriority: .defaultLow)
  • 不知道是否与约束有关,但我添加了我正在运行的实际类来测试它。
  • 嗯....可能版本不同?我在 Xcode 8.2.1 操场上运行它。如果您使用的是 Xcode 9 / Swift 4,那可能很重要。
  • 我不确定。实际上,我犯了一个错误,我也设置了每个标签的preferredMaxLayoutWidth属性来得到我的结果。如果我删除那条线,它对我来说又回到 (200,10000)。也许是环境的不同?
  • 注释掉您的preferredMaxLayoutWidth 属性分配,并尝试将verticalFittingPriority 更改为UILayoutPriorityFittingSizeLevel(可能是.fittingSizeLevel)。
猜你喜欢
  • 2013-11-06
  • 2011-04-30
  • 2021-06-14
  • 2012-10-09
  • 2020-03-18
  • 2017-11-21
  • 2019-04-11
  • 2012-09-19
  • 2013-12-30
相关资源
最近更新 更多