这两年swift火得有点不像话,作为一个iOS开发者,Apple大大推出的编程语言是必须要学的,于是乎好多iOS攻城狮不是在用swift写项目就是在用swift改项目的路上。我着手的项目之前一直都是用纯OC编写的,因为项目较大,而且版本更新频率比较高,一直都没有转swift。趁着最近项目要发版本,手中的事不是很多,就开始试着写一个swift版本(论装逼的最高境界)。
Swift发布以后,一直都是看文档,没怎么用swift写过项目,趁着这次机会尝试用swift写手中的项目。由于首页中就有无限轮播,自然着手点也从这开始。使用两个UIImageView+UIScrollView实现,二话不说,先看效果图:
无限循环轮播.gif
先说一下原理,这里假设图片的宽度为imgWidth,高度为imgHeight,scrollView的宽=图片的宽,scrollView的高=图片的高, 设置 scrollView 的 contentSize = 3倍图片宽度,高度相同,将第一个imageView放在scrollView的中间,第二个 imageView 放在最后,因为暂时不显示,所以放在最前面和最后面是一样的,再设置 scrollView 的偏移量为图片宽度(刚好显示中间的 imageView)。具体代码如下:
//图片宽度
imgWidth = frame.size.width
//图片高度
imgHeight = frame.size.height
scrollView = UIScrollView.init(frame: frame)
scrollView?.delegate = self
//设置分页
scrollView?.pagingEnabled = true
scrollView?.showsHorizontalScrollIndicator = false
//设置 contentSize 为图片3倍宽度,高度相同
scrollView?.contentSize = CGSizeMake(3*imgWidth!, imgHeight!)
scrollView?.contentOffset = CGPointMake(imgWidth!, 0)
self.addSubview(scrollView!)
//将当前显示视图放在 scrollView 中间
currentView = UIImageView.init(frame: CGRectMake(imgWidth!, 0, imgWidth!, imgHeight!))
scrollView?.addSubview(currentView!)
//下一视图放在中间视图后面
nextView = UIImageView.init(frame: CGRectMake(2*imgWidth!, 0, imgWidth!, imgHeight!))
scrollView?.addSubview(nextView!)
上面设置完初始数据后,接下来就要定义一个变量 direction 来记录 scrollView 的滚动方向,这里我们先定义一个滚动方向枚举类型:
enum Direction
{
case DirectionLeft //向左滚动
case DirectionRight //向右滚动
case DirectionNone //无滚动
}
direction是记录 scrollView 的滚动方向的变量,它的值是根据滑动方向来改变的,所以要在 scrollView 中的代理方法监听 scrollView的滚动方向并赋值给direction。
//MARK: -----UIScrollViewDelegate-----
func scrollViewDidScroll(scrollView: UIScrollView)
{
let offsetX = scrollView.contentOffset.x;
self.direction = offsetX > imgWidth! ? .DirectionLeft : offsetX < imgWidth! ? .DirectionRight : .DirectionNone
}
以前在 OC中我们可以用 KVO 来实现,但是 Swift 中没有 KVO,所以要想到重写 setter 方法来实现。
var direction :Direction = .DirectionNone //滚动方向
{
//设置新值之前
willSet
{
if newValue == direction
{
return
}
}
//设置新值之后
didSet
{
//向右滚动
if direction == .DirectionRight
{
nextView?.frame = CGRectMake(0, 0, imgWidth!, imgHeight!)
nextIndex = currentIndex!-1
if nextIndex < 0
{
nextIndex = (ADsArray?.count)! - 1
}
}
//向左滚动
if direction == .DirectionLeft
{
nextView?.frame = CGRectMake(imgWidth!*2, 0, imgWidth!, imgHeight!)
nextIndex = (currentIndex!+1) % (ADsArray?.count)!
}
nextView?.backgroundColor = ADsArray![nextIndex!]
}
}
上面代码可以看到,在滚动方向发生变化时我们要改变 nextView 的 frame,以及它对应的图片(这里因为是 demo,所以直接使用了color)。当滚动结束后 scrollView 会调用scrollViewDidEndDecelerating(scrollView: UIScrollView)这个方法,此时我们要改变currentView的 frame 以及它对应的图片(即 nextView 对应的图片)。
let offset = self.scrollView!.contentOffset.x;
let index = offset / self.imgWidth!
//1表示没有滚动
if index == 1
{
return
}
self.currentIndex = self.nextIndex
self.pageControl?.currentPage = self.currentIndex!
self.currentView?.frame = CGRectMake(self.imgWidth!, 0, self.imgWidth!, self.imgHeight!)
self.currentView?.backgroundColor = self.nextView?.backgroundColor
self.scrollView?.contentOffset = CGPointMake(imgWidth!, 0);
关于自动轮播这里不再赘述,详情点击这里查看整个工程demo的实现,如有疑问和写的不好的地方还望各位多多包涵,也欢迎指正,如果对您确实产生了有利的影响也希望您能赏个star!!!
网友评论
self.currentView?.frame
self.currentView?.backgroundColor
self.scrollView?.contentOffset
这里为啥都是用的?