代码之家  ›  专栏  ›  技术社区  ›  Frankenstein

当帧小于要求时,为UIStackView中的第一个UILabel赋予更高的优先级

  •  -1
  • Frankenstein  · 技术社区  · 4 年前

    [UILabel] UIStackView 在他们身上打圈。在某一点上 UILabel s超过了 UIStackView公司 UILabel公司

    screenshot

    我想 text 1 text 2

    override func viewDidLoad() {
        super.viewDidLoad()
    
        let stackView = UIStackView()
        stackView.alignment = .top
        stackView.axis = .vertical
    
        view.addSubview(stackView)
        stackView.center = view.center
        stackView.frame.size = CGSize(width: 100, height: 24)
    
        (0..<4).forEach {
            let label = UILabel()
            label.text = "text \($0)"
            label.backgroundColor = .red
            stackView.addArrangedSubview(label)
        }
    }
    

    更新:多亏了@DonMag和@Rob,我在代码中设置了内容压缩阻力优先级。不幸的是,由于某种原因,我得到了与@DonMag截图中描述的不同的结果。以下是我更新的代码:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        let stackView = UIStackView()
        stackView.alignment = .leading
        stackView.axis = .vertical
    
        view.addSubview(stackView)
        stackView.frame = CGRect(x: 100, y: 100, width: 100, height: 150)
    
        (0..<15).forEach {
            let label = UILabel()
            label.text = "text \($0)"
            label.backgroundColor = .red
            stackView.addArrangedSubview(label)
        }
        var p: Float = 1000
        for v in stackView.arrangedSubviews {
            v.setContentCompressionResistancePriority(UILayoutPriority(rawValue: p), for: .vertical)
            p -= 1
        }
    }
    

    screenshot 2

    0 回复  |  直到 4 年前
        1
  •  1
  •   DonMag    4 年前

    这应该做到:

        var p: Float = 1000
        for v in stackView.arrangedSubviews {
            v.setContentCompressionResistancePriority(UILayoutPriority(rawValue: p), for: .vertical)
            p -= 1
        }
        
    

    不过,使用堆栈视图有点奇怪,它可能最终不能满足您的需要。

    例如,使用 100 x 150 框架和14个标签,我们得到:

    enter image description here

    正如我们所见,底部的标签有点“关闭”

    而且,只有5个标签,我们得到:

    enter image description here

    顶部标签的高度会被拉长,除非我们用内容优先权做同样的事情。。。在这种情况下,底部标签会被拉伸。

    更好的方法是将堆栈视图嵌入 UIView UIView公司 .clipsToBounds = true

    有14个标签:

    enter image description here

    enter image description here

    下面是要玩的代码。。。

    方法1:

    class FrankMethod1ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            
            let stackView = UIStackView()
            stackView.alignment = .leading
            stackView.axis = .vertical
            
            view.addSubview(stackView)
            stackView.frame = CGRect(x: 100, y: 100, width: 100, height: 150)
            
            // change to (0..<5) to see the stretching
            (0..<15).forEach {
                let label = UILabel()
                label.text = "text \($0)"
                label.backgroundColor = .red
                stackView.addArrangedSubview(label)
            }
    
            var p: Float = 1000
            for v in stackView.arrangedSubviews {
                v.setContentCompressionResistancePriority(UILayoutPriority(rawValue: p), for: .vertical)
                p -= 1
            }
    
        }
    
    }
    

    class FrankMethod2ViewController: UIViewController {
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            let cView = UIView()
            cView.frame = CGRect(x: 100, y: 100, width: 100, height: 150)
            cView.clipsToBounds = true
            
            // so we can see the view frame
            cView.backgroundColor = .cyan
            
            view.addSubview(cView)
            
            let stackView = UIStackView()
            stackView.alignment = .leading
            stackView.axis = .vertical
            
            cView.addSubview(stackView)
            
            stackView.translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                stackView.topAnchor.constraint(equalTo: cView.topAnchor),
                stackView.leadingAnchor.constraint(equalTo: cView.leadingAnchor),
                stackView.trailingAnchor.constraint(equalTo: cView.trailingAnchor),
            ])
            
            // change to (0..<5) to see NO stretching
            (0..<15).forEach {
                let label = UILabel()
                label.text = "text \($0)"
                label.backgroundColor = .red
                stackView.addArrangedSubview(label)
            }
            
        }
        
    }
    

    编辑

    我得到的是:

    enter image description here

    import UIKit
    import PlaygroundSupport
    
    class PlaygroundFrankViewController: UIViewController {
    
        override func loadView() {
            let view = UIView()
            view.backgroundColor = .white
            self.view = view
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()
            
            let stackView1 = UIStackView()
            stackView1.alignment = .leading
            stackView1.axis = .vertical
            
            view.addSubview(stackView1)
            stackView1.frame = CGRect(x: 50, y: 50, width: 100, height: 150)
            
            // change to (0..<5) to see the stretching
            (0..<15).forEach {
                let label = UILabel()
                label.text = "text \($0)"
                label.backgroundColor = .red
                stackView1.addArrangedSubview(label)
            }
            
            var p: Float = 1000
            for v in stackView1.arrangedSubviews {
                v.setContentCompressionResistancePriority(UILayoutPriority(rawValue: p), for: .vertical)
                p -= 1
            }
    
            let stackView2 = UIStackView()
            stackView2.alignment = .leading
            stackView2.axis = .vertical
            
            view.addSubview(stackView2)
            stackView2.frame = CGRect(x: 200, y: 50, width: 100, height: 150)
            
            // change to (0..<5) to see the stretching
            (0..<5).forEach {
                let label = UILabel()
                label.text = "text \($0)"
                label.backgroundColor = .red
                stackView2.addArrangedSubview(label)
            }
            
            p = 1000
            for v in stackView2.arrangedSubviews {
                v.setContentCompressionResistancePriority(UILayoutPriority(rawValue: p), for: .vertical)
                p -= 1
            }
            
            
            let cView1 = UIView()
            cView1.frame = CGRect(x: 50, y: 220, width: 100, height: 150)
            cView1.clipsToBounds = true
            
            // so we can see the view frame
            cView1.backgroundColor = .cyan
            
            view.addSubview(cView1)
            
            let stackView3 = UIStackView()
            stackView3.alignment = .leading
            stackView3.axis = .vertical
            
            cView1.addSubview(stackView3)
            
            stackView3.translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                stackView3.topAnchor.constraint(equalTo: cView1.topAnchor),
                stackView3.leadingAnchor.constraint(equalTo: cView1.leadingAnchor),
                stackView3.trailingAnchor.constraint(equalTo: cView1.trailingAnchor),
            ])
            
            // change to (0..<5) to see NO stretching
            (0..<15).forEach {
                let label = UILabel()
                label.text = "text \($0)"
                label.backgroundColor = .red
                stackView3.addArrangedSubview(label)
            }
            
            let cView2 = UIView()
            cView2.frame = CGRect(x: 200, y: 220, width: 100, height: 150)
            cView2.clipsToBounds = true
            
            // so we can see the view frame
            cView2.backgroundColor = .cyan
            
            view.addSubview(cView2)
            
            let stackView4 = UIStackView()
            stackView4.alignment = .leading
            stackView4.axis = .vertical
            
            cView2.addSubview(stackView4)
            
            stackView4.translatesAutoresizingMaskIntoConstraints = false
            NSLayoutConstraint.activate([
                stackView4.topAnchor.constraint(equalTo: cView2.topAnchor),
                stackView4.leadingAnchor.constraint(equalTo: cView2.leadingAnchor),
                stackView4.trailingAnchor.constraint(equalTo: cView2.trailingAnchor),
            ])
            
            // change to (0..<5) to see NO stretching
            (0..<5).forEach {
                let label = UILabel()
                label.text = "text \($0)"
                label.backgroundColor = .red
                stackView4.addArrangedSubview(label)
            }
    
        }
        
    }
    
    // Present the view controller in the Live View window
    PlaygroundPage.current.liveView = PlaygroundFrankViewController()