简体   繁体   中英

ios autolayout dynamic UILabel height

Say I have three UILabels whose positions are like below:

[Label1] [Label2]

[Label3]

Label1 and Label2 are in the same row and Label3 is below them. All the labels will have a fixed width and will contain dynamic text, so their height will vary.

How do I make the Label3 10 points below the label which has a higher height using AutoLayout?

For example, if Label1 's height is 100 points, Label2 's height is 120 points (their Y positions are the same), then Label3 should be 10 points below Label2 , but if Label1 is 120 points high and Label2 is 100 points high, then Label3 should be 10 points below Label1 .

You simply make constraints between both Label3->Label1 and Label3->Label2. Use inequality constraints. There will be only one way to satisfy both!

You will also need a top constraint for Label3; its constant should be very small and its priority should be very low. This will give the two inequality constraints something to "aim at".

Here is an example. This as achieved entirely without code - the buttons have code to add text to the labels, of course, but the constraints are configured entirely in Interface Builder; the labels are resizing, and the bottom label is moving down, automatically . (You can construct the same layout in code if you want to, naturally.)

在此处输入图片说明

I suggest you to wrap top two label s to UIView and setup constraints so these label s fit all space inside that view . Then you simple add vertical spacing constraint to bottom label3 with constant = 10 . In that case top view will have size of larger label and will satisfy your conditions

I thought this would be an interesting exercise so I create a little test project. The gist of the code is below. You can just copy/paste it in the standard Single View iOS template.

(Note that I use SnapKit for programmatic Auto Layout because it is so much simpler than the UIKit API. I find it even much simpler than doing things in Xcode.)

The result is exactly the same as Matt's great screencast.

// ViewController.swift

import UIKit
import SnapKit

class ViewController: UIViewController
{
    override func viewDidLoad() {
        super.viewDidLoad()

        let leftLabel = UILabel()
        leftLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "addText:"))
        leftLabel.userInteractionEnabled = true
        view.addSubview(leftLabel)
        leftLabel.numberOfLines = 0
        leftLabel.text = "All the world's a stage, and all the men and women merely players: they have their exits and their entrances; and one man in his time plays many parts, his acts being seven ages."
        leftLabel.snp_makeConstraints { (make) -> Void in
            make.top.equalTo(40)
            make.left.equalTo(self.view)
            make.right.equalTo(self.view.snp_centerX)
        }

        let rightLabel = UILabel()
        rightLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "addText:"))
        rightLabel.userInteractionEnabled = true
        view.addSubview(rightLabel)
        rightLabel.numberOfLines = 0
        rightLabel.text = "There is a tide in the affairs of men, Which taken at the flood, leads on to fortune. Omitted, all the voyage of their life is bound in shallows and in miseries. On such a full sea are we now afloat. And we must take the current when it serves, or lose our ventures."
        rightLabel.snp_makeConstraints { (make) -> Void in
            make.top.equalTo(40)
            make.right.equalTo(self.view)
            make.left.equalTo(self.view.snp_centerX)
        }

        let bottomView = UIView()
        view.addSubview(bottomView)
        bottomView.backgroundColor = UIColor.redColor()
        bottomView.snp_makeConstraints { (make) -> Void in
            make.height.equalTo(20)
            make.left.right.equalTo(self.view)
            make.top.greaterThanOrEqualTo(leftLabel.snp_bottom)
            make.top.greaterThanOrEqualTo(rightLabel.snp_bottom)
        }
    }

    @objc func addText(recognizer: UIGestureRecognizer) {
        if let label = recognizer.view as? UILabel {
            label.text = label.text! + " I like cheese."
        }
    }
}

Updated the code to add some additional text to the labels when tapped.

First of all remove height constraints and set all 3 labels vertical Content Compression Resistance Priority to 1000 . This is the most important part.

Then add vertical space from Label3 to Label 1, and set instead of Equal, Greater Than or Equal with priority say 500. Add same space constraint to Label2.

Last add constraint from Label3 to Top = 0, but set priority to 1.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM