ios UICollectionView 自动滚动到 IndexPath 处的单元格
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15985574/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UICollectionView auto scroll to cell at IndexPath
提问by AlexanderZ
Before loading the collection view user sets the number of image in the array of collection view. All of the cells don't fit on the screen. I have 30 cells and only 6 on the screen.
在加载集合视图之前,用户设置集合视图数组中的图像数量。所有单元格都不适合屏幕。我有 30 个单元格,屏幕上只有 6 个。
The question: How to scroll to the cell with desired image automatically at the load of UICollectionView?
问题:如何在加载 UICollectionView 时自动滚动到具有所需图像的单元格?
采纳答案by LenK
I've found that scrolling in viewWillAppear
may not work reliably because the collection view hasn't finished it's layout yet; you may scroll to the wrong item.
我发现滚动viewWillAppear
可能无法可靠地工作,因为集合视图还没有完成它的布局;您可能会滚动到错误的项目。
I've also found that scrolling in viewDidAppear
will cause a momentary flash of the unscrolled view to be visible.
我还发现滚动viewDidAppear
会导致未滚动视图的瞬间闪烁可见。
And, if you scroll every time through viewDidLayoutSubviews
, the user won't be able to manually scroll because some collection layouts cause subview layout every time you scroll.
而且,如果您每次都滚动viewDidLayoutSubviews
,用户将无法手动滚动,因为每次滚动时某些集合布局都会导致子视图布局。
Here's what I found works reliably:
这是我发现可靠的工作:
Objective C :
目标C:
- (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];
}
}
Swift :
斯威夫特:
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if (!self.initialScrollDone) {
self.initialScrollDone = true
self.testNameCollectionView.scrollToItem(at:selectedIndexPath, at: .centeredHorizontally, animated: true)
}
}
回答by boweidmann
New, Edited Answer:
新的,编辑的答案:
Add this in viewDidLayoutSubviews
添加这个 viewDidLayoutSubviews
SWIFT
迅速
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let indexPath = IndexPath(item: 12, section: 0)
self.collectionView.scrollToItem(at: indexPath, at: [.centeredVertically, .centeredHorizontally], animated: true)
}
Normally, .centerVertically
is the case
通常情况下.centerVertically
是这样
ObjC
对象
-(void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:12 inSection:0];
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically | UICollectionViewScrollPositionCenteredHorizontally animated:NO];
}
Old answer working for older iOS
适用于较旧 iOS 的旧答案
Add this in viewWillAppear
:
将此添加到viewWillAppear
:
[self.view layoutIfNeeded];
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO];
回答by raistlin
I totally agree with the above answer. The only thing is that for me the solution was set the code in viewDidAppear
我完全同意上面的回答。唯一的问题是,对我来说,解决方案是在 viewDidAppear 中设置代码
viewDidAppear
{
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES];
}
When I used the viewWillAppear the scrolling didn't work.
当我使用 viewWillAppear 时,滚动不起作用。
回答by greenhouse
this seemed to work for me, its similar to another answer but has some distinct differences:
这似乎对我有用,它类似于另一个答案,但有一些明显的区别:
- (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];
}
回答by Rajesh Loganathan
Swift:
迅速:
your_CollectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)
Swift 3
斯威夫特 3
let indexPath = IndexPath(row: itemIndex, section: sectionIndex)
collectionView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition.right, animated: true)
Scroll Position:
滚动位置:
UICollectionViewScrollPosition.CenteredHorizontally / UICollectionViewScrollPosition.CenteredVertically
回答by Tianyu Wang
You can use GCD to dispatch the scroll into the next iteration of main run loop in viewDidLoad to achieve this behavior. The scroll will be performed before the collection view is showed on screen, so there will be no flashing.
您可以使用 GCD 将滚动分派到 viewDidLoad 中主运行循环的下一次迭代中以实现此行为。滚动将在集合视图显示在屏幕上之前执行,因此不会闪烁。
- (void)viewDidLoad {
dispatch_async (dispatch_get_main_queue (), ^{
NSIndexPath *indexPath = YOUR_DESIRED_INDEXPATH;
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
});
}
回答by Eike
I would recommend doing it in collectionView: willDisplay:
Then you can be sure that the collection view delegate delivers something.
Here my example:
我会建议这样做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
}
}
回答by nCod3d
As an alternative to mentioned above. Call after data load:
作为上述的替代方案。数据加载后调用:
Swift
迅速
collectionView.reloadData()
collectionView.layoutIfNeeded()
collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .right)
回答by trickster77777
All answers here - hacks. I've found better way to scroll collection view somewhere after relaodData:
Subclass collection view layout what ever layout you use, override method prepareLayout, after super call set what ever offset you need.
ex: https://stackoverflow.com/a/34192787/1400119
这里的所有答案 - 黑客。我找到了在 relaodData 之后在某处滚动集合视图的更好方法:
子类集合视图布局无论您使用什么布局,覆盖方法 prepareLayout,在超级调用之后设置您需要的偏移量。
例如:https: //stackoverflow.com/a/34192787/1400119