在我将内容滚动出屏幕之前,单元格约束不会处于活动状态 - 自动维度表视图 - Swift 5

Posted

技术标签:

【中文标题】在我将内容滚动出屏幕之前,单元格约束不会处于活动状态 - 自动维度表视图 - Swift 5【英文标题】:Cell constraints won't be active until I scroll content off the screen - automatic dimension Table view - Swift 5 【发布时间】:2021-06-18 10:39:33 【问题描述】:

我有一个UITableView,它使用单元格内容约束来使用UITableView.automaticDimension 自动生成单元格高度。

这是来自我的UIViewController 的一些代码(我只粘贴了最重要的方法):

     lazy var tableView = UITableView(frame: CGRect.zero, style: .grouped)

     override func viewDidLoad() 
        super.viewDidLoad()
                    
        tableView.delegate = self
        tableView.dataSource = self
        
        tableView.backgroundColor = .clear
        
        tableView.estimatedRowHeight = 112
        tableView.rowHeight = UITableView.automaticDimension
        
        tableView.sectionHeaderHeight = 50
        
        tableView.register(TransactionCell.self, forCellReuseIdentifier: TransactionCell.reuseId)
        tableView.register(TransactionsHeaderView.self, forHeaderFooterViewReuseIdentifier: TransactionsHeaderView.reuseId)
        
        tableView.contentInsetAdjustmentBehavior = .never
        
        view.addSubview(tableView)
        
        // <--> setting up my data here... <-->

        tableView.reloadData()
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        
        guard let cell = tableView.dequeueReusableCell(withIdentifier: TransactionCell.reuseId, for: indexPath) as? TransactionCell  else 
            fatalError("The dequeued cell is not an instance of TableViewCell.")
        
        
        cell.transaction = sections[indexPath.section].transactions[indexPath.row]
        cell.layoutIfNeeded()
        return cell
    

   func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
        return UITableView.automaticDimension
    

然后我有我的自定义UITableViewCell 类:

    lazy var backgroundBox = RoundShadowView()
    lazy var cellView = TransactionCellView()
    lazy var detailView = TransactionCellDetailView()

    private func commonInit() 
        
        selectionStyle = .none
        
        backgroundColor = .clear
        contentView.backgroundColor = .clear
        
        backgroundBox.layer.cornerRadius = 10
        backgroundBox.shouldRasterize = false
        backgroundBox.insets = UIEdgeInsets(top: 15, left: SAFE_AREA_MARGIN, bottom: 15, right: SAFE_AREA_MARGIN)
        
        detailView.alpha = 0
        detailView.addTopBorder()
        
        backgroundBox.translatesAutoresizingMaskIntoConstraints = false
        cellView.translatesAutoresizingMaskIntoConstraints = false
        detailView.translatesAutoresizingMaskIntoConstraints = false
                
        contentView.addSubview(backgroundBox)
        backgroundBox.addSubview(cellView)
        backgroundBox.addSubview(detailView)
    

    override func updateConstraints() 
        super.updateConstraints()

        print(#function)
                
        backgroundBox.snp.remakeConstraints  make in
            make.left.equalToSuperview()
            make.right.equalToSuperview()
            make.top.equalToSuperview().priority(999)
            make.bottom.equalToSuperview()
            make.height.equalTo(111).priority(999)
        
        
        cellView.snp.remakeConstraints  make in
            make.left.equalToSuperview().offset(SAFE_AREA_MARGIN)
            make.right.equalToSuperview().inset(SAFE_AREA_MARGIN)
            make.top.equalToSuperview().offset(15)
            make.height.equalTo(111)
        

        detailView.snp.remakeConstraints  make in
            make.left.equalToSuperview().offset(SAFE_AREA_MARGIN)
            make.right.equalToSuperview().inset(SAFE_AREA_MARGIN)
            make.top.equalTo(cellView.snp.bottom)
            make.bottom.equalToSuperview()
        
        
    

我正在使用SnapKit 库进行约束。

如您所见,我设置了顶部、底部和高度约束来强制 UITableViewCell 增加其高度。

问题是,当我构建和运行时,我的视图布局已设置,但单元格高度尚未计算。 但是,如果我滚动直到一个单元格不可见并且我向下滚动,它的高度是根据我的约束计算的。 第一次如何计算单元格高度?

【问题讨论】:

你可以在这里看到我对此感到困惑:biteinteractive.com/… @matt 但是他不应该在添加子视图后立即设置约束吗? @Desdenova,没错,在添加子视图后立即添加 setNeedsUpdateConstraints() 即可。但这很奇怪。 【参考方案1】:

正如@Desdenova 所说,在添加子视图后立即添加setNeedsUpdateConstraints() 解决了我的问题。

【讨论】:

以上是关于在我将内容滚动出屏幕之前,单元格约束不会处于活动状态 - 自动维度表视图 - Swift 5的主要内容,如果未能解决你的问题,请参考以下文章

向下滚动时不会出现 Swift Expandable tableView 单元格按钮

Swift 包中的 XIB 文件 - 忽略约束

在我滚动之前,数据不会加载到 UITableView 中

如何在滚动时将单元格的内容保留在屏幕上,直到单元格用完可用空间?

UICollectionView,单元格选择不起作用,单元格滚动正常

滚动时 UITableViewCell 自动布局抖动的动态单元格高度问题