iOS簡易輪播圖的實現(xiàn)

前言

見過很多的iOS應用,都有無限輪播圖宴霸,之前也看到過很多相關實現(xiàn)的文章,可是僅僅就是一看而過罷了膏蚓。當自己在項目中用到這個瓢谢,真正去寫的時候才發(fā)現(xiàn)不是很容易,遇到了一些問題驮瞧,這篇文章就記錄下自己最后成功實現(xiàn)輪播圖的歷程氓扛。

原理

原理其實就是一種假象。不過在我這里,目前有過兩種原理的實現(xiàn)采郎。一種利用UICollectionView實現(xiàn)輪播千所,另一種利用UIScrollView實現(xiàn)輪播。
今天我們要來打造一款這樣的輪播圖(圖畫的不好蒜埋,請勿見怪)淫痰。

舉例:三張圖的無限輪播

原理一:利用UIScrollView實現(xiàn)輪播圖。

要想實現(xiàn)這樣的效果整份,我們使用UIScrollView包含image0待错,image1,image2的三個UIImageView都是放在UIScrollView里面的烈评,但是這樣的話是不可以實現(xiàn)輪播的火俄。要想實現(xiàn)輪播就要再在該UIScrollView的左右兩側各加一張UIImageView。在最后一張放image0讲冠, 第一張放image2瓜客。這樣的話當我們滾動到最后或者最前面的的時候,我們就把列表切換到相應的位置沟启。

實際UISrollView圖

原理二:利用UICollectionView實現(xiàn)輪播圖忆家。

你當然可以利用原理一再用UICollectionView實現(xiàn)一次。但是我這里采用一種偷懶的方式德迹,利用UICollectionView的cell重用機制芽卿。創(chuàng)建個無數(shù)個cell,比如3x20000胳搞。當用戶第一次進來的我們就將UICollectionView滑到3x20000x0.5的位置卸例。然后利用cell.indexPath.item % 3來對cell上的UIImageView進行image顯示。這種方式比較偷懶肌毅,在后來添加NSTimer自動輪播和點擊事件的時候也比較簡單筷转,不過有點大炮打小鳥的感覺。所以我在這里也只是介紹下原理悬而,如果你有興趣呜舒,可以自己嘗試去實現(xiàn)下。而且UICollectionView自帶一個方法- scrollToItemAtIndexPath:atScrollPosition:animated:還比較厲害笨奠。

具體實現(xiàn)

針對原理一袭蝗,我就來簡單實現(xiàn)下。(我這里使用代碼創(chuàng)建,你也可以使用Storyboard創(chuàng)建,原理一樣)

創(chuàng)建工程般婆,創(chuàng)建BannerView.Swift,添加初始化代碼如下:

/// 初始化scrollView
lazy var scrollView: UIScrollView = {
       let scrollView = UIScrollView()
       scrollView.delegate = self
       scrollView.alwaysBounceVertical = false
       scrollView.bounces = true
       scrollView.pagingEnabled = true
       scrollView.scrollEnabled = true
       scrollView.showsVerticalScrollIndicator = false
       scrollView.showsHorizontalScrollIndicator = false
       return scrollView
   }()
/// 初始化pageControl
   lazy var pageControl: UIPageControl = {
       let pageControl = UIPageControl()
       pageControl.currentPageIndicatorTintColor = UIColor.redColor()
       pageControl.pageIndicatorTintColor = UIColor.whiteColor()
       return pageControl
   }()

   /// 在init里調用setupSubviews即可
   func setupSubviews() {  
       self.addSubview(scrollView)
       self.addSubview(pageControl)

       scrollView.translatesAutoresizingMaskIntoConstraints = false
       pageControl.translatesAutoresizingMaskIntoConstraints = false

       self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[v]|", options: [], metrics: nil, views: ["v": scrollView]))
       self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[v]|", options: [], metrics: nil, views: ["v": scrollView]))

       self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[p(==20)]-10-|", options: [], metrics: nil, views: ["p": pageControl]))
       self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[p(==100)]-10-|", options: [], metrics: nil, views: ["p": pageControl]))
   }

初始化UIScrollView:

func setupScrollView() {
        /// 創(chuàng)建 (imageNames.count + 2)個UIImageView
        for index in 0 ... (imageNmaes.count + 1) {
            let imageView = UIImageView(frame: CGRect(x: self.width*CGFloat(index), y: 0, width: self.width, height: self.height))
            var picName = String()
            switch index {
            case 0:
                picName = imageNames[imageNames.count-1]
                break
            case imageNames.count + 1:
                picName = imageNames[0]
                break
            default:
                picName = imageNames[index-1]
                break
            }

//          imageView.af_setImageWithURL(NSURL(string: picName)!)
            imageView.image = UIImage(named: picName)
            imageView.contentMode = .ScaleToFill
            imageView.clipsToBounds = true
            imageView.userInteractionEnabled = true
            scrollView.addSubview(imageView)
        }
        scrollView.contentSize = CGSize(width: self.width * CGFloat(imageNames.count + 2), height: self.height)
        scrollView.contentOffset = CGPoint(x: self.width, y: 0)
    }

無限輪番的實現(xiàn)到腥。(重點)使用UIScrollViewDelegate協(xié)議。

