一种滚动比较柔和的banner

2017-08-15 11_16_24.gif

在开发时遇到一种效果比一般普通banner滚动起来要柔和的效果,在参考了
YouXianMing的Animations后,发现他的demo里有一个很好的效果,然后把这个效果搬到使用最多的banner控件
SDCycleScrollView里,我的demodevliuhuan/SDCycleScrollView


我提到的2个第三方库或demo使用都是UICollectionView来实现的,要实现这个比较柔和的滚动包含2个要点

  1. 让可见的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"];

你可能感兴趣的:(一种滚动比较柔和的banner)