3 回答
TA贡献1856条经验 获得超5个赞
好的,答案是否定的,没有子类化UICollectionViewFlowLayout,就无法做到这一点。
但是,对于以后阅读此书的任何人来说,将其分类非常容易。
首先,我设置了子类调用MyCollectionViewFlowLayout,然后在界面构建器中,将集合视图布局更改为“自定义”,然后选择了流布局子类。
因为您是用这种方式做的,所以您无法在IB中指定项目大小等,因此在MyCollectionViewFlowLayout.m中,我有这个...
- (void)awakeFromNib
{
self.itemSize = CGSizeMake(75.0, 75.0);
self.minimumInteritemSpacing = 10.0;
self.minimumLineSpacing = 10.0;
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.sectionInset = UIEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
}
这将为我设置所有尺寸以及滚动方向。
然后 ...
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
CGFloat offsetAdjustment = MAXFLOAT;
CGFloat horizontalOffset = proposedContentOffset.x + 5;
CGRect targetRect = CGRectMake(proposedContentOffset.x, 0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
NSArray *array = [super layoutAttributesForElementsInRect:targetRect];
for (UICollectionViewLayoutAttributes *layoutAttributes in array) {
CGFloat itemOffset = layoutAttributes.frame.origin.x;
if (ABS(itemOffset - horizontalOffset) < ABS(offsetAdjustment)) {
offsetAdjustment = itemOffset - horizontalOffset;
}
}
return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}
这样可以确保滚动在左侧边缘以5.0的边距结束。
这就是我要做的。我根本不需要在代码中设置流布局。
TA贡献1826条经验 获得超6个赞
它不能很好地处理用户轻弹。用户快速滑动而滚动没有移动太多的情况下,会出现动画故障。
我提出的替代实现与以前提出的分页相同,但是可以处理页面之间的用户滑动。
#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;
}
TA贡献1906条经验 获得超10个赞
接受答案的Swift版本。
override func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
var offsetAdjustment = CGFloat.greatestFiniteMagnitude
let horizontalOffset = proposedContentOffset.x
let targetRect = CGRect(origin: CGPoint(x: proposedContentOffset.x, y: 0), size: self.collectionView!.bounds.size)
for layoutAttributes in super.layoutAttributesForElements(in: targetRect)! {
let itemOffset = layoutAttributes.frame.origin.x
if (abs(itemOffset - horizontalOffset) < abs(offsetAdjustment)) {
offsetAdjustment = itemOffset - horizontalOffset
}
}
return CGPoint(x: proposedContentOffset.x + offsetAdjustment, y: proposedContentOffset.y)
}
对Swift 3有效。
- 3 回答
- 0 关注
- 2120 浏览
添加回答
举报