【问题标题】:Auto sizing collection view cell size ignores auto layout on first display自动调整集合视图单元格大小会忽略首次显示时的自动布局
【发布时间】:2019-04-29 20:56:15
【问题描述】:

情况

我使用 UICollectionViewFlowLayout.automaticSize 制作了一个水平滚动的集合视图。 集合视图的高度为 40 单元格的高度为 40,这是我在初始化时通过 autolayo 设置的。

问题

问题是只有第一次显示集合视图时显示的单元格 大小为 50x50,它覆盖了我手动设置的自动布局高度 40。

我在 willDisplayCell 委托方法上检查了大小。

当我滚动集合视图以显示其他单元格时,每个新显示的单元格 单元格大小合适,高度为 40。

虽然尺寸为 50x50(如记录)的单元格在屏幕上正确显示(高度似乎为 40)。

由此,当我在模拟器上运行应用程序时收到错误消息(已记录),并且 如果我在我的真实设备(iPhone8 iOS 11)上运行,应用程序就会崩溃。

代码

视图控制器

import UIKit

class HorizontalTabNavigationViewController: UIViewController {

    // MARK: - Collection View

    private lazy var navigationCollectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.translatesAutoresizingMaskIntoConstraints = false
        cv.backgroundColor = .white
        cv.dataSource = self
        cv.delegate = self
        return cv
    }()

    private typealias Cell = HorizontalTabNavigationCell
    private let cellId: String = "cell"



    // MARK: - Property

    var items: [HorizontalTabNavigationItem] = []



    // MARK: - Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.translatesAutoresizingMaskIntoConstraints = false
        navigationCollectionView.register(Cell.self, forCellWithReuseIdentifier: cellId)
        navigationCollectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        setupSubviews()
    }


    private func setupSubviews() {

        view.addSubview( navigationCollectionView )

        [
        navigationCollectionView.topAnchor   .constraint(equalTo: view.topAnchor),
        navigationCollectionView.leftAnchor  .constraint(equalTo: view.leftAnchor),
        navigationCollectionView.rightAnchor .constraint(equalTo: view.rightAnchor),
        navigationCollectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        ].forEach { $0.isActive = true }
    }


}


extension HorizontalTabNavigationViewController: UICollectionViewDataSource {

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! Cell
        //cell.setProperties(item: items[indexPath.row])
        //print("Cell for item: \(items[indexPath.row].title)")

        return cell
    }

    func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
        print("Cell Size on willDispaly cell")
        print(cell.bounds.size)
        print("\n")
    }
}


extension HorizontalTabNavigationViewController: UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 5 // Defines horizontal spacing between cells
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return .zero
    }
}

细胞

class HorizontalTabNavigationCell: UICollectionViewCell {

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupSelfHeight()
        self.backgroundColor = .orange
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func setupSelfHeight() {
        self.heightAnchor.constraint(equalToConstant: 40).isActive = true
        self.widthAnchor.constraint(equalToConstant: 120).isActive = true
    }
}

【问题讨论】:

    标签: ios swift autolayout uicollectionviewcell uicollectionviewflowlayout


    【解决方案1】:

    我通过将自定义大小设置为 flowlayout 解决了这个问题。

    受到 Manav 对下面这个问题的回答的启发。

    the behavior of the UICollectionViewFlowLayout is not defined, because the cell width is greater than collectionView width

    private lazy var navigationCollectionView: UICollectionView = {
            let layout = UICollectionViewFlowLayout()
            layout.scrollDirection = .horizontal
    
            // [Here is the answer]
            // Set Height equal or less than the height of the collection view.
            // This is applied on first display of cells and 
            // will also not affect cells auto sizing.
            layout.estimatedItemSize = CGSize(width: 200, height: 40) // UICollectionViewFlowLayoutAutomaticSize
    
            let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
            cv.translatesAutoresizingMaskIntoConstraints = false
            cv.showsHorizontalScrollIndicator = false
            cv.backgroundColor = .white
            cv.dataSource = self
            cv.delegate = self
            return cv
        }()
    

    【讨论】:

      猜你喜欢
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多