如何通过对齐 iOS 中的顶部边缘来水平放置两个标签?

How to put two labels horizontally by aligning their top edges in iOS?

我想创建如下自定义视图。

如您所见,它由标题和价格标签组成。标题可以有百万行,但其上边缘应与价格标签对齐。看似简单的设计,却有成百上千的解决方案。我尝试了每一个,但我的标题标签没有增长,最后有点(numberOfLines = 0 没有帮助)。以下是我创建此类设计的方法:

  1. 我创建了带有顶部、前导、尾随价格标签、底部约束的 titleLabel。此外,我创建了带有顶部和尾部约束的价格标签,只是为了对齐它们的顶部边缘。我将抗压和拥抱优先分配给价格标签,因为它更重要,不应该被破坏。如果需要,这里是代码:

     addSubview(titleLabel)
     addSubview(priceLabel)
     titleLabel.snp.makeConstraints { make in
         make.leading.equalToSuperview().offset(16)
         make.trailing.lessThanOrEqualTo(priceLabel.snp.leading).offset(-8)
         make.top.equalToSuperview()
         make.bottom.equalToSuperview()
     }
     priceLabel.snp.makeConstraints { make in
         make.trailing.equalToSuperview().offset(-16)
         make.top.equalTo(titleLabel.snp.top)
     }
    

我创建了单独的自定义视图,因为我想在 StackView(间距 8,分布填充,垂直)中使用它。这种方法的结果:标题标签没有增长。如果有大文本,它只有一行末尾有点。

  1. 第二种方法是创建 stackView(水平,间距 8,分布填充,对齐顶部)。我设置对齐顶部以对齐标签的顶部边缘。结果与方法 #1 中的一样。

如何解决这个问题?我哪里错了?看来我在这里没有看到自动布局理论中的核心内容。

为带有
的标题标签添加一个new height constraint 关系greater than equal to
contant:一些常量(可能是 20 或基于您的字体大小和内容的东西)。

希望这能解决您的问题

在布局开发过程中,对元素背景使用对比色会非常有帮助...可以真正轻松地查看它们的框架发生了什么。

试试这个...

自定义视图class

class NeoCustomView: UIView {
    
    let titleLabel = UILabel()
    let priceLabel = UILabel()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    func commonInit() -> Void {
        
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        titleLabel.numberOfLines = 0
        titleLabel.font = .systemFont(ofSize: 17)
        
        priceLabel.translatesAutoresizingMaskIntoConstraints = false
        priceLabel.font = .boldSystemFont(ofSize: 17)
        
        priceLabel.setContentHuggingPriority(.required, for: .horizontal)
        priceLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
        
        addSubview(titleLabel)
        addSubview(priceLabel)
        
        titleLabel.snp.makeConstraints { make in
            make.leading.equalToSuperview().offset(16)
            make.trailing.lessThanOrEqualTo(priceLabel.snp.leading).offset(-8)
            make.top.equalToSuperview()
            make.bottom.equalToSuperview()
        }
        priceLabel.snp.makeConstraints { make in
            make.trailing.equalToSuperview().offset(-16)
            make.top.equalTo(titleLabel.snp.top)
        }

        // use some background colors so we can easily see the frames
        backgroundColor = .red
        titleLabel.backgroundColor = .yellow
        priceLabel.backgroundColor = .green
        
    }
    
}

示例视图控制器class - 从自定义视图的底部添加另一个标签约束 4 点,以便我们可以看到一切正常:

class NeoViewController: UIViewController {
    
    let testView = NeoCustomView()
    let anotherLabel = UILabel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        anotherLabel.translatesAutoresizingMaskIntoConstraints = false
        anotherLabel.font = .systemFont(ofSize: 15)
        anotherLabel.backgroundColor = .blue
        anotherLabel.textColor = .white
        anotherLabel.textAlignment = .center
        anotherLabel.numberOfLines = 0
        anotherLabel.text = "This label is constrained 4 points from the bottom of the custom view."
        
        view.addSubview(testView)
        view.addSubview(anotherLabel)
        
        testView.snp.makeConstraints { make in
            make.leading.trailing.equalTo(view.safeAreaLayoutGuide).inset(16)
            make.top.equalTo(view.safeAreaLayoutGuide).offset(40)
        }
        anotherLabel.snp.makeConstraints { make in
            make.top.equalTo(testView.snp.bottom).offset(4)
            make.width.equalTo(testView.snp.width)
            make.centerX.equalTo(testView.snp.centerX)
        }
        
        testView.titleLabel.text = "This is long text for the title label that will word wrap when it needs to."
        testView.priceLabel.text = "300$"
    }
}

结果(红色是带有标题和价格标签的自定义视图,蓝色是添加并限制在自定义视图下方的标签):