首页 文章

UICollectionView滚动到没有动画的最后一项

提问于
浏览
5

我有一个UICollectionView来显示聊天消息 . 在开始时,我将现有消息加载到collectionView,并使用此方法将collectionView向下滚动到最后一条消息:

- (void)scrollToLastMessageAnimated:(BOOL)animated;
{
    if (_messages.count == 0) { return; }

    NSUInteger indexOfLastSection = _messagesBySections.count - 1;
    NSInteger indexOfMessageInLastSection = [_messagesBySections[indexOfLastSection] count] - 1;
    NSIndexPath *path = [NSIndexPath indexPathForItem:indexOfMessageInLastSection
                                            inSection:indexOfLastSection];

    [_collectionView scrollToItemAtIndexPath:path
                           atScrollPosition:UICollectionViewScrollPositionCenteredVertically
                                   animated:animated];
}

这只在我在viewDidAppear:方法中调用它时才有效,而不是在viewWillAppear:方法中调用 . 如何在没有动画的情况下向下滚动?

6 回答

  • -3

    这里是...

    NSInteger section = [self.collectionView numberOfSections] - 1;
    NSInteger item = [self.collectionView numberOfItemsInSection:section] - 1;
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section];
    [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:(UICollectionViewScrollPositionBottom) animated:YES];
    
  • 8

    我还在你的另一个问题中提供了我的答案,但我也在这里写,因为这个答案只与这个问题有关

    解决方案

    要在视图出现之前滚动最后一个索引处的视图而不崩溃,首先需要触发collectionView数据的重新加载 . 重新加载后,调用您的方法滚动视图 .

    -(void)viewWillAppear:(BOOL)animated {
        [collectionView reloadData];
        [self scrollToLastMessageAnimated:YES];
    }
    

    更新

    [collectionView setContentOffset:CGPointMake(0, CGFLOAT_MAX)]
    
  • 0

    Swift 3.0 Code :

    let index = IndexPath(item: (self.mFetchedResultsControllerVar?.fetchedObjects?.count)! - 1, section: 0)
    self.collectionView?.scrollToItem(at: index, at: UICollectionViewScrollPosition.bottom, animated: true)
    
  • 2

    一个更加万无一失的解决方案,可以处理多个/ 0个部分/项目

    extension UICollectionView {
        func scrollToLastItem(at scrollPosition: UICollectionViewScrollPosition = .centeredHorizontally, animated: Bool = true) {
            let lastSection = numberOfSections - 1
            guard lastSection >= 0 else { return }
            let lastItem = numberOfItems(inSection: lastSection) - 1
            guard lastItem >= 0 else { return }
            let lastItemIndexPath = IndexPath(item: lastItem, section: lastSection)
            scrollToItem(at: lastItemIndexPath, at: scrollPosition, animated: animated)
        }
    }
    
  • 3

    此扩展滚动到实际具有项目的最后一部分 . 迄今为止的最佳方法 .

    public extension UICollectionView {
        func scrollToLastItem() {
            scrollToLastItem(animated: true, atScrollPosition: .bottom)
        }
    
        func scrollToLastItem(animated: Bool, atScrollPosition scrollPosition: UICollectionViewScrollPosition) {
            guard numberOfSections > 0 else {
                return
            }
    
            var sectionWithItems: SectionInfo?
            for section in Array(0...(numberOfSections - 1)) {
                let itemCount = numberOfItems(inSection: section)
                if itemCount > 0 {
                    sectionWithItems = SectionInfo(numberOfItems: itemCount, sectionIndex: section)
                }
            }
    
            guard let lastSectionWithItems = sectionWithItems else {
                return
            }
    
            let lastItemIndexPath = IndexPath(row: lastSectionWithItems.numberOfItems - 1, section: lastSectionWithItems.sectionIndex)
            scrollToItem(at: lastItemIndexPath, at: scrollPosition, animated: animated)
        }
    }
    
  • 0

    问题实际上是由有问题的Autolayout约束引起的,请参阅我的其他线程,找到最终帮助我的解决方案:https://stackoverflow.com/a/24033650/2302437

相关问题