我收到 UITableViewCell 中 UILable 的布局约束错误。我的应用程序是一个待办事项列表,我有一个 UITableView,其中包含不同高度的 UITableViewCell。如果我缓慢地将单元格拖到底部并且页面开始滚动,则会收到错误。 see video of error condition
这是我收到的错误:
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.
2022-03-12 11:18:28.445423-0800 Action[83734:5205929] [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:0x600003361590 V:|-(14)-[UILabel:0x1541a05d0] (active, names: '|':UITableViewCellContentView:0x15419ef60 )>",
"<NSLayoutConstraint:0x600003361680 V:[UILabel:0x1541a05d0]-(14)-| (active, names: '|':UITableViewCellContentView:0x15419ef60 )>",
"<NSLayoutConstraint:0x600003361bd0 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x15419ef60.height == 0 (active)>"
)
我按照建议设置了一个符号断点并获取了此附加信息(第 4 行有“AMBIGUOUS LAYOUT”):
| | | | | | | *<UILayoutGuide: 0x600003f7c380 - "UIViewSafeAreaLayoutGuide", layoutFrame = {{0, 94}, {375, 684}}, owningView = <UIView: 0x132006ea0; frame = (0 0; 375 812); autoresize = W+H; layer = <CALayer: 0x600000679480>>>
| | | | | | | *UIView:0x132007010
| | | | | | | | *UITableView:0x13300c000
| | | | | | | | | *<UIFocusContainerGuide: 0x60000396c4b0 - "UITableViewContentFocusContainerGuide", layoutFrame = {{0, 0}, {375, 684}}, owningView = <UITableView: 0x13300c000; frame = (0 0; 375 684); clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x6000008dc5a0>; layer = <CALayer: 0x6000006597e0>; contentOffset: {0, 0}; contentSize: {375, 2783.9999949137377}; adjustedContentInset: {0, 0, 0, 0}; dataSource: <Action.ProjectController: 0x130e085e0>>>- AMBIGUOUS LAYOUT for UIFocusContainerGuide:0x60000396c4b0'UITableViewContentFocusContainerGuide'.minX{id: 3169}, UIFocusContainerGuide:0x60000396c4b0'UITableViewContentFocusContainerGuide'.minY{id: 3170}, UIFocusContainerGuide:0x60000396c4b0'UITableViewContentFocusContainerGuide'.Width{id: 3171}, UIFocusContainerGuide:0x60000396c4b0'UITableViewContentFocusContainerGuide'.Height{id: 3172}
| | | | | | | | | Action.ActionCellView:0x12f0a1600'ReusableCell'
| | | | | | | | | | _UISystemBackgroundView:0x12de973f0
| | | | | | | | | | | UIView:0x12de95f90
| | | | | | | | | | •UITableViewCellContentView:0x12de962a0
| | | | | | | | | | | *UIButton:0x12de96440
| | | | | | | | | | | | _UISystemBackgroundView:0x12de968e0
| | | | | | | | | | | | UIImageView:0x12de96700
| | | | | | | | | | | *UILabel:0x12de96aa0
| | | | | | | | | | _UITableViewCellSeparatorView:0x12de97080
| | | | | | | | | | _UITableViewCellSeparatorView:0x12de99c70
| | | | | | | | | | _UITableViewCellSeparatorView:0x1309081d0
以下是我在 Controller 的 viewDidLoad 中设置表格 View 的方法:
tableView.register(UINib(nibName: K.Action.cellNibName, bundle: nil), forCellReuseIdentifier: K.Action.cellIdentifier)
tableView.dataSource = self
tableView.dragDelegate = self
tableView.dropDelegate = self
tableView.delegate = self
tableView.showsVerticalScrollIndicator = false
这是 UITableViewDataSource 实现:
extension ProjectController: UITableViewDataSource {
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return tableView.rowHeight
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let project = model.projects.data[projectId!] {
return project.actionIds.count
}
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: K.Action.cellIdentifier, for: indexPath) as! ActionCellView
if let project = model.projects.data[projectId!] {
let actionId = project.actionIds[indexPath.row]
let action = model.actions.data[actionId]!
cell.titleLabel.text = action.title
cell.delegate = self
cell.actionId = actionId
if action.scheduled != nil {
cell.label = action.scheduled!.toString()
}
}
return cell
}
}
我还实现了 UITableViewDragDelegate:
extension ProjectController: UITableViewDragDelegate {
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
let dragItem = UIDragItem(itemProvider: NSItemProvider())
return [ dragItem ]
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let project = model.projects.data[projectId!]!
let actionId = project.actionIds[sourceIndexPath.row]
model.moveAction(actionId, inProject: projectId!, toRank: destinationIndexPath.row)
}
}
最佳答案
按照 https://stackoverflow.com/a/36949580/10426153 中的建议,我能够通过将标签底部 anchor 的优先级从 1000 更改为 999 来解决此问题。
但是,这会导致这样的情况:如果我向下拖动单元格以使页面滚动,然后向上拖动,则拖动单元格最初所在位置下方的单元格将具有扩展且不正确的高度。在这种情况下,标签的底部 anchor 似乎被取消了优先级(正如预期的那样,优先级较低),但结果是奇怪的高度。
我认为 @matt 表示还有另一个可以解决的根本原因,但是,我不太确定那是什么。
关于TableView 单元格中的 iOS 布局约束冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71452396/