iOS開發那些事兒(一)輪播器,ios事兒

來源:互聯網
上載者:User

iOS開發那些事兒(一)輪播器,ios事兒
前言

          市面上絕大部分的APP被開啟之後映入眼帘的都是一個美輪美奐的輪播器,所以能做出一個符合需求、高效的輪播器成為了一個程式員的必備技能。所以今天的這篇部落格就來談談輪播器這個看似簡單的控制項其中蘊含的道理。

本文

    首先我們來分析一下該如何去實現一個類似的輪播器(圖片數量、URL由伺服器返回):

    

          

     策略一:UIScrollView->UIImageView->NSTimer輪詢 這算是常規的策略,但是如果仔細想想,如果伺服器返回給你50圖片是不是就需要建立50個UIImageView來做容器。這種效能肯定不是最優的。其次所有的UIImageView是按照次序排列,腦補一下如果到最後一張圖片要重新回到第一張圖片你的話,UIScrollView會被升拉到第一個位置。效果太差!

     策略二:想想UITableViewCell的重複利用,我們也可以重複利用其中的UIImageView。對於我們來說輪播器三個UIImageView就足夠用了,分為當前視野中的CenterImageView、前一張LeftImageView、後一張RightImageView。不同的是他們之間的圖片切換,下面我們就嘗試去做高效的輪播器。

代碼實現

 

  

  2.寫一個專門控制沒次滑動結束去計算左中右三張序號並載入成對應的圖片。

/** 這裡我起名叫reloadAllImageView */

-(void)reloadAllImageView{

    CGPoint offset = _backScrollView.contentOffset;                       /** 擷取到scroll的X軸位移量 */

 

       if (offset.x == 2 * DeviceWidth){                      /** 這裡有兩種邊界情況要處理 (1).由first—>last (2)last->first */

        /** (2) */

            _centerImageIndex        = (_centerImageIndex + 1)%3;          /** 3代表圖片的數量,這裡要首頁類型的強轉換。_centerImageIndex(NSUInteger)用於記錄當前圖片序號*/

            _pageControl.currentPage = (_pageControl.currentPage + 1)%3;

        }

        else if (offset.x == 0){

            /** (1) */

          if (_centerImageIndex == 0) {                        /** 一種特殊情況 當_centerImageIndex等於0的時候 去計算(_centerImageIndex - 1) % 3並不是我們想要的結果 */

              _centerImageIndex = 3;                          /** 嘗試了很久,計算類型轉換也就只有三張圖片會有問題。如果有興趣的朋友可以進行深入研究 */

          }                                      /** -1 % 3 = 0   如果都是有符號的結果是-1,如果按照無符號處理的話結果是0。難道計算過程應該先向前借位再進行計算? */

          _centerImageIndex        = (_centerImageIndex - 1) % 3;    

          _pageControl.currentPage = (_pageControl.currentPage - 1)%3;

        }

      _centerImageView.image         = [UIImage imageNamed:[NSString stringWithFormat:@"圖%d.jpg",_centerImageIndex + 1]];

      NSUInteger leftImageViewIndex  = (_centerImageIndex - 1)%3;

      NSUInteger  rightImageViewIndex = (_centerImageIndex + 1)%3;

      if (leftImageViewIndex == 0 && _centerImageIndex == 0) {          /** 同上暫時處理計算特殊情況 */ 

          leftImageViewIndex = 2;

      }

      _leftImageView.image           = [UIImage imageNamed:[NSString stringWithFormat:@"圖%d.jpg",leftImageViewIndex + 1]];

      _rightImageView.image          = [UIImage imageNamed:[NSString stringWithFormat:@"圖%d.jpg",rightImageViewIndex + 1]];

}
    3.現在輪播器應該可以在邊界正常切換了。現在需要再加上一個計時器來自動滑動即可:

/** 聲明一個定時器 */   /** 用weak的原因:self如果強擁有了Timer,之後你要設定計時器的Traget和選擇子selector的時候,Timer又會保留目標對象直到失效。產生保留環 */

@property(nonatomic,weak)NSTimer * timer;

/** 定時器初始化 */

   -(void)initTimer

   {

       self.timer = [NSTimer scheduledTimerWithTimeInterval:animationTime target:self selector:@selector(updateImageView:) userInfo:nil repeats:YES];

   }

  -(void)updateImageView:(NSTimer *)timer

  {

      [_backScrollView setContentOffset:CGPointMake(DeviceWidth*2, 0) animated:YES];

      [NSTimer scheduledTimerWithTimeInterval:0.4f target:self selector:@selector(scrollViewDidEndDecelerating:) userInfo:nil repeats:NO];

  }

/** 計算載入所有圖片然後移動的中間視野 */

  -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

      //重新載入圖片

      [self reloadAllImageView];

      //移動到當前視野

      [_backScrollView setContentOffset:CGPointMake(DeviceWidth, 0)];

      //設定腳標

      _pageControl.currentPage = _centerImageIndex;

  }

  4.自此輪播器大概雛形已經搞定了。剩下的就是需要搞定計時器和使用者滑動操作的互斥事件處理。

/**記錄一個bool值用於確定滑動操作的願意你。YES,計時器觸發,NO則為使用者觸發*/

     (1).計時器的觸發事件中,肯定是由計時器觸發的滑動。所以這裡bool值為YES

  (2).載入替換圖片的時候我們要進行判斷(如果是使用者觸發的時候我們要將計時器取消並從空為0)

 

    if (!bool) {

 

          [self.timer setFireDate:[NSDate dateWithTimeIntervalSinceNow:animationTime]];

 

      }

 

       bool = NO;

結尾

    由此輪播器就實現了,但是其中還是有問題需要解決<1>.限制必須要三張圖片不然會crash <2>沒有封裝成單獨的scrllview以供使用。後續可能會對這些問題加以思考並重新最佳化。也許嘗試用UICollection來做也是個很好的想法。

            最後經過寫這篇部落格也有一個目的,其實任何一個看似簡單的功能要深入挖掘的話還是有很說知識的,也發現了自身的不足。最後如果各位大神們看到了部落格有任何想法意見的歡迎下面留言。大家一起探討一起進步。謝謝各位!

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.