• 图片无限滚动


    用 UICollectionView 和 NSTimer 实现图片的无限滚动播放效果.
    效果图如:
    无限滚动

    实现思路:
    (1) 首先在控制器中添加 UICollectionView 根据模型的个数显示模型数据(流水布局,自定义 UICollectionViewCell 显示模型数据)
    (2) 如果仅仅只有一组数据, 当滚动到最后一个位置的时候,这个时候,由于已经到了最后一个,所以定时器如果再次滚动就会出现越界情况.
    解决方法有两个,一个是定义一个可变数组,添加多次同样的模型,但是这样内存较大.

    //视图模型类为: Newes
    //自定义cell类为: ImageCell
    #define XCMaxSections 10
    - (NSMutableArray *)newses
    {
        if (_newses == nil) {
            self.newses = [NSMutableArray array];
            for (int i = 0; i<200; i++) {
                NSArray *array = [Newes objectArrayWithFilename:@"newses.plist"];
                [self.newses addObjectsFromArray:array];
            }
        }
        return _newses;
    }
    

    第二个是定义多组,定时器每次执行的时候,首先将UICollectionView滚动到中间的那组,然后,继续向后滚动,这样就永远不会出现越界的情况. 同时在控制器显示的时候,将UICollectionView滚动到中间的一组,这样显示图片的前后,都会有图片组.
    代码

    /**
     *  控制器显示的时候
     */
    - (void)viewDidAppear:(BOOL)animated{
        [super viewDidAppear:animated];
    
        //在控制器显示的时候, 跳转到中间的那组
        NSIndexPath *beginIndexPath = [NSIndexPath indexPathForItem:0 inSection:XCMaxSections/2];
        [self.collectionView scrollToItemAtIndexPath:beginIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
    }
    
    /**
     *  添加定时器
     */
    - (void)addTimer{
        //添加定时器
        self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
        [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
    }
    
    /**
     *  定时器方法:下一张图片
     */
    - (void)nextImage{
    
        //当前正在展示的位置
        NSIndexPath *currentIndexPath = [[self.collectionView indexPathsForVisibleItems] lastObject];
    
        NSIndexPath *resetIndexPath = [NSIndexPath indexPathForItem:currentIndexPath.item inSection:XCMaxSections/2];
        [self.collectionView scrollToItemAtIndexPath:resetIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
    
        //计算出下一个位置
        NSInteger nextItem = resetIndexPath.item + 1;
        NSInteger nextSection = resetIndexPath.section;
        if (nextItem == self.newesArr.count) {
            nextItem = 0;
            nextSection += 1;
        }
        //设置pageControl选中的页码
        self.pageControl.currentPage = nextItem;
    
        NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:nextItem inSection:nextSection];
    
        //滚动到下一个位置
        [self.collectionView scrollToItemAtIndexPath:nextIndexPath atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];  
    }

    (3) 当用户拖拽视图的时候, 应该将定时器移除, 当停止拖拽的时候, 再将定时器重新添加

    /**
     *  销毁定时器
     */
    - (void)clearTimer{
        if ([self.timer isValid]) {
            [self.timer invalidate];
            self.timer = nil;
        }
    }
    
    #pragma mark - UICollectionViewDelegate
    /**
     *  即将拖拽
     */
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
        [self clearTimer];
    }
    /**
     *  停止拖拽
     */
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
        [self addTimer];
    }
    
    /**
     *  停止滚动:重新计算 PageControl 显示的页码
     */
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
        int page = (int)(self.collectionView.contentOffset.x / self.collectionView.bounds.size.width) % self.newesArr.count;
        self.pageControl.currentPage = page;
    }

    添加UICollectionView 和 UIPageControl 的代码如下:

    /**
     *  懒加载数据模型
     */
    - (NSArray *)newesArr{
        if (_newesArr == nil) {
            _newesArr = [Newes objectArrayWithFilename:@"newses.plist"];
        }
        return _newesArr;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor whiteColor];
    
        //添加CollectionView
        [self addCollectionView];
    
        [self addTimer];
    }
    
    /**
     *  添加CollectionView 和 UIPageControl
     */
    - (void)addCollectionView{
    
        // 1 添加UICollectionView
        UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
        //设置各行的间距为0
        flowLayout.minimumLineSpacing = 0;
        //设置滚动方向(水平)
        flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    
        //设置每个item的尺寸
        CGFloat itemWidth = [UIScreen mainScreen].bounds.size.width - 2 * magin;
        flowLayout.itemSize = CGSizeMake(itemWidth, CollectionHeight);
    
        UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:flowLayout];
        collectionView.backgroundColor = [UIColor blueColor];
        //设置代理和数据源方法
        collectionView.dataSource = self;
        collectionView.delegate = self;
        //隐藏滑动条
        collectionView.showsHorizontalScrollIndicator = NO;
        //设置分页
        collectionView.pagingEnabled = YES;
    
        [self.view addSubview:collectionView];
        self.collectionView = collectionView;
    
        //注册cell
        [collectionView registerClass:[ImageCell class] forCellWithReuseIdentifier:ID];
    
        //自动布局
        collectionView.sd_layout.leftSpaceToView(self.view, magin).rightSpaceToView(self.view, magin).topSpaceToView(self.view, 40).heightIs(CollectionHeight);
    
        // 2 添加分页控制器PageControl
        UIPageControl *pageControl = [[UIPageControl alloc] init];
        //设置页数
        pageControl.numberOfPages = self.newesArr.count;
        //设置选中页数的颜色
        pageControl.currentPageIndicatorTintColor = [UIColor redColor];
        //设置其他未选中页数的颜色
        pageControl.pageIndicatorTintColor = [UIColor whiteColor];
    
        [self.view addSubview:pageControl];
        self.pageControl = pageControl;
    
        //设置尺寸
        pageControl.sd_layout.rightSpaceToView(self.view, 70).bottomEqualToView(collectionView).widthIs(50).heightIs(37); 
    }
    
    #pragma mark - UICollectionViewDataSource
    /**
     *  多少组
     */
    - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
        return XCMaxSections;
    }
    
    /**
     *  每组多少个数据
     */
    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
        return self.newesArr.count;
    }
    
    
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    
        ImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
        cell.newes = self.newesArr[indexPath.item];
    
        return cell;
    }

    更详细的代码:(如 Newes 和 ImageCell的代码见 github )
    github

    不积跬步,无以至千里;不积小流,无以成江海。
  • 相关阅读:
    Java日志体系(1) —— 那些年那些事,那些日志的历史
    直播工作原理
    【PAT乙级 】1003. 我要通过!
    [牛客网刷题]被3整除
    [牛客网刷题]牛牛找工作
    Mybatis的简单分析
    数位DP
    正则表达式
    能量球
    从此,我们相伴,不离不弃
  • 原文地址:https://www.cnblogs.com/xiaocai-ios/p/7779793.html
Copyright © 2020-2023  润新知