Невозможно передать UICollectionViewDatasource в дополнительный класс - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть ViewController с CollectionView и я хотел бы поместить UICollectionViewDataSource в дополнительный класс, чтобы его можно было повторно использовать.(Я не использую конструктор интерфейса).

Поэтому я создал дополнительный класс:

class MyDataSource:  NSObject, UICollectionViewDelegate, UICollectionViewDataSource {

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

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

        public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MYIDENTIFIER", for: indexPath)
            cell.backgroundColor = .blue
            return cell
        }

}

В ViewController с CollectionView я установил его:

override func viewDidLoad() {
    super.viewDidLoad()

    collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MYIDENTIFIER")

    let myDataSource = MyDataSource()
    collectionView.delegate = myDataSource
    collectionView.dataSource = myDataSource

}

Тем не менее, collectionView останется пустым - в нем нет ячеек.

Однако, если я помещу все функции DataSource в сам класс ViewController и установлю делегату и DataSource значение self , тогда все работает.

Разве невозможно передать UICollectionViewDataSource в другие файлы или вам нужно что-то еще сделать?

Ответы [ 3 ]

0 голосов
/ 04 февраля 2019

На всякий случай.Вот причина, по которой я говорил о вызове метода init.@ Андрей Чернуха, извините, если это вызвало путаницу.Вот почему я сказал, что он работает с init, но я думаю, что это та же самая причина, что и Паскаль

import UIKit

class ViewController: UIViewController {

    lazy var collectionView : UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .green
        return cv
    }()

    var dataSource : CustomDataSource!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.view.addSubview(collectionView)
        collectionView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
        dataSource = CustomDataSource(collectionView: collectionView)
    }

}

class CustomDataSource : NSObject, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UICollectionViewDelegate {

    let collectionView : UICollectionView

    init(collectionView: UICollectionView) {
        self.collectionView = collectionView
        super.init()
        self.collectionView.dataSource = self
        self.collectionView.delegate = self
        self.collectionView.register(Cell.self, forCellWithReuseIdentifier: "cell")
    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
        cell.backgroundColor = .red
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 100, height: 100)
    }

}


class Cell : UICollectionViewCell {

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    func setupViews() {
        self.backgroundColor = .red
    }

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

}

Я проверил это, и причина в том, что dataSource слабый в collectionView, поэтому оносвобождается сразу после его создания, если объявлено в viewDidLoad()

0 голосов
/ 05 февраля 2019

Это еще одна проблема, о которой часто забывают.

  override func viewDidLoad() {
super.viewDidLoad()

collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MYIDENTIFIER")

let myDataSource = MyDataSource(). //See the problem here?
collectionView.delegate = myDataSource
collectionView.dataSource = myDataSource

} //myDataSource will be released!
0 голосов
/ 04 февраля 2019

спасибо за помощь!Я попробовал то, что предложил Гало, но для меня это не сработало.Однако я нашел решение:

Вы должны инициализировать делегат как свойство ViewController, а не в его функции viewDidLoad!Тогда все работает правильно!

let myDataSource = MyDataSource()
override func viewDidLoad() {
    super.viewDidLoad()

    collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MYIDENTIFIER")

    collectionView.delegate = myDataSource
    collectionView.dataSource = myDataSource

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