Конфликт автопоставки при скрытии подпредставления UIStackview - PullRequest
0 голосов
/ 04 июня 2019

При скрытии подпредставлений UIStackview в tableviewcell иногда возникали конфликты автоматического размещения.

Я попытался также добавить ArrangedSubview и удалить ArrangedSubview вместо того, чтобы скрывать и показывать. Но это был тот же результат.

У uistackview есть четыре подпредставления. Я распечатал скрытый статус каждого подпредставления. Как вы можете видеть ниже, первый, второй, третий вид уже скрыт. Но autolayout не может получить этот статус. CellHeight установлен, как и ожидалось, 313 (базовая высота ячейки равна 157, высота каждого подпредставления 52. Так что 313). Я знаю причину возникшего конфликта в том, что высота ячейки уже установлена ​​как 313, но высота подпредставлений не равна 313. Поскольку второе и третье представления еще не распознаны.

Самое смешное, что интерфейс работает отлично. Просто предупреждения о конфликтах. и конфликт не происходит каждый раз. Иногда, когда я показываю второй вид, это происходит, иногда добавляется второй вид, но это не третий вид.

Я действительно хочу знать точную причину и устранить эти предупреждения.

Спасибо за вашу помощь.

firstChildAgeView.isHidden : NO
secondChildAgeView.isHidden : NO
thirdChildAgeView.isHidden : NO
forthChildAgeView.isHidden : YES

cellHeight : 313.0
2019-06-04 23:07:38.076484+0900 allstay[80237:18107365] [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:0x6000011c9a40 firstChildAgeView.height == 52   (active, names: firstChildAgeView:0x7fb68e0423c0 )>",
    "<NSLayoutConstraint:0x6000011c0aa0 V:|-(0)-[containerStackView]   (active, names: containerStackView:0x7fb68e03c6a0, '|':allstay.RoomCountViewCell:0x7fb68f898800'RoomCountViewCell' )>",
    "<NSLayoutConstraint:0x6000011c0b40 V:[containerStackView]-(10)-[UIView:0x7fb68e03c150]   (active, names: containerStackView:0x7fb68e03c6a0 )>",
    "<NSLayoutConstraint:0x6000011c0b90 UIView:0x7fb68e03c150.height == 1   (active)>",
    "<NSLayoutConstraint:0x6000011c0be0 V:[UIView:0x7fb68e03c150]-(0)-|   (active, names: '|':allstay.RoomCountViewCell:0x7fb68f898800'RoomCountViewCell' )>",
    "<NSLayoutConstraint:0x6000011c0e10 roomTitleContainerView.height == 32   (active, names: roomTitleContainerView:0x7fb68e03bbf0 )>",
    "<NSLayoutConstraint:0x6000011c0e60 roomAdultContainerView.height == 52   (active, names: roomAdultContainerView:0x7fb68e03b210 )>",
    "<NSLayoutConstraint:0x6000011c0eb0 roomChildrenContainerView.height == 52   (active, names: roomChildrenContainerView:0x7fb68e03bf70 )>",
    "<NSLayoutConstraint:0x6000011c28a0 'UISV-canvas-connection' containerStackView.top == roomTitleContainerView.top   (active, names: containerStackView:0x7fb68e03c6a0, roomTitleContainerView:0x7fb68e03bbf0 )>",
    "<NSLayoutConstraint:0x6000011c28f0 'UISV-canvas-connection' V:[firstChildAgeView]-(0)-|   (active, names: containerStackView:0x7fb68e03c6a0, firstChildAgeView:0x7fb68e0423c0, '|':containerStackView:0x7fb68e03c6a0 )>",
    "<NSLayoutConstraint:0x6000011c2940 'UISV-spacing' V:[roomTitleContainerView]-(10)-[roomAdultContainerView]   (active, names: roomAdultContainerView:0x7fb68e03b210, roomTitleContainerView:0x7fb68e03bbf0 )>",
    "<NSLayoutConstraint:0x6000011c2990 'UISV-spacing' V:[roomAdultContainerView]-(0)-[roomChildrenContainerView]   (active, names: roomChildrenContainerView:0x7fb68e03bf70, roomAdultContainerView:0x7fb68e03b210 )>",
    "<NSLayoutConstraint:0x6000011c29e0 'UISV-spacing' V:[roomChildrenContainerView]-(0)-[firstChildAgeView]   (active, names: firstChildAgeView:0x7fb68e0423c0, roomChildrenContainerView:0x7fb68e03bf70 )>",
    "<NSLayoutConstraint:0x6000011c30c0 'UIView-Encapsulated-Layout-Height' allstay.RoomCountViewCell:0x7fb68f898800'RoomCountViewCell'.height == 313   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000011c2940 'UISV-spacing' V:[roomTitleContainerView]-(10)-[roomAdultContainerView]   (active, names: roomAdultContainerView:0x7fb68e03b210, roomTitleContainerView:0x7fb68e03bbf0 )>

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.

РЕДАКТИРОВАТЬ: ОБНОВЛЕНИЕ КОДА

Это целый код для создания ячейки.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "countViewCell", for: indexPath) as! countViewCell
        countArray = info.getCount()

        cell.setupViews(vc: self, countInfo: countArray[indexPath.item], row:indexPath.item)

        if countArray.count == 1 {
            cell.removeCellButton.isHidden = true
        } else {
            cell.removeCellButton.isHidden = false
        }

        if countArray.count == 4 {
            countTableView.tableFooterView?.isHidden = true
        } else {
            countTableView.tableFooterView?.isHidden = false
        }

        return cell
    }

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        roomArray = info.getCount()
        let childrenCount = countArray[indexPath.item].components(separatedBy: ",").count - 1

        return 157 + CGFloat(childrenCount * 52)
    }

