自动调整集合视图单元格大小的设置将忽略第一次显示时的自动布局

时间:2018-11-28 02:22:27

标签: ios swift autolayout uicollectionviewcell uicollectionviewflowlayout

设定

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

问题

问题在于只有第一个显示的单元格显示收集视图 具有50x50的尺寸,可以覆盖通过代码手动设置的40我的自动布局高度。

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

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

尽管尺寸为50x50(已记录)的单元格可以正确显示(似乎高度为40)在屏幕上。

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

代码

ViewController

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
    }
}

1 个答案:

答案 0 :(得分:0)

我通过将自定义尺寸设置为流布局解决了这个问题。

受到马纳夫(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
    }()