美文网首页OC开发
利用UICollectionView实现电影轮播图效果

利用UICollectionView实现电影轮播图效果

作者: 静谧无际 | 来源:发表于2016-09-07 18:06 被阅读320次

    在开发项目的过程中,有一个类似电影轮播效果的需求,最中间图片正常显示,两侧的图片随着偏移量的改变而缩小,并且具有pageEnable的效果,最初在github上找到类似的一个控件,该控件是对scrollView进行的自定制,虽然可以实现想要的效果但是内存消耗的大多,生成了许多多余的视图,最后决定自己定制该效果的视图。

    目的效果

    效果图.png

    效果分析

    • 图片需要随偏移量的改变而缩小,可以自定义UICollectionViewFlowLayout来实现该效果。
    • 控件需要实现pageable的效果,但需要自定义,pageable移动的距离。
    • 要注意内存的使用,要实现视图重用。
      经过分析,继承UICollectionView来实现目的效果。

    实现过程

    • 解决pageable的移动距离
    -(void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
    self.velocity = velocity;
       self.endPoint = scrollView.contentOffset;
       self.direction = self.startPoint.x <= self.endPoint.x ? FlowDirectionRight : FlowDirectionLeft;
       CGFloat x = targetContentOffset->x;
       CGFloat y = targetContentOffset->y;
       self.targetPoint = CGPointMake(x, y);
       NSInteger currentPage = [self currentPageWithScrollView:scrollView];
       CGFloat overOffsetX = scrollView.contentOffset.x -  currentPage* self.pageLength - self.itemLength/2;//滑动到最左端时进行定位
    if(overOffsetX < 0){
           targetContentOffset->x = self.contentOffset.x;
           [scrollView setContentOffset:CGPointMake(self.itemLength/2, 0) animated:YES];
           self.currentPage = 0;
           return;
       }//滑动最右端是进行定位
       CGFloat maxOffsetX = (self.contentSize.width - self.frame.size.width - self.itemLength/2);
       if(self.contentOffset.x > maxOffsetX){
           targetContentOffset->x = self.contentOffset.x;
           [scrollView setContentOffset:CGPointMake(maxOffsetX, 0) animated:YES];
           self.currentPage = self.itemImages.count-3;
           return;
       }//当向右滑动时
       if(self.direction == FlowDirectionRight){
           if(overOffsetX >= self.pageLength/7){
               targetContentOffset->x = (currentPage+1)*self.pageLength+self.itemLength/2;
               self.currentPage = currentPage+1;
           }else{
               self.currentPage = currentPage;
               if(self.velocity.x == 0){
                   targetContentOffset->x = (currentPage)*self.pageLength+self.itemLength/2;
               }else{
                   
                   targetContentOffset->x = scrollView.contentOffset.x;
                   [scrollView setContentOffset:CGPointMake((currentPage)*self.pageLength+self.itemLength/2, 0) animated:YES];
               }
           }
       }//当向左滑动时
       else{
           if(overOffsetX >= self.pageLength/7*6){
               self.currentPage = currentPage+1;
               if(self.velocity.x == 0){
                   targetContentOffset->x = (currentPage+1)*self.pageLength+self.itemLength/2;
               }else{
                   targetContentOffset->x = scrollView.contentOffset.x;
                   [scrollView setContentOffset:CGPointMake((currentPage+1)*self.pageLength+self.itemLength/2, 0) animated:YES];
               }
           }else{
               self.currentPage = currentPage;
               targetContentOffset->x = (currentPage)*self.pageLength+self.itemLength/2;
           }
       }
    }
    }
    

    实现自定义pageable的距离的关键是改变参数targetContentOffset的值,由于传过来的是指针,可以对值直接进行修改,来达到滑动自定义距离的目的

    • 解决视图的缩放问题
      自定义UICollectionViewFlowLayout
      重写-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect方法。
    -(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect
    {
        NSArray *array = [super layoutAttributesForElementsInRect:rect];//可见frame
        CGRect visibleRect;
        visibleRect.origin = self.collectionView.contentOffset;
        visibleRect.size = self.collectionView.frame.size;
        NSMutableArray *allAttributes = [NSMutableArray arrayWithCapacity:array.count];
        for(UICollectionViewLayoutAttributes *attributes in array)
        {
            UICollectionViewLayoutAttributes *newAttributes = [attributes copy];
            [allAttributes addObject:newAttributes];
            if(CGRectIntersectsRect(newAttributes.frame, visibleRect))
            {
                CGFloat distance = CGRectGetMidX(visibleRect) - newAttributes.center.x;
                CGFloat scale = ABS(distance)/(self.collectionView.frame.size.width/2);
                CGFloat adverseScale = ABS(1-scale);
                CGFloat trueScale = (1-self.sizeScale)*adverseScale + self.sizeScale;
                newAttributes.transform3D = CATransform3DMakeScale(trueScale, trueScale, 1.0);
                newAttributes.zIndex = 1;
            }
        }
        return allAttributes;
    }
    

    最终实现效果

    flow.gif

    具体代码前往Github下载
    如有疑问请发邮件欢迎骚扰😀
    GitHub地址:@https://github.com/somson/flowView
    邮箱地址:1246071387@qq.com

    相关文章

      网友评论

      • Tr2e:有启发 谢谢

      本文标题:利用UICollectionView实现电影轮播图效果

      本文链接:https://www.haomeiwen.com/subject/ptgjettx.html