1. 程式人生 > >Swift 利用UIScrollView和兩個UIImageView實現圖片輪滾

Swift 利用UIScrollView和兩個UIImageView實現圖片輪滾

現在基本所有的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) } }