Проверьте, видна ли ячейка в indexPath на экране UICollectionView


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

func handlePhotoDownloadCompletion(notification : NSNotification) {
    let userInfo:Dictionary<String,String!> = notification.userInfo as! Dictionary<String,String!>
    let id = userInfo["id"]
    let index = users_cities.indexOf({$0.id == id})
    if index != nil {
        let indexPath = NSIndexPath(forRow: index!, inSection: 0)
        let cell = followedCollectionView.cellForItemAtIndexPath(indexPath) as! FeaturedCitiesCollectionViewCell
        if (users_cities[index!].image != nil) {
            cell.backgroundImageView.image = users_cities[index!].image!
        }
    }
}

Это отлично работает, если ячейка в данный момент видна на экране, однако если это не так, я получаю fatal error: unexpectedly found nil while unwrapping an Optional value ошибка в следующей строке:

 let cell = followedCollectionView.cellForItemAtIndexPath(indexPath) as! FeaturedCitiesCollectionViewCell

Теперь эту функцию даже не нужно вызывать, если collectionViewCell еще не виден, потому что в этом случае изображение будет все равно установите в методе cellForItemAtIndexPath.

Отсюда мой вопрос, как я могу изменить эту функцию, чтобы проверить, является ли ячейка, с которой мы имеем дело, видимой в данный момент или нет. Я знаю о collectionView.visibleCells(), однако я не уверен, как применить его здесь.
3 5

3 ответа:

Использование followedCollectionView.indexPathsForVisibleItems() для получения видимых ячеек visibleIndexPaths и проверки вашего indexPath содержится в visibleIndexPaths или нет, прежде чем делать что-либо с ячейками.

Вложенные UICollectionViews часто не нужно прокручивать вообще, так что никакое contentOffset никогда не предоставляется и, таким образом, iOS понимает все ячейки как всегда видимые. В этом случае можно взять границы экрана в качестве ссылки:

    let cellRect = cell.contentView.convert(cell.contentView.bounds, to: UIScreen.main.coordinateSpace)
    if UIScreen.main.bounds.intersects(cellRect) {
        print("cell is visible")
    }

Вы можете просто использовать if collectionView.cellForItem(at: indexPath) == nil { }. CollectionView возвращает ячейку только в том случае, если она видна.

Или в вашем случае конкретно изменить:

let cell = followedCollectionView.cellForItemAtIndexPath(indexPath) as! FeaturedCitiesCollectionViewCell

Кому:

if let cell = followedCollectionView.cellForItemAtIndexPath(indexPath) as? FeaturedCitiesCollectionViewCell { }