【问题标题】:UICollectionView scroll to last item without AnimationUICollectionView 滚动到没有动画的最后一项
【发布时间】:2014-06-02 15:17:43
【问题描述】:

我有一个 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: 方法中调用它时,它才可以动画。如何在没有动画的情况下向下滚动?

【问题讨论】:

  • 如果水平我使用这个 CGFloat startx = self.neWBooksCollectionView.contentSize.width - 320; [self.neWBooksCollectionView scrollRectToVisible:CGRectMake(startx, 0, 320, 1) 动画:YES];

标签: ios objective-c scroll uicollectionview


【解决方案1】:

这里是……

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];

【讨论】:

    【解决方案2】:

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

    解决方案

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

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

    更新

    [collectionView setContentOffset:CGPointMake(0, CGFLOAT_MAX)]
    

    【讨论】:

    • 它不起作用:/根本没有滚动发生,只有当我在 viewDidAppear 中调用该方法时:
    • @BenMarten 在视图出现之前定义它的偏移量。答案已编辑
    • setContentOffset 对我有用。您只需要确保创建正确的点,具体取决于您的布局。例如,对于水平滚动布局,您应该传递 CGPointMake(CGFLOAT_MAX, 0) ,因为您想影响 x 坐标,而不是 y。
    【解决方案3】:

    Swift 3.0 代码:

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

    【讨论】:

      【解决方案4】:

      处理多个/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)
          }
      }
      

      【讨论】:

        【解决方案5】:

        此扩展滚动到实际包含项目的最后一个部分。 迄今为止最好的方法。

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

        【讨论】:

          【解决方案6】:

          这个问题实际上是由有问题的 Autolayout 约束引起的, 请参阅我的其他帖子以了解最终帮助我的解决方案:https://stackoverflow.com/a/24033650/2302437

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-01-22
            • 2022-01-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-07-19
            相关资源
            最近更新 更多