美文网首页
iCarousel 使用(类似 iOS9多任务管理器)

iCarousel 使用(类似 iOS9多任务管理器)

作者: 黎明s | 来源:发表于2017-09-27 15:12 被阅读0次

    参照链接:http://www.cocoachina.com/ios/20150804/12878.html

    iCarousel的一个重要的设计理念 iCarousel虽然跟UIScrollView一样都各自会维护自己的scrollOffset 但是UIScrollView在滑动的时候改变的是自己的ViewPort 就是说 UIScrollView上的itemView是真正被放置到了他被设置的位置上 只是UIScrollView通过移动显示的窗口 造成了滑动的感觉(如果不理解,请参照https://objccn.io/issue-3-2/)

    但是iCarousel并不是这样 iCarousel会把所有的itemView都居中重叠放置在一起 当scrollOffset变化时 iCarousel会计算每个itemView的offset 并通过- (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform这个函数来对每个itemView进行形变 通过形变来造成滑动的效果.

    代码如下:
    1.首先导入第三方库"iCarousel"
    2.引入头文件"iCarousel.h"
    3.实现代理方法:"iCarouselDelegate","iCarouselDataSource"
    4.定义属性:
    @property (nonatomic, strong) iCarousel *carousel;
    @property (nonatomic, assign) CGSize cardSize;

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        CGFloat cardWidth = [UIScreen mainScreen].bounds.size.width * 5.0f / 7.0f;
        self.cardSize = CGSizeMake(cardWidth, cardWidth * 16.0f / 9.0f);
        self.view.backgroundColor = [UIColor blackColor];
        
        self.carousel = [[iCarousel alloc] initWithFrame:[UIScreen mainScreen].bounds];
        self.carousel.delegate = self;
        self.carousel.dataSource = self;
        self.carousel.type = iCarouselTypeCustom;
        self.carousel.bounceDistance = 0.2f;
        self.carousel.viewpointOffset = CGSizeMake(-cardWidth / 5.0f, 0);
        [self.view addSubview:self.carousel];
    }
    

    返回 item 数量

    - (NSInteger)numberOfItemsInCarousel:(iCarousel *)carousel
    {
        return 15;
    }
    

    返回 item 宽度

    - (CGFloat)carouselItemWidth:(iCarousel *)carousel
    {
        return self.cardSize.width;
    }
    

    返回添加在 item 上的视图

    - (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view
    {
        UIView *cardView = view;
        
        if ( !cardView )
        {
            cardView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.cardSize.width, self.cardSize.height)];
            
            UIImageView *imageView = [[UIImageView alloc] initWithFrame:cardView.bounds];
            [cardView addSubview:imageView];
            imageView.contentMode = UIViewContentModeScaleAspectFill;
            imageView.backgroundColor = [UIColor whiteColor];
            
            cardView.layer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:imageView.frame cornerRadius:5.0f].CGPath;
            cardView.layer.shadowRadius = 3.0f;
            cardView.layer.shadowColor = [UIColor blackColor].CGColor;
            cardView.layer.shadowOpacity = 0.5f;
            cardView.layer.shadowOffset = CGSizeMake(0, 0);
            
            CAShapeLayer *layer = [CAShapeLayer layer];
            layer.frame = imageView.bounds;
            layer.path = [UIBezierPath bezierPathWithRoundedRect:imageView.bounds cornerRadius:5.0f].CGPath;
            imageView.layer.mask = layer;
            
            //添加一个lbl
            UILabel *lbl = [[UILabel alloc] initWithFrame:cardView.bounds];
            lbl.text = [@(index) stringValue];
            lbl.font = [UIFont boldSystemFontOfSize:200];
            lbl.textAlignment = NSTextAlignmentCenter;
            [cardView addSubview:lbl];
        }
        return cardView;
    }
    

    核心代码:计算偏移量

    - (CATransform3D)carousel:(iCarousel *)carousel itemTransformForOffset:(CGFloat)offset baseTransform:(CATransform3D)transform
    {
        CGFloat scale = [self scaleByOffset:offset];
        CGFloat translation = [self translationByOffset:offset];
        
        return CATransform3DScale(CATransform3DTranslate(transform, translation * self.cardSize.width, 0, offset), scale, scale, 1.0f);
    }
    
    - (void)carouselDidScroll:(iCarousel *)carousel
    {
        for (UIView *view in carousel.visibleItemViews)
        {
            CGFloat offset = [carousel offsetForItemAtIndex:[carousel indexOfItemView:view]];
            
            if ( offset < -3.0 )
            {
                view.alpha = 0.0f;
            }
            else if ( offset < -2.0f)
            {
                view.alpha = offset + 3.0f;
            }
            else
            {
                view.alpha = 1.0f;
            }
        }
    }
    //形变是线性的就ok了
    - (CGFloat)scaleByOffset:(CGFloat)offset
    {
        return offset * 0.04f + 1.0f;
    }
    
    //位移通过得到的公式来计算
    - (CGFloat)translationByOffset:(CGFloat)offset
    {
        CGFloat z = 5.0f / 4.0f;
        CGFloat n = 5.0f / 8.0f;
        
        //z/n是临界值 >=这个值时 我们就把itemView放到比较远的地方不让他显示在屏幕上就可以了
        if ( offset >= z/n )
        {
            return 2.0f;
        }
        return 1 / (z - n * offset) - 1 / z;
    }
    

    item 点击事件

    - (void)carousel:(iCarousel *)carousel didSelectItemAtIndex:(NSInteger)index
    {
        //点击可删除itemView
    //    [carousel removeItemAtIndex:index animated:YES];
    }
    

    其它方法

    - (CGFloat)carousel:(iCarousel *)carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value
    {
        switch (option)
        {
            case iCarouselOptionVisibleItems:
            {
                return 7;
            }
                //循环滑动效果
                //        case iCarouselOptionWrap:
                //        {
                //            return YES;
                //        }
                
            default:
                break;
        }
     
        return value;
    }
    

    相关文章

      网友评论

          本文标题:iCarousel 使用(类似 iOS9多任务管理器)

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