圖片循環(huán)滾動在 app 上很是常見,網(wǎng)上翻了一些資料,這篇博文 思路蠻不錯的,Objective-C寫的 參照這個思路自己練習擼了一版
Swift
,改進了一下..
效果圖:
實現(xiàn)功能
- 循環(huán)滾動
- 定時自動跳轉
當我們設定播放的圖片寬度與父視圖等寬的話,那么我們只需要準備3個UIView
即可滿足左右滑動,并且保持當前處于第2個UIView
上,可以通過設定contentOffSet
處在UIScrollView
位置
loopScrollView.contentOffset = CGPoint(x: self.frame.size.width,y: 0)
頁面跳轉
- 手動翻頁
- 自動翻頁
手動翻頁
當我們手動去翻頁的時候這里有兩種情況:
//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)")
}