'UICollectionView должен быть инициализирован с параметром макета, отличным от nil'? - PullRequest
0 голосов
/ 27 апреля 2019

Я пытаюсь написать собственный класс для создания UICollectionView, из которого я собираюсь создать несколько экземпляров в разных классах. Ниже приведен код, который я использую внутри пользовательского класса UICollectionView:

import UIKit

class CustomCollectionView: UICollectionView, UICollectionViewDelegate, UICollectionViewDataSource {



    override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {

        super.init(frame: frame, collectionViewLayout: layout)

        setupCollectionView(topEdgeInset: 20, bottomEdgeInset: 20, leftEdgeInset: 20, rightEdgeInset: 20, screenWdith: frame.width, screenHeight: frame.height, minimumCellsHorizontalSpacing: 20, minimumCellsVerticalSpacing: 20, numberOfCellsPerRow: 2, viewCollectionViewWillBeAddedTo: self, dataSource: self as! UICollectionViewDataSource, delegate: self as! UICollectionViewDelegate)

    }

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

    convenience init(topEdgeInset: CGFloat, bottomEdgeInset: CGFloat, leftEdgeInset: CGFloat, rightEdgeInset: CGFloat, screenWdith: CGFloat, screenHeight: CGFloat, minimumCellsHorizontalSpacing: CGFloat, minimumCellsVerticalSpacing: CGFloat, numberOfCellsPerRow: CGFloat, viewCollectionViewWillBeAddedTo: UIView, dataSource: UICollectionViewDataSource, delegate: UICollectionViewDelegate) {

        self.init(frame: viewCollectionViewWillBeAddedTo.bounds,collectionViewLayout: UICollectionViewFlowLayout())

        setupCollectionView(topEdgeInset: topEdgeInset, bottomEdgeInset: bottomEdgeInset, leftEdgeInset: leftEdgeInset, rightEdgeInset: rightEdgeInset, screenWdith: screenWdith, screenHeight: screenHeight, minimumCellsHorizontalSpacing: minimumCellsHorizontalSpacing, minimumCellsVerticalSpacing: minimumCellsVerticalSpacing, numberOfCellsPerRow: numberOfCellsPerRow, viewCollectionViewWillBeAddedTo: viewCollectionViewWillBeAddedTo, dataSource: dataSource, delegate: delegate)

    }

    func setupCollectionView (topEdgeInset topInset: CGFloat, bottomEdgeInset bottomInset: CGFloat, leftEdgeInset leftInset: CGFloat, rightEdgeInset rightInset: CGFloat, screenWdith width: CGFloat, screenHeight height: CGFloat, minimumCellsHorizontalSpacing cellsHorizontalSpacing: CGFloat, minimumCellsVerticalSpacing cellsVerticalSpacing: CGFloat, numberOfCellsPerRow cellsPerRow: CGFloat, viewCollectionViewWillBeAddedTo hostView: UIView, dataSource: UICollectionViewDataSource, delegate: UICollectionViewDelegate) {

        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()

        layout.sectionInset = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset)

        layout.minimumLineSpacing = cellsVerticalSpacing

        layout.minimumInteritemSpacing = cellsHorizontalSpacing

        let widthOfCollectionViewCell: CGFloat = width - (leftInset + rightInset + cellsHorizontalSpacing) / cellsPerRow

        layout.itemSize = CGSize(width: widthOfCollectionViewCell, height: 100)

        let myCollectionView = UICollectionView(frame: hostView.bounds, collectionViewLayout: layout)

        myCollectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MyCell")

        myCollectionView.dataSource = dataSource

        myCollectionView.delegate = delegate

        hostView.addSubview(self)

    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath)

        myCell.backgroundColor = .blue

        return myCell
    }

}

В приведенном ниже классе я создал экземпляр из указанного выше пользовательского класса UICollectionView:

class FirstItemInTabBarOpenRolledSections: UIViewController
{

    override func viewDidLoad() {

        super.viewDidLoad()

        view.backgroundColor = .black

    }

    override func viewWillAppear(_ animated: Bool) {

        super.viewWillAppear(animated)
_ = CustomCollectionView(topEdgeInset: 20, bottomEdgeInset: 20, leftEdgeInset: 20, rightEdgeInset: 20, screenWdith: self.view.frame.width, screenHeight: self.view.frame.height, minimumCellsHorizontalSpacing: 20, minimumCellsVerticalSpacing: 20, numberOfCellsPerRow: 2, viewCollectionViewWillBeAddedTo: self.view, dataSource: self as! UICollectionViewDataSource, delegate: self as! UICollectionViewDelegate)

    }
func numberOfSections(in collectionView: UICollectionView) -> Int {

        return 1

    }


    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        print("User tapped on itme \(indexPath.row)")

    }

}

Однако, каждый раз, когда я запускаю приложение, оно падает, и я получаю сообщение об ошибке:

Завершение приложения из-за необработанного исключения «NSInvalidArgumentException», причина: «UICollectionView должен быть инициализирован с параметром макета, отличным от nil»

Я не понимаю, мой мой макет не инициализирован ?? Может ли кто-нибудь выбрать место, где проблема?

1 Ответ

0 голосов
/ 27 апреля 2019

Ошибка понятна. При создании представления коллекции необходимо указать макет, но вы этого не сделаете.

Для вашего удобства init вы звоните self.init(), но вы должны позвонить self.init(frame:,collectionViewLayout:).

Вам нужно будет реорганизовать свой метод setupCollectionView, чтобы получить правильное значение.

...