targetContentOffsetForProposedContentOffset:

我的应用程序中有一个非常简单的collectionView(仅一行方形缩略图)。


我想拦截滚动,以便偏移量始终在左侧保留完整图像。此刻,它滚动到任何地方,都将留下剪切的图像。


无论如何,我知道我需要使用该功能


- (CGPoint)targetContentOffsetForProposedContentOffset:withScrollingVelocity

做到这一点,但我只是使用一个标准UICollectionViewFlowLayout。我不是子类化。


没有子类,有没有办法拦截它UICollectionViewFlowLayout?


汪汪一只猫
浏览 2132回答 3
3回答

RISEBY

好的,答案是否定的,没有子类化UICollectionViewFlowLayout,就无法做到这一点。但是,对于以后阅读此书的任何人来说,将其分类非常容易。首先,我设置了子类调用MyCollectionViewFlowLayout,然后在界面构建器中,将集合视图布局更改为“自定义”,然后选择了流布局子类。因为您是用这种方式做的,所以您无法在IB中指定项目大小等,因此在MyCollectionViewFlowLayout.m中,我有这个...- (void)awakeFromNib{&nbsp; &nbsp; self.itemSize = CGSizeMake(75.0, 75.0);&nbsp; &nbsp; self.minimumInteritemSpacing = 10.0;&nbsp; &nbsp; self.minimumLineSpacing = 10.0;&nbsp; &nbsp; self.scrollDirection = UICollectionViewScrollDirectionHorizontal;&nbsp; &nbsp; self.sectionInset = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);}这将为我设置所有尺寸以及滚动方向。然后 ...- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity{&nbsp; &nbsp; CGFloat offsetAdjustment = MAXFLOAT;&nbsp; &nbsp; CGFloat horizontalOffset = proposedContentOffset.x + 5;&nbsp; &nbsp; CGRect targetRect = CGRectMake(proposedContentOffset.x, 0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);&nbsp; &nbsp; NSArray *array = [super layoutAttributesForElementsInRect:targetRect];&nbsp; &nbsp; for (UICollectionViewLayoutAttributes *layoutAttributes in array) {&nbsp; &nbsp; &nbsp; &nbsp; CGFloat itemOffset = layoutAttributes.frame.origin.x;&nbsp; &nbsp; &nbsp; &nbsp; if (ABS(itemOffset - horizontalOffset) < ABS(offsetAdjustment)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; offsetAdjustment = itemOffset - horizontalOffset;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);}这样可以确保滚动在左侧边缘以5.0的边距结束。这就是我要做的。我根本不需要在代码中设置流布局。

跃然一笑

它不能很好地处理用户轻弹。用户快速滑动而滚动没有移动太多的情况下,会出现动画故障。我提出的替代实现与以前提出的分页相同,但是可以处理页面之间的用户滑动。 #pragma mark - Pagination - (CGFloat)pageWidth {     return self.itemSize.width + self.minimumLineSpacing; } - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {                   CGFloat rawPageValue = self.collectionView.contentOffset.x / self.pageWidth;        CGFloat currentPage = (velocity.x > 0.0) ? floor(rawPageValue) : ceil(rawPageValue);        CGFloat nextPage = (velocity.x > 0.0) ? ceil(rawPageValue) : floor(rawPageValue);        BOOL pannedLessThanAPage = fabs(1 + currentPage - rawPageValue) > 0.5;        BOOL flicked = fabs(velocity.x) > [self flickVelocity];        if (pannedLessThanAPage && flicked) {            proposedContentOffset.x = nextPage * self.pageWidth;        } else {            proposedContentOffset.x = round(rawPageValue) * self.pageWidth;        }        return proposedContentOffset; } - (CGFloat)flickVelocity {     return 0.3; }

隔江千里

接受答案的Swift版本。override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {&nbsp; &nbsp; var offsetAdjustment = CGFloat.greatestFiniteMagnitude&nbsp; &nbsp; let horizontalOffset = proposedContentOffset.x&nbsp; &nbsp; let targetRect = CGRect(origin: CGPoint(x: proposedContentOffset.x, y: 0), size: self.collectionView!.bounds.size)&nbsp; &nbsp; for layoutAttributes in super.layoutAttributesForElements(in: targetRect)! {&nbsp; &nbsp; &nbsp; &nbsp; let itemOffset = layoutAttributes.frame.origin.x&nbsp; &nbsp; &nbsp; &nbsp; if (abs(itemOffset - horizontalOffset) < abs(offsetAdjustment)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; offsetAdjustment = itemOffset - horizontalOffset&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return CGPoint(x: proposedContentOffset.x + offsetAdjustment, y: proposedContentOffset.y)}对Swift 3有效。
打开App,查看更多内容
随时随地看视频慕课网APP