TableView 单元格中的 iOS 布局约束冲突

标签 ios swift uitableview autolayout

我收到 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)
    }
}

Screenshot of Table View constraints

Screenshot of Table View cell Label constraints

最佳答案

按照 https://stackoverflow.com/a/36949580/10426153 中的建议,我能够通过将标签底部 anchor 的优先级从 1000 更改为 999 来解决此问题。

但是,这会导致这样的情况:如果我向下拖动单元格以使页面滚动,然后向上拖动,则拖动单元格最初所在位置下方的单元格将具有扩展且不正确的高度。在这种情况下,标签的底部 anchor 似乎被取消了优先级(正如预期的那样,优先级较低),但结果是奇怪的高度。

我认为 @matt 表示还有另一个可以解决的根本原因,但是,我不太确定那是什么。

关于TableView 单元格中的 iOS 布局约束冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71452396/

相关文章:

ios - 如何使用 EKEventViewController 在我的应用程序中显示 EKEvent 邀请的详细信息?

ios - 使用 Swift 最佳实践解析 PFUser 子类注册

ios - Swift segue 不会将数据传递给旧的 ViewController

ios - 删除屏幕外的 UITableView 的索引路径 - indexPath.row 大于我的数组的大小

ios - iOS联系人备份我们需要保存的文件扩展名

ios - Swift 从 UITableViewCell 中删除存储在 UITableViewController 中的数据

ios - 应用程序委托(delegate)检查所有 View Controller 转换何时完成

ios - 如何在 Collection View 单元格中插入图像

swift - 使用 DispatchGroup 相对于基本计数器类的好处

uitableview - 设置 UITableView 节标题的样式