自从找到工作以来一直都是搞逻辑层,UI层的实现基本不用我搞,所以UI层的东西俺研究的不是特别多,然而像俺这种追求完美的男子,俺是不允许这种偏科的情况出现滴,所以2017年计划将一部分时间花费在UI层的研究上。那么先从最简单的图片轮播搞起吧,给自己一个完美的开端(说了那么多,其实根本原因是我最近没有啥写的了藍)!
图片轮播网上一搜一大堆,做法也是多种多样,不过目的都是能搞定的。这篇文章主要总结了一下两种最完美的实现方式。
虽然这两种实现方式有点小区别,但都能做到内存消耗很少,实现imageView的复用,实现无限图片轮播效果。先看下效果(图片有点大,让网页多加载一会):
Demo地址 猛戳我 使用的是Swift 3编写。
好了,其实实现原理看代码就行了,不需要再往下写了。但是像俺这种追求完美的男子,不允许文章就这么短,俺接着往下写,小伙伴们可以直接去看代码了,不要打扰我装逼!裸
使用UIScrollView实现的原理超级简单,你懂,就是很简单。我们用三个UIImageView循环去显示图片,这样子内存占用得到了保障,效果也非常好。具体做法:
A -> 最后一张图片 , B -> 第一张图片 , C -> 第二张图片 。首先让ScrollView显示B也就是第一张图片。 /// 只使用3个UIImageView,依次设置好最后一个,第一个,第二个图片,这里面使用取模运算。
for index in 0..<3 {
let imageView = UIImageView(frame: CGRect(x: CGFloat(index) * kScreenWidth, y: 0, width: kScreenWidth, height: kScreenHeight))
imageView.image = UIImage(named: "/((index +3)% 4).png")
scrollView.addSubview(imageView)
}
当我们左滑显示第二张图片也就是C, 当页面显示滑动停止以后 ,我们将A B C重新显示图片为: A -> 第一张图片 , B -> 第二张图片 , C -> 第三张图片 ,然后让ScrollView再次显示B。所以界面显示的图片虽然变了,但一直显示的还是中间那个UIImageView。这样就造成了无限循环滑动。右滑原理一样。
如果我们右滑显示最后一张图片也就是A, 当页面显示滑动停止以后 ,我们将A B C重新显示图片为: A -> 倒数第二张图片 , B -> 最后一张图片 , C -> 第一张图片 ,然后让ScrollView再次显示B。这样子就是一个无限循环轮播。
也就是说scrollView永远显示就是中间那个imageView,只是显示的图片不一样,所以左滑右滑都会有图片,就是传说中的无限滚动。关键点就是图片显示以后有一个reloadImage的过程。(为了简单我使用了万恶的 ! )
/// 重新加载图片,重新设置3个imageView
funcreloadImage() {
let currentIndex = pageView.currentPage
let nextIndex = (currentIndex + 1) % 4
let preIndex = (currentIndex + 3) % 4
(scrollView.subviews[0] as! UIImageView).image = UIImage(named: "/(preIndex).png")
(scrollView.subviews[1] as! UIImageView).image = UIImage(named: "/(currentIndex).png")
(scrollView.subviews[2] as! UIImageView).image = UIImage(named: "/(nextIndex).png")
}
至于自动滚动就是添加 NSTimer ,具体可以参考一下 Demo
使用UICollectionView的原理和使用UIScrollView的原理有点区别。具体哪种方式好就是仁者见仁智者见智了。使用UICollectionView的原理是设置2倍图片数量的Cell,循环显示图片,具体做法:
funcnumberOfSections(incollectionView: UICollectionView) -> Int {
return 1
}
funccollectionView(_collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return images.count * 2
}
funccollectionView(_collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? BannerCollectionViewCell
if let cell = cell {
cell.imageName = images[indexPath.item % 4]
return cell
}
return cell!
}
关键方法还是reloadImage方法
funcreloadImage() {
guard let currentIndexPath = currentIndexPath else {
return
}
if currentIndexPath.item == images.count * 2 - 1 { //如果是最后一个图片,回到第一部分的最后一张图片
let newIndexPath = IndexPath(item: images.count - 1, section: 0)
self.currentIndexPath = newIndexPath
collectionView.scrollToItem(at: newIndexPath, at: .centeredHorizontally, animated: false)
} else if currentIndexPath.item == 0 { //如果是第一个图片,就回到第二部分的第一张图片
let newIndexPath = IndexPath(item: images.count, section: 0)
self.currentIndexPath = newIndexPath
collectionView.scrollToItem(at: newIndexPath, at: .centeredHorizontally, animated: false)
}
}
哈哈,是不是炒鸡简单,具体代码小伙伴们直接参考Demo,代码稍作修改就可以进行复用了。裸
小伙伴们如果感觉文章可以,可以关注博主博客
小伙伴们多多关注博主微博,探索博主内心世界
如要转载请注明出处。