Размер ячейки в представлении коллекции автоматического определения размера игнорирует автоматическое расположение при первом отображении - PullRequest
0 голосов
/ 28 ноября 2018

Ситуация

Я сделал представление коллекции с горизонтальной прокруткой с помощью 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
    }
}

Cell

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 голосов
/ 28 ноября 2018

Я решил проблему, установив нестандартный размер для flowlayout.

Вдохновленный ответом Манава на этот вопрос ниже.

поведение UICollectionViewFlowLayout не определено, потому что ячейкаширина больше, чем 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
    }()
...