【问题标题】:Unable to properly arrange two UILabels in a Stackview in Swift programatically无法以编程方式在 Swift 的堆栈视图中正确排列两个标签
【发布时间】:2018-06-22 06:15:35
【问题描述】:

这是我的层次结构:

  1. 将包含行的垂直 Stackview (mystack)
  2. 视图、包装器(父视图)
  3. 将包含两个标签的水平 Stackview (stacktmp)
  4. 标签 x2 (tx, tx2)

另外:mystack 有 4 个约束:前导、尾随、顶部和底部与“安全视图”相同。

代码:

let parentview = UIView()
parentview.backgroundColor = UIColor.cyan
let stacktmp = UIStackView()
stacktmp.axis = .horizontal

let tx = UILabel()
tx.text = "ss"
tx.backgroundColor = UIColor.red
tx.font = UIFont.boldSystemFont(ofSize: 19)

let tx2 = UILabel()
tx2.text = "This is a long sentence to check whether the view and the stackview adapt successfully to the length of this label."
//tx2.numberOfLines = 0
stacktmp.addArrangedSubview(tx)
stacktmp.addArrangedSubview(tx2)

parentview.addSubview(stacktmp)

stacktmp.translatesAutoresizingMaskIntoConstraints = false
print(parentview.frame.size.height)
stacktmp.topAnchor.constraint(equalTo: parentview.topAnchor).isActive = true
stacktmp.heightAnchor.constraint(equalTo:    parentview.heightAnchor).isActive = true

mystack.addArrangedSubview(parentview)

stacktmp.trailingAnchor.constraint(equalTo: parentview.trailingAnchor, constant: 0).isActive = true
stacktmp.leadingAnchor.constraint(equalTo: parentview.leadingAnchor, constant: 0).isActive = true

我得到了什么:

我的目标:

如果需要,我希望第二个标签的句子将单词分开并在下面多行填写。

我尝试添加以下行:tx2.numberOfLines = 0(在代码中注释)

结果我得到了:

它确实按照我的意愿拆分了句子,但现在第一个标签不必要地扩展了。

如何在保持第一个标签尽可能窄的同时允许第二个标签在必要时使用多行?我已经尝试修复这个问题几个小时了,已经尝试更改约束,但我仍然无法修复它。

【问题讨论】:

  • 您要查找的内容称为 HuggingPriority 和 CompressionResistance。一开始可能很难理解,但是有很多博客文章可以让它更容易 - 只需谷歌它。

标签: swift autolayout


【解决方案1】:

如前所述,拥抱和抗压优先级是有帮助的(需要)。

这应该可以得到你想要的:

override func viewDidLoad() {
    super.viewDidLoad()

    // create parentview
    let parentview = UIView()
    parentview.translatesAutoresizingMaskIntoConstraints = false
    parentview.backgroundColor = UIColor.cyan

    // add parentview to view
    view.addSubview(parentview)

    // constrain parentview to Zero all the way around
    parentview.topAnchor.constraint(equalTo: view.topAnchor, constant: 0.0).isActive = true
    parentview.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0.0).isActive = true
    parentview.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0).isActive = true
    parentview.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0.0).isActive = true

    // create stack view
    let stacktmp = UIStackView()
    stacktmp.translatesAutoresizingMaskIntoConstraints = false
    stacktmp.axis = .horizontal

    // add stack view to parentview
    parentview.addSubview(stacktmp)

    // constrain stack view top / leading / trailing at Zero, height equal to parentview height
    stacktmp.topAnchor.constraint(equalTo: parentview.topAnchor, constant: 0.0).isActive = true
    stacktmp.leadingAnchor.constraint(equalTo: parentview.leadingAnchor, constant: 0.0).isActive = true
    stacktmp.trailingAnchor.constraint(equalTo: parentview.trailingAnchor, constant: 0.0).isActive = true
    stacktmp.heightAnchor.constraint(equalTo: parentview.heightAnchor).isActive = true

    // create "left" label
    let tx = UILabel()
    tx.text = "ss"
    tx.backgroundColor = UIColor.red
    tx.font = UIFont.boldSystemFont(ofSize: 19)

    // set Content Hugging to 252
    tx.setContentHuggingPriority(UILayoutPriority(rawValue: 252), for: .horizontal)
    // set Content Compression Resistance to 1000
    tx.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 1000), for: .horizontal)

    // create "right" label
    let tx2 = UILabel()
    tx2.text = "This is a long sentence to check whether the view and the stackview adapt successfully to the length of this label."
    // Zero lines, to get word wrapping
    tx2.numberOfLines = 0

    // set Content Hugging to 252
    tx2.setContentHuggingPriority(UILayoutPriority(rawValue: 252), for: .horizontal)
    // set Content Compression Resistance to 1000
    tx2.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 1000), for: .horizontal)

    // add labels to stack view
    stacktmp.addArrangedSubview(tx)
    stacktmp.addArrangedSubview(tx2)

}

结果:

