gpt4 book ai didi

ios - 隐藏 UIStackview 的 subview 时自动布局冲突

转载 作者:行者123 更新时间:2023-11-28 13:37:24 28 4
gpt4 key购买 nike

在tableviewcell中隐藏UIStackview的 subview 时,有时会发生autolayout冲突。

我还尝试了 addArrangedSubview 和 removeArrangedSubview 而不是隐藏和取消隐藏。但结果是一样的。

uistackview 有四个 subview 。我打印了每个 subview 的隐藏状态。正如您在下面看到的,第一、第二、第三 View 已经取消隐藏。但是自动布局无法获得该状态。 CellHeight 按预期设置,313(基本单元格高度为 157,每个 subview 的高度为 52。因此为 313)。我知道发生冲突的原因是单元格高度已设置为 313,但 subview 的高度不是 313。因为第二个和第三个 View 尚未被识别。

有趣的是 UI 完美运行。只是冲突警告。并且冲突并非每次都发生。有时当我取消隐藏第二个 View 时,它发生了,有时添加第二个 View 是好的,但不是第三个 View 。

我真的很想知道确切的原因并消除警告。

感谢您的帮助。

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)>"

最佳答案

首先让我印象深刻的是:去掉你的 heightForRowAt 函数。允许自动布局根据单元格内容的适当约束来处理单元格高度。

不过,看起来您的方向是对的。如果我理解你的布局,你有:

  • containerStackView(其中包含一些已排列的 subview ),以及
  • separatorView

作为单元格中的两个“顶级”元素。您正在限制:

  • containerStackViewtop 到 cell 的top
  • containerStackView底部separatorView顶部,以及
  • separatorViewbottom到cell的bottom

哪个应该满足自动布局,并允许自动处理行高——根本不需要在 heightForRowAt 中计算。

关于ios - 隐藏 UIStackview 的 subview 时自动布局冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56445834/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com