Search code examples
iosswiftuitableviewuilabelnslayoutconstraint

Two UILabels side by side in UITableviewCell programmaticaly with priories in swift


I would like to put programmaticaly 2 labels side by side in forcing the full size for the second label:

sample

With my current code, depending of datas, sometimes, it works, sometimes the status label is crushed, and sometimes the first label stay in one line....

result

Currently I have these constraints (part as UITableViewCell):

NSLayoutConstraint.activate([

            /* the 2 labels */
            titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: margin),
            titleLabel.topAnchor.constraint(equalTo: topAnchor, constant: midMargin),
            titleLabel.trailingAnchor.constraint(lessThanOrEqualTo: sView.leadingAnchor, constant: -4),
            
            statusLabel.topAnchor.constraint(equalTo: topAnchor, constant: midMargin),
            statusLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -margin),
           
            /* the others views */
            dateLabel.topAnchor.constraint(equalTo: sView.bottomAnchor, constant: midMargin),
            dateLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -margin),
            dateLabel.leadingAnchor.constraint(greaterThanOrEqualTo: descriptionabel.trailingAnchor, constant: 4),
            
            descriptionabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: midMargin),
            descriptionabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: margin),
           
            askByTitleLabel.topAnchor.constraint(equalTo: descriptionabel.bottomAnchor, constant: midMargin),
            askByTitleLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: margin),
            askByTitleLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -margin),
            
            askByLabel.topAnchor.constraint(equalTo: askByTitleLabel.bottomAnchor, constant: .midMargin/2),
            askByLabel.leadingAnchor.constraint(equalTo: leadingAnchor, constant: margin),
            askByLabel.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -margin),
            
            docView.topAnchor.constraint(equalTo: askByLabel.bottomAnchor, constant: midMargin),
            docView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: margin),
            docView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -midMargin),
            docView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -.margin)
        ])

A idea of the problem ?


Solution

  • Make sure statusLabel is set to only 1 line. Set Hugging and Compression Resistance Priorities for statusLabel:

        statusLabel.numberOfLines = 1
        statusLabel.setContentHuggingPriority(.required, for: .horizontal)
        statusLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
    

    titleLabel.trailingAnchor should be relative to statusLabel.leadingAnchor:

        titleLabel.trailingAnchor.constraint(equalTo: statusLabel.leadingAnchor, constant: -4),
            
    

    A side note: it can be very helpful when developing your layout to give views (and labels) contrasting background colors... makes it very easy to see their frames at runtime.