swift3.0版----使用一个UIImageView实现轮播图

使用一个UIImageView实现无限轮播功能
比如:
1.使用GCD定时器来解决NSTimer使用过程中的坑
GCD定时器使用如下

/// GCD定时器
    let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())

然后在设置UI时添加触发方法----这里一定要注意,刷新UI一定要回到主线程去操作

fileprivate func updateviews() {
        contentMode = .scaleAspectFill
        layer.masksToBounds = true
        isUserInteractionEnabled = true

        ***添加手势****
        kf.indicatorType = .activity
       //GCD定时器执行方法
        timer.scheduleRepeating(deadline: DispatchTime.now() + config.duration, interval: config.duration)
        timer.setEventHandler { 
            [weak self] in
            guard let strongSelf = self else { return }
            var new = strongSelf.index
            new = new + 1
            if new == strongSelf.urls.count {
                new = 0
            }
            DispatchQueue.main.async {
                strongSelf.index = new
                strongSelf.animator(UISwipeGestureRecognizerDirection.down)
            }
        }
        **设置pageController**
    }
  1. 属性
  /// 数据源--字符串
    var dataSource: [String] = [] {
        didSet {
            urls = dataSource.flatMap { URL(string: $0) }
        }
    }
    /// URL地址----这里使用flatMap转化并去掉不正确的URL
    fileprivate var urls: [URL] = [] {
        didSet {
    //使用Kingfisher加载网络图片
            ImagePrefetcher(resources: urls).start()
            kf.setImage(with: urls.first)
            guard urls.count > 1 else {
                return
            }
            timer.resume()
            pageControl.numberOfPages = urls.count
        }
    }
//当前index
fileprivate var index: Int = 0 {
        didSet {
            if Thread.isMainThread {
                pageControl.currentPage = index > urls.count ? urls.count : index
            } else {
                DispatchQueue.main.async { [weak self] in
                    guard let strongSelf = self else { return }
                    strongSelf.pageControl.currentPage = strongSelf.index > strongSelf.urls.count ? strongSelf.urls.count : strongSelf.index
                }
            }
        }
    }
/// 动画函数--- 这里是只初始化一个动画对象---防止重建多个对象
其中 typealias Animator = (UISwipeGestureRecognizerDirection) -> ()
    fileprivate var animator: Animator!
fileprivate func setAnimator() -> Animator {
        let transition = CATransition()
        return { direction in
            guard self.urls.count > 1 else {
                return
            }
            self.kf.setImage(with: self.urls[self.index])
            if direction == UISwipeGestureRecognizerDirection.left {
                transition.duration = 0.5
                transition.type = self.config.gestureAnimator.rawValue
                transition.subtype = "fromRight"
            } else if direction == UISwipeGestureRecognizerDirection.right {
                transition.duration = 0.5
                transition.type = self.config.gestureAnimator.rawValue
                transition.subtype = "fromLeft"
            } else {
                transition.duration = 1
                transition.type = self.config.motionAnimator.rawValue
                transition.subtype = "fromRight"
            }
            self.layer.add(transition, forKey: nil)
        }
    }

最终初始化方法---其中config是采用回调方式设置轮播图

/// 初始化轮播图
    ///
    /// - Parameters:
    ///   - frame: 位置
    ///   - placeholder: 默认uiimage
    ///   - config: 轮播图配置
    ///   - delegate: 代理
    ///   - callBack: 点击回调
typealias RunConfig = () -> RunloopViewConfig
    init(frame: CGRect, placeholder: UIImage? = nil, config: RunConfig? = nil, delegate: RunloopViewDelegate? = nil, callBack: Select? = nil) {
        self.callBack = callBack
        if let config = config {
            self.config = config()
        }
        if let delegate = delegate {
            self.delegate = delegate
        }
        super.init(frame: frame)
        updateviews()
        self.image = placeholder
        animator = setAnimator()
    }
/// 轮播图设置
struct RunloopViewConfig {
    /// 图片轮播时间---默认5s
    var duration: TimeInterval        = 5
    /// pageControl圆点颜色---默认white
    var pageColor: UIColor            = UIColor.white
    /// pageControl当前颜色---默认green
    var currentColor: UIColor         = UIColor.green
    /// 手势动画---默认新图推旧图
    var gestureAnimator: AnimatorMode = .push
    /// 定时动画---默认水滴波
    var motionAnimator: AnimatorMode  = .ripple
}

/// 动画类型
///
/// - fade: 淡出效果
/// - moveIn: 新视图移动到旧视图上
/// - push: 新视图推出旧视图
/// - reveal: 移开旧视图显示新视图
/// - cube: 立方体翻转效果
/// - ripple: 水滴波纹效果
/// - oglFlip: 翻转效果
enum AnimatorMode: String {
    case fade
    case moveIn
    case push
    case reveal
    case cube
    case ripple    = "rippleEffect"
    case oglFlip
}

外界调用

let runView = RunloopView(frame: CGRect.init(x: 0, y: 80, width: UIScreen.main.bounds.width, height: 200), config: { _ in
            var a = RunloopViewConfig()
            a.gestureAnimator = .cube
            return a
        }) { (index) in
            print("----\(index)")
        }
        runView.dataSource = [
            "http://pic.qiantucdn.com/58pic/18/14/83/54d58PICtkn_1024.jpg",
            "http://pic.qiantucdn.com/58pic/13/71/43/67I58PICJ4r_1024.jpg",
            "http://pic16.nipic.com/20110927/3101644_080616110148_2.jpg",
            "http://pic30.nipic.com/20130619/13053351_060617500180_2.jpg",
            "http://pic125.nipic.com/file/20170323/13452884_100721331000_2.jpg",
            "http://pic125.nipic.com/file/20170323/13452884_100713250000_2.jpg"
        ]

你可能感兴趣的:(swift3.0版----使用一个UIImageView实现轮播图)