我创建了一个CollectionView控件并用图像填充它.现在我想在开始时滚动到特定索引处的项目.我试过scrollToItemAtIndexPath如下:
[self.myFullScreenCollectionView scrollToItemAtIndexPath:indexPath
atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
Run Code Online (Sandbox Code Playgroud)
但是,我得到了以下异常.任何人都可以指导我在哪里出错.
2013-02-20 02:32:45.219 ControlViewCollection1[1727:c07] *** Assertion failure in
-[UICollectionViewData layoutAttributesForItemAtIndexPath:], /SourceCache/UIKit_Sim/UIKit-2380.17
/UICollectionViewData.m:485 2013-02-20 02:32:45.221 ControlViewCollection1[1727:c07] must return a
UICollectionViewLayoutAttributes instance from -layoutAttributesForItemAtIndexPath: for path
<NSIndexPath 0x800abe0> 2 indexes [0, 4]
Run Code Online (Sandbox Code Playgroud)
fol*_*ben 74
无论是bug还是功能,UIKit都会scrollToItemAtIndexPath:atScrollPosition:Animated在调用之前调UICollectionView出此错误, 然后才会显示其子视图.
作为一种解决方法,将滚动调用移动到视图控制器生命周期中您确定已经计算其布局的位置,如下所示:
@implementation CollectionViewControllerSubclass
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// scrolling here doesn't work (results in your assertion failure)
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
NSIndexPath *indexPath = // compute some index path
// scrolling here does work
[self.collectionView scrollToItemAtIndexPath:indexPath
atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally
animated:YES];
}
@end
Run Code Online (Sandbox Code Playgroud)
至少,错误消息应该更有帮助.我打开了一个rdar:// 13416281 ; 请欺骗.
Cod*_*der 51
如果你想在视图控制器加载时要滚动,请确保调用layoutIfNeeded在UICollectionView你打电话之前scrollToItemAtIndexPath.这比将视图滚动逻辑放在viewDidLayoutSubviews中要好,因为每次布置父视图的子视图时都不会执行滚动操作.
jws*_*art 14
有时collectionView(_:didSelectItemAt:)要么不在主线程上调用,要么阻塞它,导致scrollToItem(at:at:animated:)不做任何事情.
通过以下方式解决此问题:
DispatchQueue.main.async {
collectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
}
Run Code Online (Sandbox Code Playgroud)
你可以在viewDidLoad方法上执行此操作
只需调用preformBatchUpdates
[self performBatchUpdates:^{
if ([self.segmentedDelegate respondsToSelector:@selector(segmentedBar:selectedIndex:)]){
[self.segmentedDelegate segmentedBar:self selectedIndex:_selectedPage];
}
} completion:^(BOOL finished) {
if (finished){
[self scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:_selectedPage inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
}
}];
Run Code Online (Sandbox Code Playgroud)
在我的情况下,我的子类CollectionView有一个属性selectedPage,并在我调用的这个属性的setter上
- (void)setSelectedPage:(NSInteger)selectedPage {
_selectedPage = selectedPage;
[self performBatchUpdates:^{
if ([self.segmentedDelegate respondsToSelector:@selector(segmentedBar:selectedIndex:)]){
[self.segmentedDelegate segmentedBar:self selectedIndex:_selectedPage];
}
} completion:^(BOOL finished) {
if (finished){
[self scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:_selectedPage inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
}
}];
}
Run Code Online (Sandbox Code Playgroud)
在视图控制器中我通过代码调用它
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationBar.segmentedPages.selectedPage = 1;
}
Run Code Online (Sandbox Code Playgroud)
从iOS 9.3开始,Xcode 8.2.1,Swift 3:
调用scrollToItem(at:)从viewWillAppear()仍然是断开的,特别是如果你正在使用部分页眉/页脚,自动布局,科插图.
即使你打电话setNeedsLayout()和layoutIfNeeded()上collectionView,行为仍然是borked.将滚动代码放入动画块中无法可靠地工作.
如其他答案所示,解决方案是只有scrollToItem(at:)在确定所有内容都已布置后才会调用.即viewDidLayoutSubviews().
但是,你需要有选择性; 你不想每次viewWillLayoutSubviews()调用都要执行滚动.因此,解决方案是在其中设置标志viewWillAppear(),并在其上执行操作viewDidLayoutSubviews().
即
fileprivate var needsDelayedScrolling = false
override func viewWillAppear(_ animated: Bool)
{
super.viewWillAppear(animated)
self.needsDelayedScrolling = true
// ...
}
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
if self.needsDelayedScrolling {
self.needsDelayedScrolling = false
self.collectionView!.scrollToItem(at: someIndexPath,
at: .centeredVertically,
animated: false)
}
}
}
Run Code Online (Sandbox Code Playgroud)
还要记住,您需要使用正确的 UICollectionviewScrollPosition 值。请参阅以下代码以进行说明:
typedef NS_OPTIONS(NSUInteger, UICollectionViewScrollPosition) {
UICollectionViewScrollPositionNone = 0,
/* For a view with vertical scrolling */
// The vertical positions are mutually exclusive to each other, but are bitwise or-able with the horizontal scroll positions.
// Combining positions from the same grouping (horizontal or vertical) will result in an NSInvalidArgumentException.
UICollectionViewScrollPositionTop = 1 << 0,
UICollectionViewScrollPositionCenteredVertically = 1 << 1,
UICollectionViewScrollPositionBottom = 1 << 2,
/* For a view with horizontal scrolling */
// Likewise, the horizontal positions are mutually exclusive to each other.
UICollectionViewScrollPositionLeft = 1 << 3,
UICollectionViewScrollPositionCenteredHorizontally = 1 << 4,
UICollectionViewScrollPositionRight = 1 << 5
Run Code Online (Sandbox Code Playgroud)
};
| 归档时间: |
|
| 查看次数: |
29319 次 |
| 最近记录: |