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"
        ]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,123评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,031评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,723评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,357评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,412评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,760评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,904评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,672评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,118评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,456评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,599评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,264评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,857评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,731评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,956评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,286评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,465评论 2 348

推荐阅读更多精彩内容