如何检测最后一个单元格在UICollectionView中是否可见?

问题描述 投票:5回答:4

我试图检测collectionView中的最后一个单元格是否可见。

var isLastCellVisible: Bool {

    let lastIndexPath = NSIndexPath(forItem: self.messages.count - 1, inSection: 0)
    let visibleIndexPaths = self.collectionView.indexPathsForVisibleItems()

    let lastCellPositionY = self.collectionView.layoutAttributesForItemAtIndexPath(lastIndexPath)!.frame.origin.y
    let bottomInset = self.collectionView.contentInset.bottom // changes when the keyboard is shown / hidden
    let contentHeight = self.collectionView.contentSize.height

    if visibleIndexPaths.contains(lastIndexPath) && (contentHeight - lastCellPositionY) > bottomInset {
        return true
    } else {
        return false
    }
}

什么有效:

如果最后一个单元格可见并且显示键盘以便单元格不被其隐藏,则上面的代码返回true。如果它是隐藏的,则返回false。

但是,当用户向上滚动并且最后一个单元格位于键盘上方时,我无法弄清楚如何返回true。

lastCellPositionY向上滚动时,contentHeightcollectionView不会改变。相反self.collectionView.bounds.origin.y确实发生了变化,但我不知道如何将lastCellPositionY与它进行比较,因为它们不具有相同的起源,而self.collectionView.bounds.origin.y明显小于lastCellPositionY

swift cocoa-touch uicollectionview uicollectionviewlayout
4个回答
15
投票

我在用什么

override func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
        if indexPath.row == dataSource.count - 1 {
            // Last cell is visible
        }
    }

1
投票

我使用这段代码(从这个帖子的提交翻译成Swift:https://github.com/jessesquires/JSQMessagesViewController/issues/1458

var isLastCellVisible: Bool {

    if self.messages.isEmpty {
        return true
    }

    let lastIndexPath = NSIndexPath(forItem: self.messages.count - 1, inSection: 0)
    var cellFrame = self.collectionView.layoutAttributesForItemAtIndexPath(lastIndexPath)!.frame

    cellFrame.size.height = cellFrame.size.height

    var cellRect = self.collectionView.convertRect(cellFrame, toView: self.collectionView.superview)

    cellRect.origin.y = cellRect.origin.y - cellFrame.size.height - 100 
    // substract 100 to make the "visible" area of a cell bigger

    var visibleRect = CGRectMake(
        self.collectionView.bounds.origin.x,
        self.collectionView.bounds.origin.y,
        self.collectionView.bounds.size.width,
        self.collectionView.bounds.size.height - self.collectionView.contentInset.bottom
    )

    visibleRect = self.collectionView.convertRect(visibleRect, toView: self.collectionView.superview)

    if CGRectContainsRect(visibleRect, cellRect) {
        return true
    }

    return false
}

1
投票

对于Swift 3:

var isLastCellVisible: Bool {

    if self.posts.isEmpty {
        return true
    }

    let lastIndexPath = IndexPath(item: self.posts.count - 1, section: 1)
    var cellFrame = self.collectionView?.layoutAttributesForItem(at: lastIndexPath)!.frame

    cellFrame?.size.height = (cellFrame?.size.height)!

    var cellRect = self.collectionView?.convert(cellFrame!, to: self.collectionView?.superview)

    cellRect?.origin.y = (cellRect?.origin.y)! - (cellFrame?.size.height)! - 100 
    // substract 100 to make the "visible" area of a cell bigger

    var visibleRect = CGRect(x: (self.collectionView?.bounds.origin.x)!, y: (self.collectionView?.bounds.origin.y)!, width: 
        (self.collectionView?.bounds.size.width)!, height: 
        (self.collectionView?.bounds.size.height)! - (self.collectionView?.contentInset.bottom)!
    )

    visibleRect = (self.collectionView?.convert(visibleRect, to: self.collectionView?.superview))!

    if visibleRect.contains(cellRect!) {
        return true
    }

    return false
}

0
投票

Swift版本4.2

 func scrollViewDidScroll(_ scrollView: UIScrollView) {

    if (scrollView.bounds.maxY) == scrollView.contentSize.height{
        // Call Your API or hide UIElements
     }
 }
© www.soinside.com 2019 - 2024. All rights reserved.