Как использовать пользовательский UICollectionReusableView в качестве заголовка раздела представления коллекции? - PullRequest
0 голосов
/ 05 апреля 2020

Меня сводили с ума в течение нескольких часов, поскольку я не могу обойти эту проблему.

У меня есть представление коллекции, которое может иметь другой раздел с разными номерами. предметов в каждом. Для каждого раздела мне нужно использовать заголовок раздела разного типа. Так что для этого я собираюсь использовать UICollectionReusableView. Но я не могу добиться успеха в использовании пользовательского подкласса UICollectionReusableView посредством UINib регистрации.

Cra sh происходит, когда я понижаю представление многократного использования до моего подкласса. Как:

let friendHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, 
                                    withReuseIdentifier: "FriendHeaderView", 
                                    for: indexPath) as! FriendHeaderView

Ниже приведен фрагмент кода:

class ViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!

    private let viewModel = ProfileViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView.dataSource = self
        collectionView.delegate = self
        // more code
        collectionView.register(UINib(nibName: "FriendHeaderView", bundle: nil), 
                                forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, 
                                withReuseIdentifier: "FriendHeaderView")
    }
}

Теперь вот реализация источника данных:

extension ViewController: UICollectionViewDataSource {

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

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        // valid implementation
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        // valid implementation

    }

    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {

        switch kind {
        case UICollectionView.elementKindSectionHeader:
            let friendHeader = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "FriendHeaderView", for: indexPath) as! FriendHeaderView

            // *** Crash happens here *** //

            return friendHeader
        default:
            assert(false, "Invalid element type")
        }

    }

}

И я не Не знаю, почему collectionView(_:layout:referenceSizeForHeaderInSection:) также должен быть реализован. Итак, вот оно:

extension ViewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        let size = CGSize(width: collectionView.bounds.width, height: 100)
        return size
    }

}

Хорошо, теперь перейдем к сути: вышеупомянутый cra sh вообще не произойдет, если я не опущу вниз с as! оператор. Что ж, если я использую заголовок раздела из раскадровки вместо UINib регистрации, нет никакого cra sh.

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


Что можно сделать, чтобы иметь несколько типов заголовков с представлением, построенным из построителя интерфейса?


Я сделал демонстрационный проект с тем, что я сказал выше. Если кому-то интересно, пожалуйста, проверьте это.

Ответы [ 2 ]

1 голос
/ 05 апреля 2020

Как только вы назначите правильный класс и идентификатор в вашем Xib-файле, он будет работать без сбоев.

0 голосов
/ 05 апреля 2020

Что ж, после еще одного исследования и ввода @ good4p c в принятом ответе (на самом деле я узнал, что сам, прежде чем посмотреть на ответ), кажется, что проблема действительно возникает из-за какой-то нежелательной проблемы с Xcode .

Когда мы создаем любое представление (предпочтительно, UITableViewCell или UICollectionViewCell) с .xib, идентификатор класса автоматически предоставляется для этого .xib в инспекторе идентификации. Но это было не так для UICollectionReusableView. Смотрите прилагаемый скриншот ниже для легкого понимания.

Это UICollectionViewCell подкласс с .xib:

UICollectionViewCell custom class

Это UICollectionReusableView с подклассом .xib :

UICollectionReusableView custom class


Таким образом, ключ заключается в предоставлении идентификатора класса файла .xib, который делается из инспектор атрибутов .

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