创建一个无限循环滚动的广告视图。

import UIKit

typealias ImgIndexBlock = (Int) -> Void

class BunnderView: UIView {
    
    lazy var scrollView: UIScrollView = {
        let sv = UIScrollView(frame: CGRect(x: 0, y: 0,  self.frame.width, height: self.frame.height))
        sv.contentSize = CGSize( self.frame.width*3, height: self.frame.height)
        sv.delegate = self
        sv.isPagingEnabled = true
        sv.showsVerticalScrollIndicator = false;
        return sv
    }()
    
    var dataImgArray = [String](){
        didSet{
            imgArray = dataImgArray
            //目的是最终以图片数量大于3的情况处理
            if imgArray.count == 1 {//如果只有一张图片的时候则创建三张一样的图片
                imgArray += (imgArray + imgArray);
            }else if imgArray.count == 2 { //如果只有两张图片的时候则复制一遍生成4张一样的图片
                imgArray += imgArray;
            }
        }
    }
    private var imgArray = [String]()
    private var currentNum = 1;
    private var isNext = "center"
    var imgV_left:UIImageView!
    var imgV_center:UIImageView!
    var imgV_right:UIImageView!
    
    var imgIndexBlock:ImgIndexBlock = {_ in }
    
    func getImgIndex(block:@escaping ImgIndexBlock){
        imgIndexBlock = block
    }
    
    lazy var timer:Timer = {
        let t = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(scrollViewAction), userInfo: nil, repeats: true)
        return t;
    }()
    
    //MARK: 计时器事件
    @objc func scrollViewAction(){
        isNext = "true";
        //将scrollView 模拟滚动到第三章显示
        let point = CGPoint(x: self.frame.width*2, y: 0)
        scrollView.setContentOffset(point, animated: true)
    }
    
    lazy var tap:UITapGestureRecognizer = {
        let t = UITapGestureRecognizer(target: self, action: #selector(tapAction(_:)))
        return t;
    }()
    
    @objc func tapAction(_ t:UITapGestureRecognizer){
        if dataImgArray.count == 1 {
            imgIndexBlock(0)
        }else if dataImgArray.count == 2{
            if currentNum - 1 == 1{
                imgIndexBlock(1)
            }else if currentNum - 1 == 2{
                imgIndexBlock(0)
            }else if currentNum - 1 == 3{
                imgIndexBlock(1)
            }else{
                imgIndexBlock(0)
            }
        }else{
            imgIndexBlock(currentNum - 1)
        }
    }
    
    override func awakeFromNib() {
        
    }
    
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
        self.addSubview(scrollView)
        for i in 0..<imgArray.count{
            let imgV = UIImageView(frame: CGRect(x: self.frame.width*CGFloat(i), y:0 ,  self.frame.width, height: self.frame.height))
            if i == 0 {
                imgV.image = UIImage(named:imgArray.last!)
                imgV_left = imgV
            }
            if i == 1{
                imgV.image = UIImage(named:imgArray.first!)
                imgV_center = imgV
            }
            if i == 2{
                imgV.image = UIImage(named:imgArray[1])
                imgV_right = imgV
            }
            scrollView.addSubview(imgV)
        }
        setScollViewContentOffset()
        self.perform(#selector(timerContinue), with: nil, afterDelay: 3)
        //只需要处理显示在中间那一张的事件即可
        imgV_center.addGestureRecognizer(tap)
        imgV_center.isUserInteractionEnabled = true
    }
    
    
    @objc func timerContinue(){
        timer.timer_continue()
    }
    
    //将scrollView 偏移到第二张显示
    func setScollViewContentOffset(){
        let point = CGPoint(x: self.frame.width, y: 0)
        scrollView.setContentOffset(point, animated: false)
    }
}



//MARK:- Timer
extension Timer{
    /**
     *计时器暂停
     */
    func timer_pause(){
        self.fireDate = Date.distantFuture
    }
    /**
     *计时器继续
     */
    @objc func timer_continue(){
        self.fireDate = Date.distantPast
    }
}


////
extension BunnderView:UIScrollViewDelegate{
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        
        if scrollView.contentOffset.x > self.frame.width {
            isNext = "true";
        }else if scrollView.contentOffset.x < self.frame.width{
            isNext = "false";
        }else{
            isNext = "center"
        }
        scrollViewChange()
    }
    
    @objc func scrollViewChange(){
        setScollViewContentOffset()
        if isNext == "true" {
            currentNum += 1;
            if currentNum>imgArray.count{
                currentNum = 1;
            }
            
        }else if isNext == "false"{
            currentNum -= 1;
            if currentNum <= 0{
                currentNum = imgArray.count;
            }
        }
        setPreviousCenterImgView()
        setNextCenterImgView()
        imgV_center.image = UIImage(named:imgArray[currentNum-1])
    }
    
    //MARK: 设置前一张中心显示imgView
    func setPreviousCenterImgView(){
        let previousFristPageNum = currentNum - 1
        if previousFristPageNum <= 0{
            imgV_left.image = UIImage(named:imgArray.last!)
        }else{
            imgV_left.image = UIImage(named:imgArray[previousFristPageNum-1])
        }
    }
    //MARK: 设置下一张中心显示imgView
    func setNextCenterImgView(){
        let nextFristPageNum = currentNum + 1
        if nextFristPageNum > imgArray.count{
            imgV_right.image = UIImage(named:imgArray.first!)
        }else{
            imgV_right.image = UIImage(named:imgArray[nextFristPageNum-1])
        }
    }
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        
    }
    
    //MARK: 自动滚动结束设置scrollView的状态
    func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
        scrollViewChange()
    }
    
    //MARK: 手势滚动瞬间暂停计时器,同时暂停未执行的计时器事件
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        timer.timer_pause()
        NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(scrollViewAction), object: nil)
        NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(timerContinue), object: nil)
    }
    //MARK: 手势滚动结束计时器延迟3秒执行
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if decelerate {
            self .perform(#selector(timerContinue), with: nil, afterDelay: 3)
        }
    }
}

调用界面:使用方法

class ViewController: UIViewController {
    @IBOutlet weak var bunderView: BunnderView!
    override func viewDidLoad() {
        super.viewDidLoad()

        bunderView.dataImgArray = ["1"]
        bunderView.getImgIndex { (index) in
            print("点击了坐标为:(index)的图片")
        }

    }
}

  

  

原文地址:https://www.cnblogs.com/mapanguan/p/8032568.html