Swift 利用UIScrollView和兩個UIImageView實現圖片輪滾
阿新 • • 發佈:2019-01-23
現在基本所有的app都帶有圖片輪滾的廣告頁面或者推薦頁面,圖片輪滾實現的方式有很多種:
最簡單的一種,利用scrollView在前後各加一個輔助的imageView過渡,然後更改scrollView的contentOffset實現圖片輪滾。
第二種,利用三個imageView,add到scrollView上,一直顯示最中間的imageView,每次滾動後,更改scrollView的contentOffset,更新每個imageView的image。
第三種,利用兩個imageView,add到scrollView上,在每次滾動時,判斷滾動方向然後更改沒有顯示的imageView的frame,再更改scrollView的contentOffset,再更新imageView的image.
第四種,利用UICollectionView,每次滾動更改item的順序就可以了。
在這裡實現的第三種方法:
import UIKit
class HGPictureScrollView: UIView, UIScrollViewDelegate {
var images: Array<UIImage!>!
var scrollView: UIScrollView!
var pageControl: UIPageControl!
var currentImageView: UIImageView!
var defaultImageView: UIImageView!
var timer: NSTimer!
init(frame: CGRect, withImages: Array<UIImage!>) {
super.init (frame: frame)
self.images = withImages
scrollView = UIScrollView.init()
scrollView.alwaysBounceVertical = false
scrollView.pagingEnabled = true
scrollView.showsHorizontalScrollIndicator = false
scrollView.contentSize = CGSizeMake((self.bounds.size.width * CGFloat(3)), self.bounds.size.height)
scrollView.contentOffset.x = self.bounds.size.width
scrollView.delegate = self
self.addImages()
self.addSubview(scrollView)
pageControl = UIPageControl.init()
pageControl.numberOfPages = images.count
pageControl.pageIndicatorTintColor = UIColor.redColor()
pageControl.currentPageIndicatorTintColor = UIColor.yellowColor()
self.addSubview(pageControl)
timer = NSTimer.scheduledTimerWithTimeInterval(1.5, target: self, selector: "next", userInfo: nil, repeats: true)
//如需在tableView的滾動中也讓timer工作,只需開啟下面的註釋,將上面一句註釋掉
// timer = NSTimer.init(timeInterval: 1.5, target: self, selector: "next", userInfo: nil, repeats: true)
// NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
timer.invalidate()
}
//設定兩個imageView的初始image
func addImages() {
currentImageView = UIImageView.init(frame: CGRectMake(self.bounds.size.width, 0, self.bounds.size.width, self.bounds.size.height))
currentImageView.image = images[0]
scrollView.addSubview(currentImageView)
defaultImageView = UIImageView.init(frame: CGRectMake(self.bounds.size.width * 2, 0, self.bounds.size.width, self.bounds.size.height))
defaultImageView.image = images[1]
scrollView.addSubview(defaultImageView)
}
//返回imageView上的image在images中的index
func indexOfImageView(imageView: UIImageView)->Int {
return images.indexOf({ (image) -> Bool in
return (imageView.image?.isEqual(image))!
})!
}
//得到pageControl的currentPage,1.5表示:超過0.5個螢幕大小,就認為發生了page變化
func currentPageWithImageViews(imageView: UIImageView, rightImageView: UIImageView)->Int {
return scrollView.contentOffset.x > self.bounds.size.width * 1.5 ? indexOfImageView(rightImageView) : indexOfImageView(imageView)
}
//滾動到下一張圖片
func next() {
scrollView.scrollRectToVisible(CGRectMake(scrollView.contentOffset.x + self.bounds.size.width, 0, self.bounds.size.width, self.bounds.size.height), animated: true)
}
override func layoutSubviews() {
super.layoutSubviews()
scrollView.frame = self.bounds
pageControl.frame = CGRectMake(0, 0, CGFloat(20 * images.count), 20)
pageControl.center = CGPointMake(self.bounds.width/2, 20)
}
func scrollViewDidScroll(scrollView: UIScrollView) {
//判斷向左還是向右滾動
if scrollView.contentOffset.x > self.bounds.size.width {
defaultImageView.frame = CGRectMake(self.bounds.size.width * 2, 0, self.bounds.size.width, self.bounds.size.height)
//更改副imageView的image
defaultImageView.image = images[(indexOfImageView(currentImageView) + 1) % images.count]
//更改pageControl的currentPage
pageControl.currentPage = currentPageWithImageViews(currentImageView, rightImageView: defaultImageView)
}
if scrollView.contentOffset.x < self.bounds.size.width {
defaultImageView.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)
defaultImageView.image = images[(indexOfImageView(currentImageView) + images.count - 1) % images.count]
pageControl.currentPage = currentPageWithImageViews(defaultImageView, rightImageView: currentImageView)
}
//這裡是判斷scrollView停止滾動,利用timer讓scrollView滾動時,不走scrollViewDidEndDecelerating方法,無法更換圖片
if (scrollView.contentOffset.x >= self.bounds.size.width * 2) || (scrollView.contentOffset.x <= 0) {
scrollView.contentOffset.x = self.bounds.size.width
currentImageView.image = defaultImageView.image
}
}
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
timer.fireDate = NSDate.distantFuture()
}
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
timer.fireDate = NSDate.init(timeIntervalSinceNow: 1.5)
}
}