设置 contentInset 后 UICollectionView 不滚动
UICollectionView doesn't scroll after setting contentInset
我有一个水平滚动并跨越其父视图全宽的集合视图。我实现分页的廉价方法是将单元格宽度设置为等于集合视图宽度的 1/3,并将宽度设置为与左右内容插图相同的宽度。
我在 IB 中禁用滚动并替换为左右滑动识别器。我的代码几乎可以在不设置 contentInset
的情况下工作,但是设置 contentInset
似乎可以防止任何滚动发生
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
CGFloat itemWidth = self.collectionView.bounds.size.width/3.0;
NSInteger count = [self collectionView:self.collectionView numberOfItemsInSection:0];
self.collectionView.contentSize = (CGSize){ .width=itemWidth*count, .height=self.collectionView.bounds.size.height };
// uncomment this line, and the scroll code in the swipes below fails to work
//self.collectionView.contentInset = UIEdgeInsetsMake(0, itemWidth, 0, itemWidth);
self.collectionView.contentOffset = (CGPoint){ .x=self.collectionView.contentSize.width/2.0, .y=0 };
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGFloat width = self.view.bounds.size.width/3.0;
return (CGSize){ .width=width, .height=collectionView.bounds.size.height };
}
此代码处理滑动...
- (NSIndexPath *)centerIndexPath {
CGRect visibleRect = (CGRect){.origin = self.collectionView.contentOffset, .size = self.collectionView.bounds.size};
CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
return [self.collectionView indexPathForItemAtPoint:visiblePoint];
}
- (void)swipeLeft:(UISwipeGestureRecognizer *)gr {
NSIndexPath *centerIndexPath = [self centerIndexPath];
NSLog(@"at %@", centerIndexPath);
if (centerIndexPath.row < [self collectionView:self.collectionView numberOfItemsInSection:0]-1) {
[self.collectionView scrollToItemAtIndexPath:centerIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
}
}
- (void)swipeRight:(UISwipeGestureRecognizer *)gr {
NSIndexPath *centerIndexPath = [self centerIndexPath];
NSLog(@"at %@", centerIndexPath);
if (centerIndexPath.row > 0) {
[self.collectionView scrollToItemAtIndexPath:centerIndexPath atScrollPosition:UICollectionViewScrollPositionRight animated:YES];
}
}
除了我在上面的设置中设置 contentInsets 之外,所有这些都有效。然后,即使我到达了 scrollToItemAtIndexPath: 调试器中的代码,也没有发生滚动。
有这些插图很重要,因为我希望用户了解中心项目是所选项目。
有人可以解释为什么 contentInset 会破坏滚动以及如何修复吗?
看起来 UICollectionView 有自己的内置方式来处理插入:
使用部分插入调整内容的边距
部分插图是一种调整可用于布局单元格的 space 的方法。您可以使用 insets 在节的页眉视图之后和页脚视图之前插入 space。您还可以使用插图在内容的两侧插入 space。图 3-5 演示了插入如何影响垂直滚动流布局中的某些内容。
图 3-5 部分插图更改了可用的 space 单元格布局
我有一个水平滚动并跨越其父视图全宽的集合视图。我实现分页的廉价方法是将单元格宽度设置为等于集合视图宽度的 1/3,并将宽度设置为与左右内容插图相同的宽度。
我在 IB 中禁用滚动并替换为左右滑动识别器。我的代码几乎可以在不设置 contentInset
的情况下工作,但是设置 contentInset
似乎可以防止任何滚动发生
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
CGFloat itemWidth = self.collectionView.bounds.size.width/3.0;
NSInteger count = [self collectionView:self.collectionView numberOfItemsInSection:0];
self.collectionView.contentSize = (CGSize){ .width=itemWidth*count, .height=self.collectionView.bounds.size.height };
// uncomment this line, and the scroll code in the swipes below fails to work
//self.collectionView.contentInset = UIEdgeInsetsMake(0, itemWidth, 0, itemWidth);
self.collectionView.contentOffset = (CGPoint){ .x=self.collectionView.contentSize.width/2.0, .y=0 };
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
CGFloat width = self.view.bounds.size.width/3.0;
return (CGSize){ .width=width, .height=collectionView.bounds.size.height };
}
此代码处理滑动...
- (NSIndexPath *)centerIndexPath {
CGRect visibleRect = (CGRect){.origin = self.collectionView.contentOffset, .size = self.collectionView.bounds.size};
CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
return [self.collectionView indexPathForItemAtPoint:visiblePoint];
}
- (void)swipeLeft:(UISwipeGestureRecognizer *)gr {
NSIndexPath *centerIndexPath = [self centerIndexPath];
NSLog(@"at %@", centerIndexPath);
if (centerIndexPath.row < [self collectionView:self.collectionView numberOfItemsInSection:0]-1) {
[self.collectionView scrollToItemAtIndexPath:centerIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
}
}
- (void)swipeRight:(UISwipeGestureRecognizer *)gr {
NSIndexPath *centerIndexPath = [self centerIndexPath];
NSLog(@"at %@", centerIndexPath);
if (centerIndexPath.row > 0) {
[self.collectionView scrollToItemAtIndexPath:centerIndexPath atScrollPosition:UICollectionViewScrollPositionRight animated:YES];
}
}
除了我在上面的设置中设置 contentInsets 之外,所有这些都有效。然后,即使我到达了 scrollToItemAtIndexPath: 调试器中的代码,也没有发生滚动。
有这些插图很重要,因为我希望用户了解中心项目是所选项目。
有人可以解释为什么 contentInset 会破坏滚动以及如何修复吗?
看起来 UICollectionView 有自己的内置方式来处理插入:
使用部分插入调整内容的边距 部分插图是一种调整可用于布局单元格的 space 的方法。您可以使用 insets 在节的页眉视图之后和页脚视图之前插入 space。您还可以使用插图在内容的两侧插入 space。图 3-5 演示了插入如何影响垂直滚动流布局中的某些内容。
图 3-5 部分插图更改了可用的 space 单元格布局