func changeChildrenCountRow(row:Int) {

        let range = Range(NSRange(location: 0, length: 1))

        let sectionToReload = IndexSet(integersIn: range!)
        countTableView.reloadSections(sectionToReload, with: .fade)
    }



cell class ----------------------------------------------------------

func setupViews(vc:countViewController, guestInfo:String, row:Int) {

        countViewController = vc

        numberLabel.text = "\(row+1)"

        let guestArray = guestInfo.components(separatedBy: ",")
        childrenCount = guestArray.count - 1
        adultCount = Int(guestArray[0])!

        adultCountLabel.text = "\(adultCount)"
        childrenCountLabel.text = "\(childrenCount)"

        setChildrenAgeViews()

        addSubview(containerStackView)
        addSubview(separatorView)
        containerStackView.addArrangedSubview(titleContainerView)
        containerStackView.addCustomSpacing(10, after: titleContainerView)
        containerStackView.addArrangedSubview(adultContainerView)
        containerStackView.addArrangedSubview(childrenContainerView)
        titleContainerView.addSubview(numberLabel)
        titleContainerView.addSubview(removeButton)
        adultContainerView.addSubview(adultLabel)
        adultContainerView.addSubview(reduceAdultCountButton)
        adultContainerView.addSubview(adultCountLabel)
        adultContainerView.addSubview(addAdultCountButton)
        childrenContainerView.addSubview(childrenLabel)
        childrenContainerView.addSubview(reduceChildrenCountButton)
        childrenContainerView.addSubview(childrenCountLabel)
        childrenContainerView.addSubview(addChildrenCountButton)

        firstChildAgeView.accessibilityIdentifier = "firstChildAgeView"
        secondChildAgeView.accessibilityIdentifier = "secondChildAgeView"
        thirdChildAgeView.accessibilityIdentifier = "thirdChildAgeView"
        forthChildAgeView.accessibilityIdentifier = "forthChildAgeView"
        titleContainerView.accessibilityIdentifier = "titleContainerView"
        adultContainerView.accessibilityIdentifier = "adultContainerView"
        childrenContainerView.accessibilityIdentifier = cChildrenContainerView"
        containerStackView.accessibilityIdentifier = "containerStackView"

        firstChildAgeView.addSubview(firstChildAgeButton)
        firstChildAgeView.addConstraintsWithFormat(format: "H:[v0(80)]-29-|", views: firstChildAgeButton)
        firstChildAgeView.addConstraintsWithFormat(format: "V:|[v0]|", views: firstChildAgeButton)

        secondChildAgeView.addSubview(secondChildAgeButton)
        secondChildAgeView.addConstraintsWithFormat(format: "H:[v0(80)]-29-|", views: secondChildAgeButton)
        secondChildAgeView.addConstraintsWithFormat(format: "V:|[v0]|", views: secondChildAgeButton)

        thirdChildAgeView.addSubview(thirdChildAgeButton)
        thirdChildAgeView.addConstraintsWithFormat(format: "H:[v0(80)]-29-|", views: thirdChildAgeButton)
        thirdChildAgeView.addConstraintsWithFormat(format: "V:|[v0]|", views: thirdChildAgeButton)

        forthChildAgeView.addSubview(forthChildAgeButton)
        forthChildAgeView.addConstraintsWithFormat(format: "H:[v0(80)]-29-|", views: forthChildAgeButton)
        forthChildAgeView.addConstraintsWithFormat(format: "V:|[v0]|", views: forthChildAgeButton)

        print("firstChildAgeView.isHidden : \(firstChildAgeView.isHidden ? "YES" : "NO")")
        print("secondChildAgeView.isHidden : \(secondChildAgeView.isHidden ? "YES" : "NO")")
        print("thirdChildAgeView.isHidden : \(thirdChildAgeView.isHidden ? "YES" : "NO")")
        print("forthChildAgeView.isHidden : \(forthChildAgeView.isHidden ? "YES" : "NO")")

        containerStackView.addArrangedSubview(firstChildAgeView)
        containerStackView.addConstraintsWithFormat(format: "H:|[v0]|", views: firstChildAgeView)
        containerStackView.addConstraintsWithFormat(format: "V:[v0(52)]", views: firstChildAgeView)
        containerStackView.addArrangedSubview(secondChildAgeView)
        containerStackView.addConstraintsWithFormat(format: "H:|[v0]|", views: secondChildAgeView)
        containerStackView.addConstraintsWithFormat(format: "V:[v0(52)]", views: secondChildAgeView)
        containerStackView.addArrangedSubview(thirdChildAgeView)
        containerStackView.addConstraintsWithFormat(format: "H:|[v0]|", views: thirdChildAgeView)
        containerStackView.addConstraintsWithFormat(format: "V:[v0(52)]", views: thirdChildAgeView)
        containerStackView.addArrangedSubview(forthChildAgeView)
        containerStackView.addConstraintsWithFormat(format: "H:|[v0]|", views: forthChildAgeView)
        containerStackView.addConstraintsWithFormat(format: "V:[v0(52)]", views: forthChildAgeView)

        addConstraintsWithFormat(format: "H:|[v0]|", views: containerStackView)
        addConstraintsWithFormat(format: "H:|[v0]|", views: separatorView)
        addConstraintsWithFormat(format: "V:|[v0]-10-[v1(1)]|", views: containerStackView, separatorView)

        let tempConstraint = NSLayoutConstraint(item: separatorView, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1, constant: 0)
        tempConstraint.priority = .defaultLow

        NSLayoutConstraint.activate([
            containerStackView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
            containerStackView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
            containerStackView.topAnchor.constraint(equalTo: self.topAnchor),
            containerStackView.bottomAnchor.constraint(equalTo: separatorView.topAnchor, constant: -10),
            separatorView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
            separatorView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
            separatorView.heightAnchor.constraint(equalToConstant: 1),
            tempConstraint
            ])

        containerStackView.addConstraintsWithFormat(format: "H:|[v0]|", views: titleContainerView)
        containerStackView.addConstraintsWithFormat(format: "H:|[v0]|", views: adultContainerView)
        containerStackView.addConstraintsWithFormat(format: "H:|[v0]|", c: childrenContainerView)
        containerStackView.addConstraintsWithFormat(format: "V:[v0(32)]", views: titleContainerView)
        containerStackView.addConstraintsWithFormat(format: "V:[v0(52)]", views: adultContainerView)
        containerStackView.addConstraintsWithFormat(format: "V:[v0(52)]", c: childrenContainerView)

        titleContainerView.addConstraintsWithFormat(format: "H:|-20-[v0][v1(100)]-20-|", views: numberLabel, removeButton)
        titleContainerView.addConstraintsWithFormat(format: "V:|[v0]|", views: numberLabel)
        titleContainerView.addConstraintsWithFormat(format: "V:|[v0]|", views: removeButton)

        adultContainerView.addConstraintsWithFormat(format: "H:|-20-[v0][v1(28)][v2(60)][v3(28)]-20-|", views: adultLabel, reduceAdultCountButton, adultCountLabel, addAdultCountButton)
        adultContainerView.addConstraintsWithFormat(format: "V:|[v0]|", views: adultLabel)
        adultContainerView.addConstraintsWithFormat(format: "V:|-12-[v0(28)]-12-|", views: reduceAdultCountButton)
        adultContainerView.addConstraintsWithFormat(format: "V:|[v0]|", views: adultCountLabel)
        adultContainerView.addConstraintsWithFormat(format: "V:|-12-[v0(28)]-12-|", views: addAdultCountButton)

        childrenContainerView.addConstraintsWithFormat(format: "H:|-20-[v0][v1(28)][v2(60)][v3(28)]-20-|", views: childrenLabel,
                                                           reduceChildrenCountButton, childrenCountLabel, addChildrenCountButton)
        childrenContainerView.addConstraintsWithFormat(format: "V:|[v0]|", views: childrenLabel)
        childrenContainerView.addConstraintsWithFormat(format: "V:|-12-[v0(28)]-12-|", views: reduceChildrenCountButton)
        childrenContainerView.addConstraintsWithFormat(format: "V:|[v0]|", views: childrenCountLabel)
        childrenContainerView.addConstraintsWithFormat(format: "V:|-12-[v0(28)]-12-|", views: addChildrenCountButton)

        removeButton.addTarget(self, action: #selector(remove), for: .touchUpInside)

        addAdultCountButton.addTarget(self, action: #selector(countChangeAction(sender:)), for: .touchUpInside)
        reduceAdultCountButton.addTarget(self, action: #selector(countChangeAction(sender:)), for: .touchUpInside)
        addChildrenCountButton.addTarget(self, action: #selector(countChangeAction(sender:)), for: .touchUpInside)
        reduceChildrenCountButton.addTarget(self, action: #selector(countChangeAction(sender:)), for: .touchUpInside)

    }

func setChildrenAgeViews() {
        var childrenViewArray = [firstChildAgeView, secondChildAgeView, thirdChildAgeView, forthChildAgeView]
        for index in 0..<4 {
            if index < childrenCount {
                childrenViewArray[index].isHidden = false
            } else {
                childrenViewArray[index].isHidden = true
            }
        }
    }

РЕДАКТИРОВАТЬ 2: Обновить предупреждающее сообщение

"<NSLayoutConstraint:0x6000023699a0 V:|-(0)-[containerStackView]   (active, names: containerStackView:0x7fa33ad23270, '|':allstay.RoomCountViewCell:0x7fa33c068600'RoomCountViewCell' )>",
    "<NSLayoutConstraint:0x600002369900 V:[containerStackView]-(10)-[UIView:0x7fa33ad3d6f0]   (active, names: containerStackView:0x7fa33ad23270 )>",
    "<NSLayoutConstraint:0x6000023698b0 UIView:0x7fa33ad3d6f0.height == 1   (active)>",
    "<NSLayoutConstraint:0x600002369860 V:[UIView:0x7fa33ad3d6f0]-(0)-|   (active, names: '|':allstay.RoomCountViewCell:0x7fa33c068600'RoomCountViewCell' )>",
    "<NSLayoutConstraint:0x600002369540 roomTitleContainerView.height == 32   (active, names: roomTitleContainerView:0x7fa33ad3c880 )>",
    "<NSLayoutConstraint:0x600002369590 roomAdultContainerView.height == 52   (active, names: roomAdultContainerView:0x7fa33ad3d0e0 )>",
    "<NSLayoutConstraint:0x6000023692c0 roomChildrenContainerView.height == 52   (active, names: roomChildrenContainerView:0x7fa33ad3d510 )>",
    "<NSLayoutConstraint:0x600002369630 firstChildAgeView.height == 52   (active, names: firstChildAgeView:0x7fa33ad435c0 )>",
    "<NSLayoutConstraint:0x60000236ac10 secondChildAgeView.height == 52   (active, names: secondChildAgeView:0x7fa33ad43bd0 )>",
    "<NSLayoutConstraint:0x60000237ae90 'UISV-canvas-connection' containerStackView.top == roomTitleContainerView.top   (active, names: containerStackView:0x7fa33ad23270, roomTitleContainerView:0x7fa33ad3c880 )>",
    "<NSLayoutConstraint:0x60000236c140 'UISV-canvas-connection' V:[secondChildAgeView]-(0)-|   (active, names: containerStackView:0x7fa33ad23270, secondChildAgeView:0x7fa33ad43bd0, '|':containerStackView:0x7fa33ad23270 )>",
    "<NSLayoutConstraint:0x60000236c4b0 'UISV-spacing' V:[roomTitleContainerView]-(10)-[roomAdultContainerView]   (active, names: roomAdultContainerView:0x7fa33ad3d0e0, roomTitleContainerView:0x7fa33ad3c880 )>",
    "<NSLayoutConstraint:0x60000236c500 'UISV-spacing' V:[roomAdultContainerView]-(0)-[roomChildrenContainerView]   (active, names: roomChildrenContainerView:0x7fa33ad3d510, roomAdultContainerView:0x7fa33ad3d0e0 )>",
    "<NSLayoutConstraint:0x60000236c550 'UISV-spacing' V:[roomChildrenContainerView]-(0)-[firstChildAgeView]   (active, names: firstChildAgeView:0x7fa33ad435c0, roomChildrenContainerView:0x7fa33ad3d510 )>",
    "<NSLayoutConstraint:0x60000236c5a0 'UISV-spacing' V:[firstChildAgeView]-(0)-[secondChildAgeView]   (active, names: secondChildAgeView:0x7fa33ad43bd0, firstChildAgeView:0x7fa33ad435c0 )>",
    "<NSLayoutConstraint:0x6000023777f0 'UIView-Encapsulated-Layout-Height' allstay.RoomCountViewCell:0x7fa33c068600'RoomCountViewCell'.height == 365   (active)>"

1 Ответ

1 голос
/ 05 июня 2019

Первое, что бросается в глаза: избавься от своей heightForRowAt функции.Разрешить автоматическому макету обрабатывать высоту ячейки на основе надлежащих ограничений содержимого ячейки.

Это выглядит , как будто вы на правильном пути.Если я понимаю ваш макет, у вас есть:

  • containerStackView (который содержит некоторые упорядоченные подпредставления) и
  • separatorView

в качестведва элемента «верхнего уровня» в вашей клетке.Вы ограничиваете:

  • top из containerStackView до top ячейки,
  • bottom из containerStackView до верхней из separatorView и
  • нижней из separatorView до нижней изячейка

Который должен удовлетворять автоматической компоновке и позволяет автоматически обрабатывать высоты строк - вообще не нужно вычислять в heightForRowAt.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...