Обновление вложенного UICollectionView - Swift 3

У меня проблема с обновлением моего UICollectionView. У меня есть следующая настройка, состоящая из вложенных коллекцийViews.

введите здесь описание изображения

HomeControllerView — это collectionViewController с CollectionView 1, с включенным пейджингом. Каждая ячейка CollectionView 1 является коллекцией для себя, например. CollectionView A, B,... Причина этого в том, что каждый CollectionView A, B,... представляет собой канал, который извлекает информацию, которая затем отображается в виде ячеек A1, A2, B1...

Когда HomeViewController загружается, все CollectionViews A, B... заполняются, каждая (основная) ячейка 1, 2 начинает получать информацию. Некоторые каналы извлекают личную информацию, связанную с текущим пользователем, вошедшим в систему.

После переключения на другого пользователя я хотел бы, чтобы (Main) collectionView обновлялся, чтобы все ячейки 1, 2,... снова пытались получить информацию. Итак, из моего LoginController я звоню

self.homeController?.collectionView?.reloadData()

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

self.homeController?.collectionView?.reloadItems(at: (self.homeController?.collectionView?.indexPathsForVisibleItems)!)

В моем homeViewController я переопределяю функцию cellForItem, как это

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    switch indexPath.item {
        case 0:
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: incomingFeedCellId, for: indexPath) as! IncomingFeedCell
            return cell
        case 1:
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: popularFeedCellId, for: indexPath) as! PopularFeedCell
            return cell
        case 2:
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: favoritFeedCellId, for: indexPath) as! FavoritFeedCell
            return cell
        case 3:
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: personalFeedCellId, for: indexPath) as! PersonalFeedCell
            return cell
        default:
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: incomingFeedCellId, for: indexPath) as! IncomingFeedCell
            return cell
    }
}

Но с .reloadData() функция cellForItem больше не вызывается, поэтому после запуска ячейки не будут обновляться снова.

Каждая FeedCell имеет функцию fetch(), которая вызывается как минимум после создания ячейки:

func fetch(){
    posts = [Post]()
    let ref = FIRDatabase.database().reference()

    ref.child("posts_incoming").queryOrderedByKey().observe(.childAdded, with: { (snapshot) in
        if let dictionary = snapshot.value as? NSDictionary {
            let post = Post()
            post.imageUrl = dictionary["image_url"] as? String
            post.caption = dictionary["caption"] as? String
            ...
            ...
            self.posts?.append(post)

            DispatchQueue.main.async(execute: {
                self.collectionView.reloadData()
            })
        }
    }, withCancel: nil)
}

В настоящее время я отслеживаю идентификатор пользователя в (основных) ячейках, поэтому, когда ячейка удаляется из очереди (например, при переходе к следующему каналу), она проверяет, изменился ли uid, и если это так, выборка будет выполнена снова... но Я уверен, что должно быть более элегантное решение этой проблемы. Есть ли способ отбросить все ячейки и принудительно выполнить новую инициализацию для каждой ячейки?


person El_Chippo    schedule 15.04.2017    source источник


Ответы (1)


Я бы порекомендовал создать пользовательский класс UICollectionView, и все вызовы для получения фида должны выполняться в пользовательском классе UICollectionView. Также, чтобы упростить его, например, не вкладывать UICollectionViews, вы можете использовать:

Основной UICollectionView для пейджинга и добавьте UITableview в ячейку UICollectionView.

Таким образом, перезагрузка будет выглядеть так:

UICollectionView в UIViewController

UITableview в пользовательском классе UICollectionView

Также вы должны всегда использовать dequeueReusableCell, иначе будет выделено слишком много памяти, что приведет к сбою вашего приложения.

person ankit    schedule 15.04.2017
comment
Спасибо за ответ, но я не понимаю, как это может помочь. Если я создам CollectionView 1 как пользовательский CollectionView с новой функцией, из которой я буду обновлять ячейки, у меня все равно не будет доступа к тем ячейкам, которые не видны, верно? - person El_Chippo; 15.04.2017
comment
Да, посмотрите, если вы исправили 5 суперячеек, вы можете сделать одну вещь, пользователь ScrollView, размер содержимого которого в 5 раз превышает представление. Затем добавьте 5 контейнерных представлений, содержащих отдельные UIViewControllers в каждом containerView. Таким образом, вы можете легко управлять всем. - person ankit; 18.04.2017