【问题标题】:UIView resize to fit labels inside of itUIView 调整大小以适应其中的标签
【发布时间】:2018-05-24 21:39:33
【问题描述】:

我有一个 UIView,我将其附加到我的应用主页上的堆栈视图中

这是我的观点类:

class MyCustomView: UIView {
    public let leftLabel: UILabel = UILabel(frame: .zero)
    public let rightLabel: UILabel = UILabel(frame: .zero)

    override init(frame: CGRect) {
        super.init(frame: frame)

        addSubview(leftLabel)
        addSubview(rightLabel)

        leftLabel.translatesAutoresizingMaskIntoConstraints = false
        rightLabel.translatesAutoresizingMaskIntoConstraints = false

        NSLayoutConstraint.activate([
            leftLabel.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.4),
            leftLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
            leftLabel.topAnchor.constraint(equalTo: topAnchor),
            leftLabel.bottomAnchor.constraint(equalTo: bottomAnchor),

            rightLabel.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.6),
            rightLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
            rightLabel.topAnchor.constraint(equalTo: topAnchor),
            rightLabel.bottomAnchor.constraint(equalTo: bottomAnchor),
        ])
        leftLabel.text = "Short string"
        rightLabel.text = "Short string too"
    }
}

我在我的主堆栈视图中附加: let myCustomView = MyCustomView(frame: .zero) stackView.addArrangedSubview(myCustomView)

这会正确加载我的标签并根据需要调整所有内容的大小。

但是,在我的主课中,我正在更新myCustomView.rightLabel.text = <New Way Longer Text That Takes 2 Lines Instead of One>

文本正在正确更新,但我的myCustomView 大小未调整大小,因此部分文本被截断

我已尝试在此处关注其他答案,但它们似乎都不适合我。

为了强制调整 customView 的大小以适应其中的标签,我是否遗漏了一些小东西?

提前谢谢你

【问题讨论】:

    标签: swift uiview autolayout resize constraints


    【解决方案1】:

    您的代码未显示您将标签中的.numberOfLines 设置为0 以允许使用多行标签。

    仅添加这一点,应该允许您的标签增加高度并扩展您的自定义视图。但是...这也会使两个标签都扩展到最高标签的大小,从而导致“较短”标签的文本垂直居中(我添加了背景颜色以方便查看视图的框架/边界):

    如果您将自定义视图的底部限制为 greaterThanOrEqualTo 处每个标签的底部,您可以保持标签“顶部对齐”:

    您可以直接在 Playground 页面中运行此代码以查看结果:

    //: A UIKit based Playground for presenting user interface
    
    import UIKit
    import PlaygroundSupport
    
    class MyCustomView: UIView {
        public let leftLabel: UILabel = UILabel(frame: .zero)
        public let rightLabel: UILabel = UILabel(frame: .zero)
    
        override init(frame: CGRect) {
            super.init(frame: frame)
    
            addSubview(leftLabel)
            addSubview(rightLabel)
    
            // background colors so we can see the view frames
            backgroundColor = .cyan
    
            leftLabel.backgroundColor = .yellow
            rightLabel.backgroundColor = .green
    
            // we want multi-line labels
            leftLabel.numberOfLines = 0
            rightLabel.numberOfLines = 0
    
            // use auto-layout
            leftLabel.translatesAutoresizingMaskIntoConstraints = false
            rightLabel.translatesAutoresizingMaskIntoConstraints = false
    
            NSLayoutConstraint.activate([
                // constrain to top
                leftLabel.topAnchor.constraint(equalTo: topAnchor),
                // constrain to left
                leftLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
                // constrain width = 40%
                leftLabel.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.4),
    
                // constrain to top
                rightLabel.topAnchor.constraint(equalTo: topAnchor),
                // constrain to right
                rightLabel.trailingAnchor.constraint(equalTo: trailingAnchor),
                // constrain width = 60%
                rightLabel.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.6),
    
                // constrain bottom of view (self) to >= 0 from bottom of leftLabel
                bottomAnchor.constraint(greaterThanOrEqualTo: leftLabel.bottomAnchor, constant: 0.0),
                // constrain bottom of view (self) to >= 0 from bottom of rightLabel
                bottomAnchor.constraint(greaterThanOrEqualTo: rightLabel.bottomAnchor, constant: 0.0),
                ])
    
            leftLabel.text = "Short string"
            rightLabel.text = "Short string too"
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }
    
    class MyViewController : UIViewController {
    
        var theButton: UIButton = {
            let b = UIButton()
            b.setTitle("Tap Me", for: .normal)
            b.translatesAutoresizingMaskIntoConstraints = false
            b.backgroundColor = .red
            return b
        }()
    
        var theStackView: UIStackView = {
            let v = UIStackView()
            v.translatesAutoresizingMaskIntoConstraints = false
            v.axis = .vertical
            v.spacing = 8
            v.distribution = .equalSpacing
            return v
        }()
    
        var myView = MyCustomView()
    
        // on button tap, change the text in the label(s)
        @objc func didTap(_ sender: Any?) -> Void {
            myView.leftLabel.text = "Short string with\nA\nB\nC\nD\nE"
            myView.rightLabel.text = "Short string too\nA\nB"
        }
    
        override func loadView() {
            let view = UIView()
            self.view = view
    
            view.backgroundColor = .white
    
            view.addSubview(theButton)
            // constrain button to Top: 32 and centerX
            NSLayoutConstraint.activate([
                theButton.topAnchor.constraint(equalTo: view.topAnchor, constant: 32.0),
                theButton.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0.0),
                ])
    
            view.addSubview(theStackView)
    
            // constrain stack view to Top: 100 and Leading/Trailing" 0
            // no Bottom or Height constraint
            NSLayoutConstraint.activate([
                theStackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100.0),
                theStackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0),
                theStackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0.0),
                ])
    
            theStackView.addArrangedSubview(myView)
    
            // add an action for the button tap
            theButton.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)
    
        }
    }
    
    // Present the view controller in the Live View window
    PlaygroundPage.current.liveView = MyViewController()
    

    【讨论】:

      猜你喜欢
      • 2012-07-22
      • 1970-01-01
      • 2021-05-21
      • 1970-01-01
      • 1970-01-01
      • 2015-07-07
      • 1970-01-01
      • 2015-11-17
      • 2017-06-24
      相关资源
      最近更新 更多