自从找到工作以来一直都是搞逻辑层,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,代码稍作修改就可以进行复用了。裸
小伙伴们如果感觉文章可以,可以关注博主博客
小伙伴们多多关注博主微博,探索博主内心世界
如要转载请注明出处。