OC开发

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

2016-09-07  本文已影响320人  静谧无际

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

目的效果

效果图.png

效果分析

实现过程

-(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的值,由于传过来的是指针,可以对值直接进行修改,来达到滑动自定义距离的目的

-(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

上一篇 下一篇

猜你喜欢

热点阅读