Swift - UIScrollView 循環(huán)滾動

圖片循環(huán)滾動在 app 上很是常見,網(wǎng)上翻了一些資料,這篇博文 思路蠻不錯的,Objective-C寫的 參照這個思路自己練習擼了一版 Swift,改進了一下..

效果圖:


loopscrollview.png

實現(xiàn)功能

  1. 循環(huán)滾動
  2. 定時自動跳轉

當我們設定播放的圖片寬度與父視圖等寬的話,那么我們只需要準備3個UIView即可滿足左右滑動,并且保持當前處于第2個UIView上,可以通過設定contentOffSet處在UIScrollView位置

loopScrollView.contentOffset = CGPoint(x: self.frame.size.width,y: 0)

頁面跳轉

  1. 手動翻頁
  2. 自動翻頁
手動翻頁

當我們手動去翻頁的時候這里有兩種情況:

    //MARK: - UIScrollView delegate
    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
        let ratio = scrollView.contentOffset.x/self.frame.size.width
        self.endScrollMethod(ratio)
    }
    func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if !decelerate{
            let ratio = scrollView.contentOffset.x/self.frame.size.width
            self.endScrollMethod(ratio)
        }
    }
  • 左右滑動swipe 手勢,帶有減速效果, scrollViewDidEndDecelerating方法響應
  • 左右拖動drag手勢,并沒有帶減速效果,可以根據(jù)scrollViewDidEndDragging 方法的decelerate來判斷是否有減速效果

當手勢動作執(zhí)行完畢后,就需要做一些處理,根據(jù)算出來的ratio來判斷向左還是向右,當ratio < 1.0標示向左,反之則向右翻頁

private func endScrollMethod(ratio:CGFloat){
        if ratio <= 0.7{
            if currentPage - 1 < 0{
                currentPage = arrImage.count - 1
            }else{
                currentPage -= 1
            }
        }
        if ratio >= 1.3{
            if currentPage == arrImage.count - 1{
                currentPage = 0
            }else{
                currentPage += 1
            }
        }
        self.updateImageData()
        self.startTimer()
    }

根據(jù) currentPage來判斷當前處于第幾頁 而后再更新圖片內容

private func updateImageData(){
        if currentPage == 0{
            imageView0.image = arrImage.last
            imageView1.image = arrImage[currentPage]
            imageView2.image = arrImage[currentPage + 1]
        }else if currentPage == arrImage.count - 1{
            imageView0.image = arrImage[currentPage - 1]
            imageView1.image = arrImage[currentPage]
            imageView2.image = arrImage.first
        }else{
            imageView0.image = arrImage[currentPage - 1]
            imageView1.image = arrImage[currentPage]
            imageView2.image = arrImage[currentPage + 1]
        }
        pageControl.currentPage = currentPage
        loopScrollView.contentOffset = CGPoint(x: self.frame.size.width,y: 0)
    }

更新完圖片內容后,通過contentOffset將復位當前的位置為第二個 UIView上,至此就完成了翻頁動作

自動翻頁

啟用一個定時器,定時完成以上動作,用一個變量來控制定時器開關

  var autoShow:Bool = false{
        didSet{
            if autoShow{
                self.startTimer()
            }else{
                self.stopTimer()
            }
        }
    }

定時器響應的方法,跳轉到下一頁 currentPage+1 再更新一下即完成翻頁動作

    @objc private func autoTurnNextView(){
        
        if currentPage == arrImage.count - 1{
            currentPage = 0
        }else{
            currentPage += 1
        }
        self.updateImageData()
    } 

初始方法,當設置 arrImage的時候更新視圖內容

    var arrImage:[UIImage] = []{
        willSet{
            currentPage = 0
            pageControl.numberOfPages = newValue.count
        }
        didSet{
            self.updateImageData()
        }
    }

使用方法

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    
        let image1 = UIImage(named: "Barcelona0")!
        let image2 = UIImage(named: "Barcelona1")!
        let image3 = UIImage(named: "Barcelona2")!
        let image4 = UIImage(named: "Barcelona3")!
        let images = [image1,image2,image3,image4]
        
        
        let rect = CGRectMake(0, 22, CGRectGetWidth(self.view.frame), CGRectGetWidth(self.view.frame)/16 * 9)
        
        let loopView = CLLoopView(frame:rect)
        self.view.addSubview(loopView)
        loopView.arrImage = images
        loopView.autoShow = true
        loopView.delegate = self
    }

代理方法,當點擊scrollview響應的方法,idx為當前頁數(shù)

    //MARK: - CLLoopView Delegate
    func selectLoopViewPage(idx: Int) {
        print("select page:\(idx)")
    }

GitHub : Demo

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末看锉,一起剝皮案震驚了整個濱河市夺饲,隨后出現(xiàn)的幾起案子轴合,更是在濱河造成了極大的恐慌毅否,老刑警劉巖忿磅,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒲祈,死亡現(xiàn)場離奇詭異丁存,居然都是意外死亡彩匕,警方通過查閱死者的電腦和手機漠烧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門杏愤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人已脓,你說我怎么就攤上這事珊楼。” “怎么了度液?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵厕宗,是天一觀的道長。 經(jīng)常有香客問我恨诱,道長媳瞪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任照宝,我火速辦了婚禮蛇受,結果婚禮上,老公的妹妹穿的比我還像新娘厕鹃。我一直安慰自己兢仰,他們只是感情好乍丈,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著把将,像睡著了一般轻专。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上察蹲,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天请垛,我揣著相機與錄音,去河邊找鬼洽议。 笑死宗收,一個胖子當著我的面吹牛,可吹牛的內容都是我干的亚兄。 我是一名探鬼主播混稽,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼审胚!你這毒婦竟也來了匈勋?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤膳叨,失蹤者是張志新(化名)和其女友劉穎洽洁,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體懒鉴,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡诡挂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了临谱。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片璃俗。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖悉默,靈堂內的尸體忽然破棺而出城豁,到底是詐尸還是另有隱情,我是刑警寧澤抄课,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布唱星,位于F島的核電站,受9級特大地震影響跟磨,放射性物質發(fā)生泄漏间聊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一抵拘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦尚蝌、人聲如沸迎变。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽衣形。三九已至,卻和暖如春姿鸿,著一層夾襖步出監(jiān)牢的瞬間谆吴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工般妙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留纪铺,地道東北人相速。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓碟渺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親突诬。 傳聞我的和親對象是個殘疾皇子苫拍,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內容