zoukankan      html  css  js  c++  java
  • ios之无限图片轮播器的实现

    • 首先实现思路:整个collectionView中只有2个cell.中间始终显示第二个cell.
    • 滚动:向前滚动当前cell的脚标为0,向后滚动当前的cell脚标为2.利用当前cell的脚标减去1,得到+1,或者-1,来让图片的索引加1或者减1,实现图片的切换.
    • 声明一个全局变量index来保存图片的索引,用来切换显示在当前cell的图片.
    • 在滚动前先让显示的cell的脚标变为1.代码viewDidLoad中设置
    • 完成一次滚动结束后,代码再设置当前的cell为第二个cell(本质上就是让当前显示的cell的脚标为1)
    • 最后一个有一个线程问题就是:当你连续滚动的时候,最后停止,当前显示的图片会闪动,因为是异步并发执行的,线程不安全导致.解决办法:让滚动完成后设置cell的代码加入主队列执行即可.

    • 准备工作,创建collectionViewController,storyboard,进行类绑定,cell绑定,cell可重用标识绑定.
    • 创建的cell.h文件
    //
    //  PBCollectionCell.h
    //  无限滚动
    //
    //  Created by 裴波波 on 16/3/30.
    //  Copyright © 2016年 裴波波. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface PBCollectionCell : UICollectionViewCell
    
    @property(nonatomic,strong)UIImage * img;
    @end
    
    
    
    
    • cell.m文件
    
    //
    //  PBCollectionCell.m
    //  无限滚动
    //
    //  Created by 裴波波 on 16/3/30.
    //  Copyright © 2016年 裴波波. All rights reserved.
    //
    
    #import "PBCollectionCell.h"
    
    @interface PBCollectionCell ()
    //不要忘记给collectionView的cell上设置图片框,并拖线到cell分类中
    @property (strong, nonatomic) IBOutlet UIImageView *imgView;
    
    @end
    
    @implementation PBCollectionCell
    //重写img的set方法来个cell进行赋值.(当调用cell.img = img的时候回调用set ..img的方法)
    -(void)setImg:(UIImage *)img{
    
        _img = img;
        self.imgView.image = img;
    }
    
    
    @end
    
    
    
    • 控制器的代码详解

    
    //
    //  ViewController.m
    //  无限滚动
    //
    //  Created by 裴波波 on 16/3/30.
    //  Copyright © 2016年 裴波波. All rights reserved.
    //
    
    #import "ViewController.h"
    #import "PBCollectionCell.h"
    //定义宏图片的个数
    #define kPictureCount 3
    @interface ViewController ()
    @property (strong, nonatomic) IBOutlet UICollectionViewFlowLayout *flowLayout;
    /**
     *  图片的索引
     */
    @property(nonatomic,assign) NSInteger index;
    
    @end
    
    
    • 声明全局变量index为了拼接滚动过程中切换的图片的索引
    
    @implementation ViewController
    
    -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    
        return kPictureCount;
    }
    
    -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    
        static NSString * ID = @"cell";
        PBCollectionCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
        //图片索引只有下一站或者上一张,即+1,或者-1,为了切换图片
        //中间的cell的脚标是1,滚动后脚标是2或者0,凑成next值为+1或者-1(让图片索引+1或者-1来完成切换图片),则
        NSInteger next = indexPath.item - 1;
        //为了不让next越界,进行取余运算 ---------+next为了切换图片
        next = (self.index + kPictureCount + next) % kPictureCount;
        
        NSString * imgName = [NSString stringWithFormat:@"%02ld",next + 1];
        UIImage * img = [UIImage imageNamed:imgName];
        cell.img = img;
        return cell;
    }
    
    
    • 在viewDidLoad设置了当前显示图片的cell是第二个cell,当cell向前滚动脚标-1(cell的indexPath.item的值为0),向后滚动脚标+1(cell的indexPath.item的值为2)
    • 如何拼接图片?---通过全局变量self.index:
      • cell向前滚动图片的索引self.index -1 此时cell的indexPath.item为0;然而此时图片的索引需要减1
      • cell向后滚动图片的索引self.index+1 此时cell的indexPath.item为2;图片的索引需要加1
      • 综上可以得出通过对cell的indexPath.item-1 再加上self.index就可以得出,要在下个图片中显示的图片的索引
    
    -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    
        //计算偏移的整数倍,偏移了0或者是2, -1是让self.index图片索引+1 或者 -1以切换图片;
        NSInteger offset = scrollView.contentOffset.x / scrollView.bounds.size.width - 1;
        self.index = (offset + self.index + kPictureCount) % kPictureCount;
        //本质就是改变cell的索引,再根据self.index来切换图片,使用取余让图片索引不至于越界
        //异步主队列执行,为了不让连续滚动停止后,图片有闪动.
        dispatch_async(dispatch_get_main_queue(), ^{
            [self scrollToSecondCell];
        });
    }
    
    
    • cell停止滚动后将图片的索引self.index值计算出来,保存在全局变量.为了在数据源第三个方法---返回cell的时候通过cell的indexPath.item的+1或者-1以及图片的索引self.index来正确切换要显示的图片.
    • 滚动停止后将操作放入主队列异步执行,此操作是为了将中间显示的cell的脚标变为1,也就是将当前显示的图片的cell变为第二个cell.放在主队列异步执行(不堵塞主线程,主队列的任务顺序执行,当主线程任务完成后再执行切换cell为第二个cell)不会出现连续滚动后闪动图片的bug.(此句看不懂可以略过).
    //封装设置当前显示的cell为第二个cell的方法.
    -(void)scrollToSecondCell{
    
        NSIndexPath * idxPath = [NSIndexPath indexPathForItem:1 inSection:0];
        [self.collectionView scrollToItemAtIndexPath:idxPath atScrollPosition:UICollectionViewScrollPositionLeft animated:NO];
    }
    
    - (void)viewDidLoad {
    
        [super viewDidLoad];
        self.flowLayout.itemSize = self.collectionView.bounds.size;
        self.flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        self.flowLayout.minimumLineSpacing = 0;
        self.collectionView.backgroundColor = [UIColor whiteColor];
        self.collectionView.pagingEnabled = YES;
        self.collectionView.bounces = NO;
        self.collectionView.showsHorizontalScrollIndicator = NO;
        [self scrollToSecondCell];
    }
    
    
    
    @end
    
    
    
    

    1. cell滑动前或者每次滑动结束后都用代码设置当前显示的cell为第二个cell,在数据源第三个方法也就是返回cell的方法中实现图片的切换用的是cell的indexPath.item-1 = -1或者 +1 再加上图片本身的索引值self.index就会得出即将滚出的cell要显示的是上一张图片还是下一张图片.

    2. cell滚动结束后要计算当前cell显示图片的索引.是通过scrollview的偏移量contentoffset.x除以scrollview的宽度,计算出当前cell的图片的索引保存.之后再滑动cell的时候,会调用数据源第三个方法,就会使用保存下来的self.index以及加上cell的indexPath.item-1来计算要显示的图片的索引.

  • 相关阅读:
    Dynamics AX 2012 R2 配置E-Mail模板
    Dynamics AX 2012 R2 设置E-Mail
    Dynamics AX 2012 R2 为运行失败的批处理任务设置预警
    Dynamics AX 2012 R2 耗尽用户
    Dynamics AX 2012 R2 创建一个专用的批处理服务器
    Dynamics AX 2012 R2 创建一个带有负载均衡的服务器集群
    Dynamics AX 2012 R2 安装额外的AOS
    Dynamics AX 2012 R2 将系统用户账号连接到工作人员记录
    Dynamics AX 2012 R2 从代码中调用SSRS Report
    Dynamics AX 2012 R2 IIS WebSite Unauthorized 401
  • 原文地址:https://www.cnblogs.com/adampei-bobo/p/5339537.html
Copyright © 2011-2022 走看看