首页 > 解决方案 > Self Sizing CollectionView 在 Self Sizing TableViewCell 内

问题描述

我花了数周时间试图让它发挥作用,并在这里、苹果开发者论坛、谷歌等上查看了许多不同的建议,但我仍在努力解决问题。任何帮助将不胜感激。

我有一个包含 TableView 的 ViewController。它不是全屏 tableView。

tableView 是用 customTableViewCells 构建的,每个都有一个 CollectionView。我遇到的问题是自调整collectionView 和自调整tableView 行似乎不起作用。我在网上找到了一些选项,但它们似乎只部分有效。

这是我最初运行时得到的:

在此处输入图像描述

我包含了项目文件的链接,因为这可能比将代码复制到此处更容易: https ://www.dropbox.com/sh/7a2dquvxg62aylt/AACK_TjDxT9eOShZaKi7vLYga?dl=0

一些在线“解决方法”并非在所有情况下都有效 - 例如,如果您点击 CollectionView 中的一个按钮,它会被删除,并且 collectionView(以及随后的 TableView)应该调整大小,但我还是无法做到这一点始终如一地工作。

我尝试过的一些解决方案:

UICollectionView 具有自动布局的自定尺寸单元格

UITableViewCell 内的 UICollectionView - 动态高度?

基于动态集合视图的 UITableView 的动态高度

自动调整包含 UICollectionView 的 UITableViewCell

任何帮助将不胜感激。

标签: iosswiftuitableviewuicollectionview

解决方案


我发现出了什么问题。有几件事需要修复:

  1. 您需要设置估计的行高(带有实际值)并将行高设置为自动。你反其道而行之。所以请用下面的这个替换你的 setupTableView 函数。另外,你需要设置你没有做的委托。因此,请确保在类名旁边添加 UITableViewDelegate,并将其分配到 setupTableView() 中,就像我在下面所做的那样。

    func setupTableView() {
        view.addSubview(tempTableView)
        NSLayoutConstraint.activate([
            tempTableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            tempTableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 200),
            tempTableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            tempTableView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -200)
        ])
        tempTableView.rowHeight = UITableView.automaticDimension
        tempTableView.estimatedRowHeight = 90
        tempTableView.register(CustomTableViewCell.self, forCellReuseIdentifier: CustomTableViewCell.cellIdentifier)
        tempTableView.dataSource = self
        tempTableView.delegate = self
        tempTableView.translatesAutoresizingMaskIntoConstraints = false
        tempTableView.layoutIfNeeded()
    }
    
  2. 在 cellForRowAt 中,添加 layoutIfNeeded 以确保单元格自动调整大小:

    extension ViewController: UITableViewDataSource, UITableViewDelegate {
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            2
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tempTableView.dequeueReusableCell(withIdentifier: CustomTableViewCell.cellIdentifier) as! CustomTableViewCell
            cell.layoutIfNeeded()
            return cell
        }
    }
    
  3. 您的 CustomCollectionView 需要继承 UICollectionViewDelegateFlowLayout。

  4. 确保将您配置的CollectionViewLayout 变量分配给您的collectionView:

    func setupCollectionView() {
        backgroundColor = .systemPink
        isScrollEnabled = false
        register(CustomCollectionViewCell.self, forCellWithReuseIdentifier: CustomCollectionViewCell.cellIdentifier)
        dataSource = self
        self.collectionViewLayout = configuredCollectionViewFlowLayout
    }
    
  5. 最后,添加这 3 个覆盖以根据其内容(在 CustomCollectionView 内)使您的 collectionView 自动调整大小:

    override var intrinsicContentSize: CGSize {
         self.layoutIfNeeded()
         return self.contentSize
     }
    
     override var contentSize: CGSize {
         didSet{
             self.invalidateIntrinsicContentSize()
         }
     }
    
     override func reloadData() {
         super.reloadData()
         self.invalidateIntrinsicContentSize()
     }
    

这是单击按钮时触发单元格重绘的方式。我没有使用协议,但请这样做,这只是向您展示这个想法:

func tokenTapped(withTitle title: String) {
    guard let indexOfItemToRemove = tokens.sampleData.firstIndex(where: {$0.name == title}) else { return }
    tokens.sampleData.remove(at: indexOfItemToRemove)
    DispatchQueue.main.async {
        self.performBatchUpdates({
            self.deleteItems(at: [IndexPath(item: indexOfItemToRemove, section: 0)])
        }) { (true) in
            if let tableView = self.superview?.superview?.superview as? UITableView {
                print("tableview updates")
                tableView.beginUpdates()
                tableView.endUpdates()
                DispatchQueue.main.async {
                    tableView.layoutIfNeeded()
                }
            }
        }
    }
}

推荐阅读