图片循环滚动在 app 上很是常见,网上翻了一些资料,这篇博文 思路蛮不错的,Objective-C写的 参照这个思路自己练习撸了一版
Swift
,改进了一下..
效果图:
实现功能
- 循环滚动
- 定时自动跳转
当我们设定播放的图片宽度与父视图等宽的话,那么我们只需要准备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
手势,并没有带减速效果,可以根据scrollViewDidEndDragging
方法的decelerate
来判断是否有减速效果
当手势动作执行完毕后,就需要做一些处理,根据算出来的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()
}
根据 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为当前页数
//MARK: - CLLoopView Delegate
func selectLoopViewPage(idx: Int) {
print("select page:\(idx)")
}