【讨论】:

    【解决方案2】:

    试试这个

    import UIKit
    
    class stackQueryVC: UIViewController {
    
        /// Width Height
        let height = UIScreen.main.bounds.height
        let width = UIScreen.main.bounds.width
    
        private var mainStackView: UIStackView?
        private var internalView1: UIView?
        private var internalView2: UIView?
        private var label1 : UILabel?
        private var label2 : UILabel?
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Do any additional setup after loading the view.
            DispatchQueue.main.async {
                self.addStackView()
            }
        }
    
        func addStackView(){
            mainStackView = UIStackView()
            internalView1 = UIView()
            internalView2 = UIView()
            label1 = UILabel()
            label2 = UILabel()
    
            label1?.text = "ios-geek"
            label2?.text = "qwerykgasgdasgdhgashdgjasgdasgdjahsdjahsgdasdjagsjdahsgdjsdhasd"
            label1?.numberOfLines = 0
            label2?.numberOfLines = 0
            label1?.textColor = UIColor.black
            label2?.textColor = UIColor.black
    
            /// Set Translation Properties
            mainStackView?.translatesAutoresizingMaskIntoConstraints = false
            internalView1?.translatesAutoresizingMaskIntoConstraints = false
            internalView2?.translatesAutoresizingMaskIntoConstraints = false
            label1?.translatesAutoresizingMaskIntoConstraints = false
            label2?.translatesAutoresizingMaskIntoConstraints = false
    
            addContentView()
        }
    
        func addContentView(){
    
            /// Add Stack View Constraints
            mainStackView?.backgroundColor = UIColor.white
            self.view.addSubview(mainStackView!)
            mainStackView?.topAnchor.constraint(equalTo: self.view.topAnchor).isActive=true
            mainStackView?.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive=true
            mainStackView?.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive=true
            mainStackView?.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive=true
    
            /// Add First StackView
            mainStackView?.distribution = .fillEqually
            mainStackView?.axis = .horizontal
            mainStackView?.alignment = .center
            mainStackView?.spacing = 10
            mainStackView?.backgroundColor = UIColor.white
    
            /// View Properties
            internalView1?.backgroundColor = .red
            internalView2?.backgroundColor = .purple
    
            /// Add Views
            mainStackView?.addArrangedSubview(internalView1!)
            internalView1?.topAnchor.constraint(equalTo: mainStackView!.topAnchor).isActive=true
            internalView1?.bottomAnchor.constraint(equalTo: mainStackView!.bottomAnchor).isActive=true
            internalView1?.leadingAnchor.constraint(equalTo: mainStackView!.leadingAnchor).isActive=true
    
            mainStackView?.addArrangedSubview(internalView2!)
            internalView2?.leadingAnchor.constraint(equalTo: internalView1!.trailingAnchor).isActive=true
            internalView2?.bottomAnchor.constraint(equalTo: internalView1!.bottomAnchor).isActive=true
            internalView2?.topAnchor.constraint(equalTo: internalView1!.topAnchor).isActive=true
    
            /// Add Labels
            internalView1?.addSubview(label1!)
            label1?.topAnchor.constraint(equalTo: internalView1!.topAnchor).isActive=true
            label1?.bottomAnchor.constraint(equalTo: internalView1!.bottomAnchor).isActive=true
            label1?.leadingAnchor.constraint(equalTo: internalView1!.leadingAnchor).isActive=true
            label1?.trailingAnchor.constraint(equalTo: internalView1!.trailingAnchor).isActive=true
    
            internalView2?.addSubview(label2!)
            label2?.topAnchor.constraint(equalTo: internalView2!.topAnchor).isActive=true
            label2?.bottomAnchor.constraint(equalTo: internalView2!.bottomAnchor).isActive=true
            label2?.leadingAnchor.constraint(equalTo: internalView2!.leadingAnchor).isActive=true
            label2?.trailingAnchor.constraint(equalTo: internalView2!.trailingAnchor).isActive=true
        }
    }
    

    选项2如果你只想直接添加UILabels

    private var totalNumberOfLabels : Int?
    
    func addStackView(){
        mainStackView = UIStackView()
        label1 = UILabel()
        label2 = UILabel()
    
        label1?.text = "ios-geek"
        label2?.text = "qwerykgasgdasgdhgashdgjasgdasgdjahsdjahsgdasdjagsjdahsgdjsdhasd"
        label1?.numberOfLines = 0
        label2?.numberOfLines = 0
        label1?.textColor = UIColor.black
        label2?.textColor = UIColor.black
        label1?.backgroundColor = .red
        label2?.backgroundColor = .purple
    
        /// Set Translation Properties
        mainStackView?.translatesAutoresizingMaskIntoConstraints = false
        label1?.translatesAutoresizingMaskIntoConstraints = false
        label2?.translatesAutoresizingMaskIntoConstraints = false
    
        addContentView()
    }
    
    func addContentView(){
    
        /// Add Stack View Constraints
        mainStackView?.backgroundColor = UIColor.white
        self.view.addSubview(mainStackView!)
        mainStackView?.topAnchor.constraint(equalTo: self.view.topAnchor).isActive=true
        mainStackView?.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive=true
        mainStackView?.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive=true
        mainStackView?.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive=true
    
        /// Add First StackView
        mainStackView?.distribution = .fillEqually
        mainStackView?.axis = .horizontal
        mainStackView?.alignment = .center
        mainStackView?.spacing = 10
        mainStackView?.backgroundColor = UIColor.white
    
        /// Add Views
        mainStackView?.addArrangedSubview(label1!)
        label1?.topAnchor.constraint(equalTo: mainStackView!.topAnchor).isActive=true
        label1?.bottomAnchor.constraint(equalTo: mainStackView!.bottomAnchor).isActive=true
        label1?.leadingAnchor.constraint(equalTo: mainStackView!.leadingAnchor).isActive=true
        label1?.widthAnchor.constraint(equalToConstant: width/CGFloat(totalNumberOfLabels!)).isActive=true
    
        mainStackView?.addArrangedSubview(label2!)
        label2?.topAnchor.constraint(equalTo: label1!.topAnchor).isActive=true
        label2?.bottomAnchor.constraint(equalTo: label1!.bottomAnchor).isActive=true
        label2?.leadingAnchor.constraint(equalTo: label1!.trailingAnchor).isActive=true
        label1?.widthAnchor.constraint(equalToConstant: width/CGFloat(totalNumberOfLabels!)).isActive=true
    }
    

    输出

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多