Check whether cell at indexPath is visible on screen UICollectionView

与世无争的帅哥 提交于 2019-12-23 07:27:37

问题


I have a CollectionView which displays images to the user. I download these in the background, and when the download is complete I call the following func to update the collectionViewCell and display the image.

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!
        }
    }
}

This works great if the cell is currently visible on screen, however if it is not I get a fatal error: unexpectedly found nil while unwrapping an Optional value error on the following line :

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

Now this function does not even need to be called if the collectionViewCell is not yet visible, because in this case the image will be set in the cellForItemAtIndexPath method anyway.

Hence my question, how can I alter this function to check whether the cell we are dealing with is currently visible or not. I know of the collectionView.visibleCells() however, I am not sure how to apply it here.


回答1:


Get current available cells

// get visible cells 
let visibleIndexPaths = followedCollectionView.indexPathsForVisibleItems()

Then check your indexPath is contained in visibleIndexPaths or not, before doing anything with cells.




回答2:


Nested UICollectionViews need oft to not scroll at all, so that no contentOffset is ever provided and thus iOS understands all cells as being always visible. In that case it is possible to take the screen boundaries as reference:

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



回答3:


You can simply use if collectionView.cellForItem(at: indexPath) == nil { }. The collectionView will only return a cell if it is visible.

Or in your case specifically change:

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

to:

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


来源:https://stackoverflow.com/questions/38281883/check-whether-cell-at-indexpath-is-visible-on-screen-uicollectionview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!