UICollectionView reloadData никогда не проходит через источник данных

Я пытаюсь отобразить данные в UICollectionView, который работал точно так же, как и во всем приложении, но по какой-то причине в этом случае он не работает:

Вот код, необходимый для понимания проблемы:

Некоторые контроллеры:

func showContactsView(sender: RoundButton) -> Void {
        DispatchQueue.main.async {
            self.someView = SomeView()
            self.view.addSubview(self.someView)
            self.someView.setSomeViewViewConstraints(container: 
    self.view)
            self.someView.alpha = 0.0
            self.someView.contactsCollectionView.delegate = self
            self.someView.contactsCollectionView.dataSource = self
            self.someView.tabControlCallbacks["contacts"] = self.searchContacts
        }
    }

Контроллер запускает представление, содержащее UICollectionView. Эта часть обрабатывается автомакетом и ограничениями, у меня нет проблем с этим. Он также наследуется от UIColleCtionViewDelegate и UICollectionViewDataSource. :

class SomeController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate

Представление инициализируется collectionView и отображается с помощью SegmentedControl, который отлично работает:

private func initCollectionViews() {
        let layout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        layout.itemSize = CGSize(width: 50, height: 50)

        contactsCollectionView = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
        contactsCollectionView.backgroundColor = UIColor.black.withAlphaComponent(0.6)
        contactsCollectionView.showsVerticalScrollIndicator = false
        contactsCollectionView.showsHorizontalScrollIndicator = false
        contactsCollectionView.register(AModelCollectionViewCell.self, forCellWithReuseIdentifier: "ContactsSelectModelCell")
        contactsCollectionView.translatesAutoresizingMaskIntoConstraints = false


        // Constraints to add when view is set dynamically
        contactsCollectionViewConstraints["leading"] = NSLayoutConstraint(item: contactsCollectionView, attribute: .leading, relatedBy: .equal, toItem: self, attribute: .leading, multiplier: 1.0, constant: 0.0)
        contactsCollectionViewConstraints["trailing"] = NSLayoutConstraint(item: self, attribute: .trailing, relatedBy: .equal, toItem: contactsCollectionView, attribute: .trailing, multiplier: 1.0, constant: 0.0)
        contactsCollectionViewConstraints["top"] = NSLayoutConstraint(item: tabControl, attribute: .bottom, relatedBy: .equal, toItem: contactsCollectionView, attribute: .top, multiplier: 1.0, constant: 0.0)
        contactsCollectionViewConstraints["bottom"] = NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal, toItem: contactsCollectionView, attribute: .bottom, multiplier: 1.0, constant: 0.0)
    }

и отображение сегментированного элемента управления значением изменилось:

func cleanViews() {
        if self.contactsCollectionView.superview != nil {
            self.contactsCollectionView.removeFromSuperview()
        }
        if self.favoritesCollectionView.superview != nil {
            self.favoritesCollectionView.removeFromSuperview()
        }
    }

func bounce() {
        self.cleanViews()
        switch self.actualControl {
        case -1:
            break
        case 0:
            // Some code
        case 1:
            self.addSubview(self.contactsCollectionView)
            for constraint in self.contactsCollectionViewConstraints {
                self.addConstraint(constraint.value)
            }
            if let callback = self.tabControlCallbacks["contacts"]! {
                callback()
            }
        default:
            fatalError("Unknown control")
        }
    }

    // Selectors UISegmentedControl
    func valueChanged(sender: UISegmentedControl) {
        if sender.selectedSegmentIndex == actualControl {
            tabControl.isMomentary = true
            sender.selectedSegmentIndex = -1
            tabControl.isMomentary = false
        }
        actualControl = sender.selectedSegmentIndex


        DispatchQueue.main.async {
            self.bounce()
        }
    }

Как видите, я устанавливаю обратный вызов от контроллера к представлению, чтобы выполнить действие в моей сети и получить данные для отображения в collectionView. Вот методы в контроллере:

  //Collection Views Actions/Callbacks for selectContactsView
    func searchContacts() -> Void {
        let params : [String:Any] = [
            "id" : "-1",
            "name_begin" : ""
        ]

        self.network?.get(......, callback: afterSearchContacts)
    }

    func afterSearchContacts() -> Void {

        DispatchQueue.main.async {

            self.contactsSearchResults.removeAll()
            let usersData : [[String:Any]] = self.network?.lastResponse!["users"] as! [[String:Any]]
            let groupsData : [[String:Any]] = self.network?.lastResponse!["groups"] as! [[String:Any]]

            for userData in usersData {
                self.contactsSearchResults.append(User(fromData: userData))
            }
            for groupData in groupsData {
                self.contactsSearchResults.append(Group(fromData: groupData))
            }
            self.contactsView.contactsCollectionView.reloadData()
        }
    }

