设置 contentInset 后 UICollectionView 不滚动 [英] UICollectionView doesn't scroll after setting contentInset
问题描述
我有一个水平滚动并跨越其父视图全宽的集合视图.我实现分页的廉价方法是将单元格宽度设置为等于集合视图宽度的 1/3,并将宽度设置为与左右内容插入相同的宽度.
我在 IB 中禁用滚动并替换为左右滑动识别器.我的代码几乎没有设置 contentInset
就可以工作,但是设置 contentInset
似乎可以防止任何滚动发生
- (void)viewDidLayoutSubviews {[超级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 };//取消注释这一行,下面滑动中的滚动代码不起作用//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 宽度 = self.view.bounds.size.width/3.0;return (CGSize){ .width=width, .height=collectionView.bounds.size.height };}
此代码处理滑动...
- (NSIndexPath *)centerIndexPath {CGRectvisibleRect = (CGRect){.origin = self.collectionView.contentOffset, .size = self.collectionView.bounds.size};CGPoint 可见点 = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));返回 [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 动画:YES];}}- (void)swipeRight:(UISwipeGestureRecognizer *)gr {NSIndexPath *centerIndexPath = [self centerIndexPath];NSLog(@"at %@", centerIndexPath);如果(centerIndexPath.row > 0){[self.collectionView scrollToItemAtIndexPath:centerIndexPath atScrollPosition:UICollectionViewScrollPositionRight 动画:YES];}}
所有这些都有效,除非我在上面的设置中设置了 contentInsets.然后,即使我到达了调试器中的 scrollToItemAtIndexPath: 代码,也不会发生滚动.
拥有这些插图很重要,因为我希望用户了解中心项目是所选项目.
有人可以解释为什么 contentInset 会破坏滚动以及如何修复吗?
看起来 UICollectionView 有自己的内置方式来处理插入:
I have a collection view that scrolls horizontally and spans its parent view's full width. My cheap way to achieve paging on it is to set the cell widths to be equal to 1/3 of the collection view width, and to set that same amount of width as left and right content insets.
I disable scrolling in IB and replace with left and right swipe recognizers. My code almost works without setting contentInset
, but setting the contentInset
seems prevent any scrolling from happening
- (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 };
}
This code handles the swipes...
- (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];
}
}
All of this works, except when I set the contentInsets in the setup above. Then, even though I reach the scrollToItemAtIndexPath: code in the debugger, no scrolling occurs.
It's important to have those insets, because I want user to understand that center item is the selected item.
Can somebody explain why contentInset spoils scrolling and how to fix?
It looks like UICollectionView has its own built-in way to handle insets:
Using Section Insets to Tweak the Margins of Your Content Section insets are a way to adjust the space available for laying out cells. You can use insets to insert space after a section’s header view and before its footer view. You can also use insets to insert space around the sides of the content. Figure 3-5 demonstrates how insets affect some content in a vertically scrolling flow layout.
Figure 3-5 Section insets change the available space for laying out cells
这篇关于设置 contentInset 后 UICollectionView 不滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!