2013-04-13 42 views
76

在加载集合视图之前,用户设置集合视图数组中图像的数量。所有的单元格都不适合在屏幕上。我有30个单元格,屏幕上只有6个单元格。UICollectionView自动滚动到IndexPath处的单元格

问题:如何在UICollectionView的加载时自动滚动到所需图像的单元格?

回答

136

新编辑的答案:

viewDidLayoutSubviews

-(void)viewDidLayoutSubviews { 
    [super viewDidLayoutSubviews]; 
    [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO]; 
} 

旧答案添加这对老年人的iOS工作

viewWillAppear补充一点:

[self.view layoutIfNeeded]; 
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO]; 
+4

这正是我想要使用的。我有数组中的对象的编号,我知道该对象的名称。但不知道如何把正确的indexPath ...任何想法? – AlexanderZ

+4

您可以轻松创建'indexPath':'[NSIndexPath indexPathForItem:numberOfTheObject切入口:sectionNumber]' –

+3

有一些错误。但后来我把所有提到的代码放在(void)viewDidLayoutSubviews {}中,现在它工作正常。 Thanx Bogdan。 – AlexanderZ

13

我完全同意上面的答案。唯一的一点是,我将溶液设置代码在viewDidAppear

viewDidAppear 
{ 
    [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES]; 
} 

当我使用的viewWillAppear中滚动没有工作。

+0

我秒! – Mike

+1

viewDidAppear有你看到的集合视图移动/闪烁,认为已经出现(顾名思义)的缺点......我真的不知道为什么苹果没有设计一个更好的方式这并不那么罕见的情况下,viewDidLayoutSubviews方式有点尴尬 – TheEye

68

我发现,在viewWillAppear中滚动因为集合视图还没有完成它的布局却可能无法可靠地工作;您可能会滚动到错误的项目。

我还发现,在viewDidAppear滚动会导致视未涡卷的瞬间闪光可见。

而且,如果每次通过viewDidLayoutSubviews滚动,用户将无法手动滚动,因为某些集合布局每次滚动时都会导致子视图布局。

这里是我的发现工作可靠:

- (void)viewDidLayoutSubviews { 
    [super viewDidLayoutSubviews]; 

    // If we haven't done the initial scroll, do it once. 
    if (!self.initialScrollDone) { 
     self.initialScrollDone = YES; 

     [self.collectionView scrollToItemAtIndexPath:self.myInitialIndexPath 
            atScrollPosition:UICollectionViewScrollPositionRight animated:NO]; 
    } 
} 
+0

好的提示。作为伦克做了,我会强调使用'initialScrollDone'标志,因为这种方法将被调用一次以上,如果你打电话scrollToItemAtIndexPath:不止一次,似乎呈现的CollectionView unscrollable(的iOS模拟器iPhone 5/8的iOS) – maz

+1

THX ,这应该是被接受的答案 – Jakob

+1

在iOS8中很好用。应该是被接受的答案。 – Nick

11

这似乎为我工作,它类似于另一种答案,但有一些明显的区别:

- (void)viewDidLayoutSubviews 
{  
    [self.collectionView layoutIfNeeded]; 
    NSArray *visibleItems = [self.collectionView indexPathsForVisibleItems]; 
    NSIndexPath *currentItem = [visibleItems objectAtIndex:0]; 
    NSIndexPath *nextItem = [NSIndexPath indexPathForItem:someInt inSection:currentItem.section]; 

    [self.collectionView scrollToItemAtIndexPath:nextItem atScrollPosition:UICollectionViewScrollPositionNone animated:YES]; 
} 
10

斯威夫特:

your_CollectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true) 

Swift 3

let indexPath = IndexPath(row: itemIndex, section: sectionIndex) 

collectionView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition.right, animated: true) 

滚动位置:

UICollectionViewScrollPosition.CenteredHorizontally/UICollectionViewScrollPosition.CenteredVertically 
7

您可以使用GCD到滚动派遣到主运行循环的viewDidLoad中的下一个迭代,以实现这种行为。滚动将在收集视图显示在屏幕上之前执行,因此不会闪烁。

- (void)viewDidLoad { 
    dispatch_async (dispatch_get_main_queue(), ^{ 
     NSIndexPath *indexPath = YOUR_DESIRED_INDEXPATH; 
     [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO]; 
    }); 
} 
+0

这是唯一适合我的方法 –

0

这里的所有答案 - 黑客。我已经找到更好的办法来relaodData后滚动某处集合视图:
什么都布局在使用 子类集合视图布局,覆盖方法prepareLayout,超级呼叫建立什么都偏移,您需要之后。
ex:https://stackoverflow.com/a/34192787/1400119

0

我会建议在collectionView: willDisplay:这样做,然后你可以确定集合视图委托提供了一些东西。 这里我的例子:

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { 
    /// this is done to set the index on start to 1 to have at index 0 the last image to have a infinity loop 
    if !didScrollToSecondIndex { 
     self.scrollToItem(at: IndexPath(row: 1, section: 0), at: .left, animated: false) 
     didScrollToSecondIndex = true 
    } 
} 
相关问题