ReloadData не работает. Вот методы делегатов и источника данных, прежде чем объяснять, какая часть работает, а какая нет:

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


        switch self.contactsView.actualControl {
        case 1:

            if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ContactsSelectModelCell", for: indexPath) as? AModelCollectionViewCell {
                cell.model = contactsSearchResults[indexPath.item]
                cell.fillCell()
                return cell
            }
        case 0:
                //some Code
                return cell
            }
        default:
            print("Unknown cell type")
        }
        fatalError("Unknown cell type")
    }

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

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        let count = collectionView == contactsView.contactsCollectionView ? contactsSearchResults.count : favoritesSearchResults.count

        return count
    }

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

У меня есть настраиваемая ячейка представления коллекции, которая работает с другими представлениями коллекции, поэтому с этим проблем нет. Я также забочусь о том, чтобы различать идентификаторы для всех разных CollectionView, когда я делаю регистрацию. В этом случае, когда я использую точки останова, количество элементов в разделе> 0, но когда я делаю reloadData в основном потоке после того, как моя сеть установила contactSearchResult, он никогда не проходит через collectionView cellForItemAt.

Есть идеи?


person Poulpy    schedule 09.07.2017    source источник
comment
Когда вы говорите, что не работает, что именно происходит? Это идет к методам источника данных? Можете ли вы распечатать contactCollectionView и посмотреть, не равен ли он нулю. Также проверьте, не является ли его источник данных нулевым   -  person adev    schedule 09.07.2017
comment
Когда я говорю, что не работает, я имею в виду, что в этом случае collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath) никогда не выполняется. ContactsCollectionView, очевидно, не равен нулю, то же самое для источника данных.   -  person Poulpy    schedule 09.07.2017
comment
Вы уверены, что он вызывает эту линию self.contactsView.contactsCollectionView.reloadData()? После этого он вызывает numberOfSections, если поставить там точку останова?   -  person adev    schedule 09.07.2017
comment
Я тестировал это раньше и только что проверил снова. К сожалению, да, это так. Я не понимаю, почему collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath) не вызывается сразу после обновления numberOfSections. Также счетчик в numberOfSections равен ровно 6 после вызова reloadData.   -  person Poulpy    schedule 09.07.2017
comment
Поставьте точку останова в строке swift self и посмотрите, идет ли она туда. В противном случае проверьте правильность написания имени источника данных. Также какое количество разделов и какое количество элементов в каждом разделе? Это правильно?   -  person adev    schedule 09.07.2017
comment
Извините, быстрая самостоятельная линия? Можете ли вы быть более точным   -  person Poulpy    schedule 09.07.2017
comment
Я проверил имя источника данных и другие параметры. Все хорошо   -  person Poulpy    schedule 09.07.2017
comment
Извините, я имел в виду switch self.contactsView.actualControl {. Поставьте здесь точку останова.   -  person adev    schedule 10.07.2017
comment
Просто попробовал и получил то, что ожидал. Ничего не происходит, потому что collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath) никогда не выполняется   -  person Poulpy    schedule 10.07.2017
comment
Мы, очевидно, можем сказать, что проблема исходит от источника данных.   -  person Poulpy    schedule 10.07.2017
comment
Вы уверены, что numberOfItemsInSection возвращает 6? Я сомневаюсь, что это происходит. Если бы это было 6, вы бы точно получили вызов на линию switch self.contactsView.actualControl {   -  person adev    schedule 10.07.2017
comment
Я знаю, что это действительно странно, и да, я уверен на 10000%. Чтобы вы были уверены, я могу сделать скриншот, но поверьте мне, это ненормально. Я знаю, что делаю, этот точный код работает с другими представлениями в моем приложении. Я пробовал буквально все: перемещение делегата, добавление ссылки на контроллер в качестве делегата и источника данных в представлении и т. д. Я не могу понять, почему у меня возникла эта проблема. Поскольку я опубликовал эту проблему, я пытаюсь ее отладить и, поверьте, я не новичок в мире разработки... Кстати, спасибо за вашу помощь.   -  person Poulpy    schedule 10.07.2017
comment
imageshack.com/a/img923/6613/LaAFnR.png   -  person Poulpy    schedule 10.07.2017
comment
Я даже пытался запустить reloadData с помощью кнопки в пользовательском интерфейсе после того, как все было установлено, проблема все та же, так что это не проблема потока.   -  person Poulpy    schedule 10.07.2017
comment
Можете ли вы один раз проверить рамку представления коллекции при ее перезагрузке?   -  person bestiosdeveloper    schedule 11.07.2017
comment
Я уже сделал, чтобы мой вид отображался правильно, кадр в порядке. Как я уже сказал, я сделал свой собственный просмотр коллекции, у меня больше нет проблем. Также я сделал это, тщательно проверив использование памяти, он использует меньше памяти, чем встроенный.   -  person Poulpy    schedule 12.07.2017


Ответы (1)


Для тех, кто читает этот пост, я закончил тем, что закодировал свой собственный CollectionView. Работает как шарм.

person Poulpy    schedule 10.07.2017