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

时间:2016-06-18 14:44:59

标签: swift cocoa-touch uicollectionview uicollectionviewlayout

我正在尝试检测AddChildEventListener中的最后一个单元格是否可见。

collectionView

什么有效:

如果最后一个单元格可见且键盘显示为单元格未隐藏,则上述代码返回true。如果隐藏,则返回false。

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

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 } } 向上滚动时,

lastCellPositionYcontentHeight不会更改。 代替 collectionView确实发生了变化,但我不知道如何将self.collectionView.bounds.origin.y与其进行比较,因为它们不共享相同的来源,lastCellPositionY远远小于self.collectionView.bounds.origin.y

5 个答案:

答案 0 :(得分:15)

我在用什么

function addItem(e) {   
    e.preventDefault();                         // Prevent form being submitted
    var text = $('input:text').val();           // Get value of text input
    var itemArr = text.split(',');                                                              
    var lngth = itemArr.length                  

    for(i = 0; i < lngth; i++)                  
    {
        $list.append('<li>' + itemArr[i] + '</li>');    // Add item to end of the list
        updateCount();                                  // Update the count
    } // End loop

    $('#addItems').val('');                         // Empty the text input
    return false;
}

$('#addItems').keypress(function(e) {
    if(e.which == 13) {
        addItem();
    }
    return false;
});

答案 1 :(得分: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
}

答案 2 :(得分: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
}

答案 3 :(得分:0)

迅速版4.2

 func scrollViewDidScroll(_ scrollView: UIScrollView) {

    if (scrollView.bounds.maxY) == scrollView.contentSize.height{
        // Call Your API or hide UIElements
     }
 }

答案 4 :(得分:0)

一个方便的扩展程序,具有两个为此计算的属性。

extension UICollectionView {

    var isLastItemFullyVisible: Bool {

        let numberOfItems = numberOfItems(inSection: 0)
        let lastIndexPath = IndexPath(item: numberOfItems - 1, section: 0)

        guard let attrs = collectionViewLayout.layoutAttributesForItem(at: lastIndexPath) 
        else { 
            return false 
        }
        return bounds.contains(attrs.frame)
    }

    // If you don't care if it's fully visible, as long as some of it is visible
    var isLastItemVisible: Bool {
       let numberOfItems = collectionView.numberOfItems(inSection: 0)
       return indexPathsForVisibleItems.contains(where: { $0.item == numberOfItems - 1 })
    }
}

isLastItemFullyVisible可以替代。一个班轮。

var isLastItemFullyVisible: Bool {
   contentSize.width == contentOffset.x + frame.width - contentInset.right
}