iosswiftuitableviewuitableviewdiffabledatasource

Using UITableViewDiffableDatasource in UITableView, Add or DeleteCell -> Warning Cell Constraints


When Cell initializer called function

    private func configureUI() {
        [dateLabel, previewLabel].forEach {
            contentsStackView.addArrangedSubview($0)
        }
        
        [titleLabel, contentsStackView].forEach {
            mainStackView.addArrangedSubview($0)
        }
        
        contentView.addSubview(mainStackView)
    }
    
    private func setUpConstraints() {
        NSLayoutConstraint.activate([
            mainStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),
            mainStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),
            mainStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5),
            mainStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5)
        ])
        
        dateLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
        previewLabel.setContentHuggingPriority(.init(1), for: .horizontal)
    }
    
    private func setUpAccessory() {
        accessoryType = .disclosureIndicator
    }

Add or Delete Cell Warning Log Message

2023-09-05 19:52:06.961611+0900 Diary[7318:185913] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<NSLayoutConstraint:0x600000118050 V:|-(5)-[UIStackView:0x13c70e940]   (active, names: '|':UITableViewCellContentView:0x13c71acd0 )>",
    "<NSLayoutConstraint:0x6000001180a0 UIStackView:0x13c70e940.bottom == UITableViewCellContentView:0x13c71acd0.bottom - 5   (active)>",
    "<NSLayoutConstraint:0x60000011f9d0 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x13c71acd0.height == 0   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000001180a0 UIStackView:0x13c70e940.bottom == UITableViewCellContentView:0x13c71acd0.bottom - 5   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

When you swipe the TableViewCell, the above Log Warning occurs, and when you Delete and scroll the screen, it appears to be a warning that occurs as the Cell is reused.

Since there is no warning when the TableView is first exposed, I don't think it is a problem with the constraints inside the cell. I'm confused because the Warning Message is listed as a problem related to Constraints.

Answering Forward Questions


Solution

  • Delete

    mainStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5)
    

    Instead, create this constraint, assign it a priority of 999, and then activate it.

    So, your code will say:

    private func setUpConstraints() {
        NSLayoutConstraint.activate([
            mainStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),
            mainStackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),
            mainStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5),
        ])
        let bottomConstraint = mainStackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5)
        bottomConstraint.priority = .init(999)
        bottomConstraint.isActive = true
        dateLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
        previewLabel.setContentHuggingPriority(.init(1), for: .horizontal)
    }