在开发时遇到一种效果比一般普通banner滚动起来要柔和的效果,在参考了
YouXianMing的Animations后,发现他的demo里有一个很好的效果,然后把这个效果搬到使用最多的banner控件
SDCycleScrollView里,我的demodevliuhuan/SDCycleScrollView
我提到的2个第三方库或demo使用都是UICollectionView来实现的,要实现这个比较柔和的滚动包含2个要点
- 让可见的Cell根据UICollectionView的contentOffset进行变化
1.1 让collectionView的contentOffset变化通知Cell
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (!self.imagePathsGroup.count) return; // 解决清除timer时偶尔会出现的问题
if (self.scrollAnimationStyle == SDCycleScrollAnimationStyleLight) {
__weak typeof(self) weakSelf = self;
[self.mainView.visibleCells enumerateObjectsUsingBlock:^(__kindof SDCollectionViewCell *obj, NSUInteger idx, BOOL * _Nonnull stop) {
// 用于竖向
CGPoint point = [obj convertPoint:obj.bounds.origin fromView:weakSelf];
if ([obj respondsToSelector:@selector(contentOffset:)]) {
[obj contentOffset:point];
}
}];
}
}
1.2 Cell在接受到contentOffset的变化后根据是横向还是竖向滚动进行Cell的操作
- (void)contentOffset:(CGPoint)offset {
if (self.scrollDirection == UICollectionViewScrollDirectionVertical) {
self.imageView.frame = CGRectMake(self.imageView.frame.origin.x, offset.y * 0.85f, self.imageView.frame.size.width, self.imageView.frame.size.height);
}else{
[self resetImageViewCenterPoint];
}
}
- (void)resetImageViewCenterPoint {
CGPoint point = [self convertPoint:CGPointZero toView:self.window];
CGPoint newCenter = self.center;
newCenter.x = -0.9 * point.x + 187.5; // ?
self.imageView.center = newCenter;
}
2、 在开启自动滚动时,SDCycleScrollViev是用UICollectionView的自带的滚动方法实现的,这个动画比较短,显得也不那么柔和,我此处使用POP的自定义动画,将滚动的过程来自定义滚动
__weak typeof(self) weakSelf = self;
POPAnimatableProperty *prop = [POPAnimatableProperty propertyWithName:@"prop" initializer:^(POPMutableAnimatableProperty *prop) {
// read value
prop.readBlock = ^(id obj, CGFloat values[]) {
};
// write value
prop.writeBlock = ^(id obj, const CGFloat values[]) {
//NSLog(@"old:%f current:%f,to:%f",offsetX,values[0],offsetX);
weakSelf.mainView.contentOffset = self.flowLayout.scrollDirection == UICollectionViewScrollDirectionHorizontal ? CGPointMake(values[0], 0) : CGPointMake(0,values[0]);
};
// dynamics threshold
prop.threshold = 0.01;
}];
CGFloat oldOffsetValue = self.flowLayout.scrollDirection == UICollectionViewScrollDirectionHorizontal ? self.mainView.contentOffset.x : self.mainView.contentOffset.y;
CGFloat newOffsetValue = self.flowLayout.scrollDirection == UICollectionViewScrollDirectionHorizontal ? self.flowLayout.itemSize.width*targetIndex : self.flowLayout.itemSize.height*targetIndex;
POPBasicAnimation *anBasic = [POPBasicAnimation easeInEaseOutAnimation]; //秒表当然必须是线性的时间函数
anBasic.property = prop; //自定义属性
anBasic.fromValue = @(oldOffsetValue); //从0开始
anBasic.toValue = @(newOffsetValue);
anBasic.duration = 1.5; //持续1.5秒
anBasic.beginTime = CACurrentMediaTime() + 0.0f; //延迟1秒开始
[self.mainView pop_addAnimation:anBasic forKey:@"autoScroll"];
网友评论