美文网首页iOS
iOS轮播图(OC版本)

iOS轮播图(OC版本)

作者: mac迷你 | 来源:发表于2018-04-26 14:26 被阅读83次

    轮播图在开发中经常用到。并且面试的时候也经常回问道。
    其实最长问道的也就两点
    1、内存优化
    2、计时器问题
    3、轮播实现方案

                                 此轮播图以UIScrollView实现
    

    先以第一点内存优化和实现方案来讲,如何去做内存优化?
    图片在iOS设备中很占内存,所以每当遇到加载图片的时候需要格外注意,不要去加载一些不必要的图片。
    首先应当想到要减少UIImageView在UIScrollView上加载。结合UITableView的特点:复用。所以至少应当创建三个UIImageView。


    要以这种方式排列

    实际上我们所展示的第1张图片在对应的ScrollView上应该是第2页。
    并且重要的一点就是:所展示的图片一直是中间的。当滑到两边的图片后,要立刻重置到第二张。

    两种代理实现方案

    减速实现

        - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 
    

    滑动过程中

          - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    

    当使用结束拖拽的代理正常使用情况下其实是不会出现的问题的,但是当用户快速拖拽时,scrollview的偏移会出现问题。最好的方法便是实时计算偏移量

    核心代码

            - (void)scrollViewDidScroll:(UIScrollView *)scrollView
      {
          [self reloadIndex];
      }
    
    
    
      //滑到中心,切记不能调用该动画,否则会触发代理
    - (void)scrollCenter
    {
          [self.mainScrollView setContentOffset:CGPointMake(CGRectGetWidth(self.mainScrollView.bounds), 0)];
          if (self.indexBack) {
              self.indexBack(self.index);
          }
      }
    
    
    
      //计算页数
        - (void)reloadIndex
      {
          if (self.imageArray && self.imageArray.count > 0)
          {
              CGFloat pointX = self.mainScrollView.contentOffset.x;
    
              //此处的value用于边缘判断,当imageview距离两边间距小于1时,触发偏移
              CGFloat Value = 0.2f;
    
              if (pointX > 2 * CGRectGetWidth(self.mainScrollView.bounds) - Value) {
                  self.index = (self.index + 1) % self.imageArray.count;
            
        } else if (pointX < Value) {
            self.index = (self.index + self.imageArray.count - 1) % self.imageArray.count;
        }
    
    }
    
      }
    
      //重写index的set方法
      - (void)setIndex:(NSInteger)index
      {
          _index = index;
          NSInteger totalCount = self.imageArray.count;
          NSInteger   leftIndex = (self.index+totalCount-1)%totalCount;
          NSInteger   rightIndex = (self.index+1)%totalCount;
    
          [self.leftImageView setImage:[UIImage imageNamed:self.imageArray[leftIndex]]];
          [self.midImageView setImage:[UIImage imageNamed:self.imageArray[self.index]]];
          [self.rightImageView setImage:[UIImage imageNamed:self.imageArray[rightIndex]]];
    
          [self scrollCenter];
      }
    

    关于计算页数说明:
    假如有4张图片排序为,4|0|1|2|3,其实严格说此排序像一个环形数列,所以leftIndex和rightIndex的公式相当于去计算指定页数的前一个和后一个数字

      .h 文件
          @interface MCScrollView : UIView
    
    
      @property (nonatomic, copy) void(^indexBack)(NSInteger pageIndex);      //页数回调
    
      @property (nonatomic, copy) NSArray *imageArray;    //存储图片数据
    
      @property (nonatomic, assign) NSInteger index;      //当前第几页,默认为0(0为第一页,如果制定页数需要加1)
    
      @end
    

    定时器添加

      .h文件添加
      @property (nonatomic, assign) NSTimeInterval    duration;       //时长
    

    实现

       - (void)setDuration:(NSTimeInterval)duration
        {
            _duration = duration;
          if (duration > 0.0) {
        
              self.timer = [NSTimer scheduledTimerWithTimeInterval:duration target:self selector:@selector(changeNext) userInfo:nil repeats:YES];
              [self.timer setFireDate:[NSDate dateWithTimeIntervalSinceNow:duration]];
          }
      }
    
    
      - (void)changeNext
      {
          [self.mainScrollView setContentOffset:CGPointMake(2*CGRectGetWidth(self.mainScrollView.bounds), 0) animated:YES];
      }
    
    
    
      - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
      {
          [self.timer setFireDate:[NSDate distantFuture]];
      //[NSDate distantFuture]表示暂停计时
      }
    
    
    
      - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
      {
          [self.timer setFireDate:[NSDate dateWithTimeIntervalSinceNow:self.duration]];
      //
      }
    

    [NSDate dateWithTimeIntervalSinceNow:self.duration]表示在当前时间的几秒后开始计时,优点是不会立即执行计时器
    Demo地址:https://github.com/HeartbeatT/MCScrollView.git

    相关文章

      网友评论

        本文标题:iOS轮播图(OC版本)

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