【问题标题】:Self-sizing UICollectionView with UITableView with dynamic header as a cell自调整 UICollectionView 与 UITableView 与动态标题作为单元格
【发布时间】:2020-03-02 21:46:17
【问题描述】:

我在使用包含 UITableView 的单元格制作自调整大小的 UICollectionView 时遇到问题,该单元格的标题具有动态高度的标签。

有人可以指出我需要在附加的示例项目中进行哪些更改吗?

您可以在屏幕截图中看到表格不适合视图,因为当前手动设置了单元格的高度。

import UIKit

class ViewController: UIViewController {
    static let section1 = "section1"
        static let section2 = "section2"
        private weak var collectionView: UICollectionView!

        override func viewDidLoad() {
            self.navigationItem.title = "Collection View"
            super.viewDidLoad()
            self.setupCollectionView()
        }

        private func setupCollectionView() {
            let flowLayout = UICollectionViewFlowLayout()
            flowLayout.scrollDirection = .vertical
            flowLayout.minimumInteritemSpacing = 0.0
            flowLayout.minimumLineSpacing = 0.0
            let collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: flowLayout)
            collectionView.alwaysBounceVertical = true
            collectionView.register(
                SectionHeaderView.self,
                forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader,
                withReuseIdentifier: SectionHeaderView.sectionHeaderId
            )
            collectionView.register(Section1.self, forCellWithReuseIdentifier: ViewController.section1)
            collectionView.register(Section2.self, forCellWithReuseIdentifier: ViewController.section2)
            self.view.addSubview(collectionView)
            self.collectionView = collectionView
            self.collectionView.translatesAutoresizingMaskIntoConstraints = false
            self.collectionView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
            self.collectionView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
            self.collectionView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
            self.collectionView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
            self.collectionView.dataSource = self
            self.collectionView.delegate = self
        }
    }

    // MARK: - UICollectionViewDelegateFlowLayout
    extension ViewController: UICollectionViewDelegateFlowLayout {
        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            switch indexPath.section {
            case 0:
                return CGSize(width: self.view.frame.width, height: 210.0)
            case 1:
                return CGSize(width: self.view.frame.width, height: 5 * 51.0 + 130.0) // How to enable self-sizing cells for table view inside
            default:
                fatalError("Unsupported section index.")
            }
        }

        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
            return CGSize(width: self.view.frame.width, height: 61)
        }
    }

    // MARK: - UICollectionViewDataSource
    extension ViewController: UICollectionViewDataSource {
        func numberOfSections(in collectionView: UICollectionView) -> Int {
            return 2
        }

        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return 1
        }

        func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
            let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: SectionHeaderView.sectionHeaderId, for: indexPath) as! SectionHeaderView
            switch indexPath.section {
            case 0:
                header.uiLabel.text = "Section 1"
            case 1:
                header.uiLabel.text = "Section 2"
            default:
                fatalError("Unsupported section index.")
            }
            return header
        }

        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            switch indexPath.section {
            case 0:
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ViewController.section1, for: indexPath) as! Section1
                return cell
            case 1:
                let cell = collectionView.dequeueReusableCell(withReuseIdentifier: ViewController.section2, for: indexPath) as! Section2
                return cell
            default:
                fatalError("OverviewController: Unsupported section index.")
            }
        }
}

【问题讨论】:

  • 您是否尝试将常量添加到正确的锚约束?
  • @vishal 主播绝对不够
  • @Thunder - 不太清楚你在说什么是错误的......图像太窄了吗?是超出屏幕底部的行吗?是“Section 2”标签和“Lorem ipsum ...”段落顶部之间的垂直间距吗?
  • @DonMag 有一个工作示例的保管箱链接。基本上如屏幕截图所示,第 2 节有一个带有标题的 UITableView(基本上只有一个 UILabel)。由于主集合视图具有手动输入的第 2 节单元格的高度,因此大部分表格都被切断了。我希望它的集合视图根据部分大小正确地自行调整大小。
  • 我看不出图片有什么问题。你的意思是Key 3Value 3 不可见?在第 1 部分尝试 UICollectionViewFlowLayout.automaticSizesizeForItemAt

标签: ios swift uitableview uicollectionview autolayout


【解决方案1】:

要实现自动调整 collectionView 单元格的大小,您实际上只需要进行一些更改。

几个关键点:

  • 单元必须满足自己的约束。因此,不要在sizeForItemAt 中计算大小,而是确保单元格具有宽度和高度限制。这些可以是动态的,基于内容。

  • 将元素添加到集合视图单元格的contentView,而不是单元格本身。

  • 对于嵌入式非滚动表视图,使用一个子类,该子类根据表的 contentSize 设置内在内容大小高度。示例:


final class ContentSizedTableView: UITableView {
    override var contentSize:CGSize {
        didSet {
            invalidateIntrinsicContentSize()
        }
    }
    override var intrinsicContentSize: CGSize {
        layoutIfNeeded()
        return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
    }
}

这里有一个很好的教程(不是我的):https://medium.com/@andrea.toso/uicollectionviewcell-dynamic-height-swift-b099b28ddd23 有更详细的解释。

我在您提供的项目中实现了这些概念,并将其放在 GitHub 存储库中(以便于查看更改):https://github.com/DonMag/ThunderCollectionView

结果:

【讨论】:

  • GitHub 链接给了我 404。不过,谢谢,会尝试并批准。
  • @Thunder - 再次尝试 GitHub 链接...现在应该可以使用了。
猜你喜欢
  • 2015-02-26
  • 1970-01-01
  • 1970-01-01
  • 2015-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-15
相关资源
最近更新 更多