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

问题描述

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

enter image description here

如您所见,它由标题和价格标签组成。标题可以有上百万行,但标题的顶部应与价格标签对齐。看起来设计很简单,但是有数百种解决方案。我尝试了每种方法,但是标题标签没有增加,因为末尾有点(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 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
        
    }
    
}

示例视图控制器类-从自定义视图的底部添加另一个标签,将标签限制在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$"
    }
}

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

enter image description here