func scrollViewDidScroll(scrollView: UIScrollView) {
       if scrollView == self.scrollView {
           let contentOffsetX = scrollView.contentOffset.x
          ///向前滑動到第0張圖的時候蔚袍,滾到第三張圖
           if contentOffsetX == 0 {
               scrollView.contentOffset = CGPoint(x: self.width * CGFloat(self.imageNames.count), y: 0)
           }
           /// 跑到第三張圖的時候乡范,滾到第0張圖
           if contentOffsetX == CGFloat(self.imageNames.count + 1)*self.width {
               scrollView.contentOffset = CGPoint(x: self.width, y: 0)
           }
           /// 改變pageControl,這里要注意,一定要一定要一定要 - 0.5晋辆, 因為最前面的第0張圖一直不顯示渠脉。
           let index = scrollView.contentOffset.x / self.width - 0.5
           self.pageControl.currentPage = Int(index)
       }
   }

添加計時器

好了,做到這里栈拖,你已經(jīng)成功實現(xiàn)了輪播圖连舍,可是這個輪播圖是手動的,下面添加自動滾動涩哟。也很簡單,設置一個NSTimer計時器即可盼玄。代碼如下:

// MARK: - Timer
   var timer: NSTimer?
   var i = 1
   /// 在scrollView上的圖片成功設置后調用startTimer即可
   private func startTimer() {
       if timer != nil {
           self.stopTimer()
       }
       /// 這里設置的滾動間隔為2秒
       timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: #selector(autoScroll), userInfo: nil, repeats: true)
       NSRunLoop.currentRunLoop().addTimer(timer!, forMode: NSDefaultRunLoopMode)
   }
   private func stopTimer() {
       timer?.invalidate()
       timer = nil
   }
   func autoScroll() {
       if i == imageNames.count + 1 {
           i = 1
       }
       i += 1
       /// 在處理無限輪番的時候設置contentOffset沒有添加animated贴彼,這里要添加上來,不然有種很突兀的感覺埃儿。
       scrollView.setContentOffset(CGPoint(x: self.width * CGFloat(i), y: 0), animated: true)
   }
    /// 手動滾動結束后恢復計時
   func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        self.startTimer()
    }
    /// 當手動滾動開始時停止計時
    func scrollViewWillBeginDragging(scrollView: UIScrollView) {
        self.stopTimer()
    }

添加具體點擊事件

具體到點擊事件的話器仗,我是放在初始化imageView那里處理的,給imageVIew添加一個UITapGestureRecognizer童番,在這里最好再寫一個代理方法精钮,將imageView的點擊事件傳遞出去。然后根據(jù)當前contentOffet.x / self.width來將具體哪張圖片的事件傳遞出去剃斧。我就不用代碼展示了轨香。

結尾

還是比較簡單的。但是我這個復用性比較差幼东,封裝的也不好臂容,可是具體要看思路??。代碼實現(xiàn)放在了Github Wiki上了BannerView.Swift根蟹,由于工程量太小脓杉,就沒將工程文件上傳了。

關于作者

Qiuncheng简逮,一位正在iOS路上前行的初學者球散,正在努力成為一名合格的iOS開發(fā)者。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末散庶,一起剝皮案震驚了整個濱河市蕉堰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌督赤,老刑警劉巖嘁灯,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異躲舌,居然都是意外死亡丑婿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來羹奉,“玉大人秒旋,你說我怎么就攤上這事【魇茫” “怎么了迁筛?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長耕挨。 經(jīng)常有香客問我细卧,道長,這世上最難降的妖魔是什么筒占? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任贪庙,我火速辦了婚禮,結果婚禮上翰苫,老公的妹妹穿的比我還像新娘止邮。我一直安慰自己,他們只是感情好奏窑,可當我...
    茶點故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布导披。 她就那樣靜靜地躺著,像睡著了一般埃唯。 火紅的嫁衣襯著肌膚如雪撩匕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天筑凫,我揣著相機與錄音滑沧,去河邊找鬼。 笑死巍实,一個胖子當著我的面吹牛滓技,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播棚潦,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼令漂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了丸边?” 一聲冷哼從身側響起叠必,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎妹窖,沒想到半個月后纬朝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡骄呼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年共苛,在試婚紗的時候發(fā)現(xiàn)自己被綠了判没。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡隅茎,死狀恐怖澄峰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情辟犀,我是刑警寧澤俏竞,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站堂竟,受9級特大地震影響魂毁,放射性物質發(fā)生泄漏。R本人自食惡果不足惜出嘹,卻給世界環(huán)境...
    茶點故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一漱牵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧疚漆,春花似錦、人聲如沸刁赦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽甚脉。三九已至丸升,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間牺氨,已是汗流浹背狡耻。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留猴凹,地道東北人夷狰。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像郊霎,于是被迫代替她去往敵國和親沼头。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫书劝、插件进倍、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,029評論 4 62
  • 只有電影里才會等你四五年,感情购对,就是不聯(lián)系就會沒有的東西
    周曌閱讀 80評論 0 0
  • 曾經(jīng)不知道多少次楷扬,我們違背自己的初心,去做那件令自己窒息的事么抗;曾經(jīng)不知道多少回毅否,我們?yōu)榱擞洗蟊姷目谖叮ゲ粩?..
    梅骨賞閱讀 202評論 0 1