一句话创建banner图,可时时刷新

用到了 SnapKit、SDWebImage两个第三方库

实现步骤----------------------------------------------------

import UIKit

typealias BtnBlock = (Int) -> Void

//ImagesBlock

typealias ImagesBlock = () -> [String]

class CycleView: UIView,UIScrollViewDelegate {

//MARK: - 私有属性

private var btnBlock:BtnBlock?  //block

private var imageBlock:ImagesBlock?

private var scrollView: UIScrollView?

private var pageControl: UIPageControl?

private var images:[UIImage]?

private var imageStrs:[String]?

private var timer: Timer?

private var currentPage = 0 {

didSet {

pageControl?.currentPage = currentPage

resetImageViewSource()

}

}

//MARK: - 给外部调用的属性

var rollingTime: TimeInterval = 2.0   //滚动一页的时间

var rollingEnable: Bool = false {             //是否自动滚动

willSet {

if newValue != rollingEnable {

if newValue {

startTimer()

} else {

stopTimer()

}

}

}

}

//MARK: -  刷新数据

public func reloadCyc(){

imageStrs = imageBlock?()

pageControl?.numberOfPages = (imageStrs?.count)!

if imageStrs?.count != 0{

currentPage = 0

if imageStrs?.count == 1{

stopTimer()

scrollView?.isScrollEnabled = false

}else{

startTimer()

scrollView?.isScrollEnabled = true

}

}else{

stopTimer()

scrollView?.isScrollEnabled = false

for i in 0..<3 {

let img = scrollView?.subviews[i] as! UIImageView

img.image = nil

}

}

}

//MAKR:- 暴露创建对象方法

/// 获取到一个滚动视图

///

/// - parameter imageSourceBlock: image数据block

/// - parameter btnBlk:           scroview点击block

///

/// - returns: CycleView对象

static func showCycView(imageSourceBlock:ImagesBlock?,btnBlk:BtnBlock?) -> CycleView {

let cycView = CycleView()

cycView.showCycView(imageSourceBlock: imageSourceBlock, btnBlk: btnBlk)

return cycView

}

//私有对象方法

private func showCycView(imageSourceBlock:ImagesBlock?,btnBlk:BtnBlock?) -> Void{

imageBlock = imageSourceBlock

btnBlock = btnBlk

setUI()

self.reloadCyc()

startTimer()

}

//创建UI

private func setUI(){

scrollView = UIScrollView()

self.addSubview(scrollView!)

scrollView?.backgroundColor = UIColor.gray

scrollView?.snp.makeConstraints({ (make) in

make.top.left.bottom.right.equalToSuperview()

})

scrollView?.showsHorizontalScrollIndicator = false

scrollView?.showsVerticalScrollIndicator = false

scrollView?.isPagingEnabled = true

scrollView?.bounces = false

scrollView?.delegate = self

scrollView?.addSubview(UIImageView())

scrollView?.addSubview(UIImageView())

scrollView?.addSubview(UIImageView())

let tap = UITapGestureRecognizer(target: self, action: #selector(self.tapAction))

scrollView?.addGestureRecognizer(tap)

pageControl?.isEnabled = false

pageControl = UIPageControl()

pageControl?.currentPage = 0

pageControl?.isUserInteractionEnabled = false

pageControl?.currentPageIndicatorTintColor = UIColor.green

pageControl?.pageIndicatorTintColor = UIColor.gray

self.addSubview(pageControl!)

pageControl?.snp.makeConstraints({ (make) in

make.left.equalToSuperview().offset(10)

make.right.equalToSuperview().offset(-10)

make.bottom.equalToSuperview().offset(-20)

make.height.equalTo(30)

})

}

//MARK:- 自动滚动

//开始滚动

private func startTimer() {

if timer==nil {

timer = Timer.scheduledTimer(timeInterval: rollingTime, target: self, selector: #selector(scrollForTime(time:)), userInfo: nil, repeats: true)

}

}

//停止滚动

private func stopTimer() {

if(timer != nil){

timer!.invalidate()

timer = nil

}

}

//滚动事件

func scrollForTime(time:Timer) -> Void {

scrollView?.setContentOffset(CGPoint(x: self.frame.size.width * 2, y: 0), animated: true)

}

//MARK:- 适配scroview及image

override func layoutSubviews() {

super.layoutSubviews()

scrollView?.contentSize = CGSize(width: self.frame.size.width * 3, height: self.frame.size.height)

scrollView?.setContentOffset(CGPoint(x: self.frame.size.width * 2, y: 0), animated: false)

for i in 0..<3 {

let img = scrollView?.subviews[i] as! UIImageView

img.contentMode = .scaleAspectFit

img.clipsToBounds = true

img.frame = CGRect(x: CGFloat(i) * (scrollView?.frame.size.width)!, y: 0, width: (scrollView?.frame.size.width)!, height: (scrollView?.frame.size.height)!)

}

}

//MARK:-每当滚动后重新设置各个imageView的图片

func resetImageViewSource() {

let placeholderImage = UIImage(named: "placeholder.png")

let leftImageView = scrollView?.subviews[0] as! UIImageView

let middleImageView = scrollView?.subviews[1] as! UIImageView

let rightImageView = scrollView?.subviews[2] as! UIImageView

//当前显示的是第一张图片

if currentPage == 0 {

leftImageView.sd_setImage(with: URL.init(string: (imageStrs?.last)!), placeholderImage: placeholderImage)

middleImageView.sd_setImage(with: URL.init(string: (imageStrs?[currentPage])!), placeholderImage: placeholderImage)

let rightImageIndex = (imageStrs?.count)!>1 ? 1 : 0 //保护

rightImageView.sd_setImage(with: URL.init(string: (imageStrs?[rightImageIndex])!), placeholderImage: placeholderImage)

}//当前显示的是最后一张图片

else if currentPage == (imageStrs?.count)! - 1 {

leftImageView.sd_setImage(with: URL.init(string: (imageStrs?[currentPage-1])!), placeholderImage: placeholderImage)

middleImageView.sd_setImage(with: URL.init(string: (imageStrs?[currentPage])!), placeholderImage: placeholderImage)

rightImageView.sd_setImage(with: URL.init(string: (imageStrs?[0])!), placeholderImage: placeholderImage)

}//其他情况

else{

leftImageView.sd_setImage(with: URL.init(string: (imageStrs?[currentPage-1])!), placeholderImage: placeholderImage)

middleImageView.sd_setImage(with: URL.init(string: (imageStrs?[currentPage])!), placeholderImage: placeholderImage)

rightImageView.sd_setImage(with: URL.init(string: (imageStrs?[currentPage+1])!), placeholderImage: placeholderImage)

}

scrollView?.setContentOffset(CGPoint(x: self.frame.size.width, y: 0), animated: false)

}

//MARK: - scrollViewDelegate

//setContentOffset的动画完成后会调用,使currentPage+1

func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {

if imageStrs?.count != 0{

currentPage = (currentPage+1)%(imageStrs?.count)!

}

}

//拖动scrollView时会停止自动滚动

func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {

if rollingEnable {

stopTimer()

}

}

//停止拖动后会重新开始自动滚动

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {

if rollingEnable {

startTimer()

}

scrollView.isScrollEnabled = false

}

//拖动scrollView时当减速动画结束时调用

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

scrollView.isScrollEnabled = true

if imageStrs?.count != 0{

if scrollView.contentOffset.x == 0 {                                    //向前滑动

if currentPage == 0 {

currentPage = (imageStrs?.count)!-1

} else {

currentPage -= 1

}

} else if scrollView.contentOffset.x == 2 * self.frame.size.width {     //向后滑动

currentPage = (currentPage+1)%(imageStrs?.count)!

}

}

}

//MARK:- 点击图片回调事件

func tapAction() {

if imageStrs?.count != 0{

btnBlock?(currentPage)

}

}

}

调用方法----------------------

import UIKit

import SnapKit

import SDWebImage

class ViewController: UIViewController {

var imageStrs = [String]()

var cyc : CycleView?

override func viewDidLoad() {

super.viewDidLoad()

self.automaticallyAdjustsScrollViewInsets = false

setUI()

}

func setUI(){

cyc = CycleView.showCycView(imageSourceBlock: { () -> [String] in

return self.imageStrs //返回图片url,若要支持本地图片,自行修改

}) { (tag) in

print("tag:\(tag)")//图片点击回调

}

self.view.addSubview(cyc!)

cyc?.rollingTime = 4

cyc?.snp.makeConstraints { (make) in

make.left.right.equalToSuperview().offset(0)

make.top.equalToSuperview().offset(20)

make.height.equalTo(230)

}

let btn = UIButton(type: UIButtonType.system)

btn.setTitle("增加image", for: UIControlState.normal)

self.view.addSubview(btn)

btn.tag = 1

btn.addTarget(self, action: #selector(btnAction(btn:)), for: UIControlEvents.touchUpInside)

btn.snp.makeConstraints { (make) in

make.center.equalToSuperview()

make.width.equalTo(100)

make.height.equalTo(30)

}

let btn2 = UIButton(type: UIButtonType.system)

btn2.setTitle("减少image", for: UIControlState.normal)

self.view.addSubview(btn2)

btn2.tag = 2

btn2.addTarget(self, action: #selector(btnAction(btn:)), for: UIControlEvents.touchUpInside)

btn2.snp.makeConstraints { (make) in

make.centerX.equalTo(btn.snp.centerX)

make.centerY.equalTo(btn.snp.centerY).offset(100)

make.width.equalTo(100)

make.height.equalTo(30)

}

}

var count = 0

func btnAction(btn:UIButton){

let str1 = "http://d.hiphotos.baidu.com/image/pic/item/f9dcd100baa1cd11c1c35727bb12c8fcc3ce2dbb.jpg"

let str2 = "http://c.hiphotos.baidu.com/image/pic/item/6c224f4a20a4462323289f659a22720e0df3d7d2.jpg"

let str3 = "http://d.hiphotos.baidu.com/image/pic/item/7dd98d1001e939014acbb73979ec54e737d196ef.jpg"

let str4 = "http://i.zeze.com/attachment/forum/201502/09/122834pcd2q5l5dcnd4nqc.jpg"

let str5 = "http://img0.imgtn.bdimg.com/it/u=2176846966,1717026392&fm=21&gp=0.jpg"

let str6 = "http://b.hiphotos.baidu.com/zhidao/wh=450,600/sign=457d1fcc2c2eb938ec3872f6e052a903/21a4462309f7905289b85b130ff3d7ca7bcbd573.jpg"

let str7 = "http://img2.imgtn.bdimg.com/it/u=2553369102,2423460114&fm=21&gp=0.jpg"

let str8 = "http://img0.imgtn.bdimg.com/it/u=3230797900,10373402&fm=21&gp=0.jpg"

let str9 = "http://img4.imgtn.bdimg.com/it/u=1432393253,809810063&fm=21&gp=0.jpg"

let arr = [str1,str2,str3,str4,str5,str6,str7,str8,str9]

if btn.tag == 1{

if count >= arr.count{

imageStrs.removeAll()

count = 0;

}

imageStrs.append(arr[count])

cyc?.reloadCyc()

count += 1

}else{

if imageStrs.count != 0{

imageStrs.removeLast()

cyc?.reloadCyc()

count -= 1

}else{

count = 0

}

}

}

override func didReceiveMemoryWarning() {

super.didReceiveMemoryWarning()

}

}

demo下载地址

swift3 循环滚动视图 自适应横竖屏 reload数据源的更多相关文章

  1. IOS实现自动循环滚动广告--ScrollView的优化和封装

    一.问题分析 在许多App中,我们都会见到循环滚动的视图,比如广告,其实想实现这个功能并不难,用ScrollView就可以轻松完成,但是在制作的过程中还存在几个小问题,如果能够正确的处理好这些小问题, ...

  2. UIScrollView循环滚动1

    现在基本每一个商业APP都会有循环滚动视图,放一些轮播广告之类的,都是放在UIScrollView之上.假如我要实现N张图片的轮播,我借鉴了几个博文,得到两种方法实现: [第一种]:如下图(图片来源于 ...

  3. layoutSubviews中判断横竖屏

    在ContentView中重写layoutSubviews方法,然后根据stausbar的方向判断当前视图的横竖屏.具体代码: -(void)layoutSubviews{ [super layout ...

  4. 【IOS界面布局】横竖屏切换和控件自适应(推荐)

    [IOS界面布局]横竖屏切换和控件自适应(推荐) 分类: [MAC/IOS下开发]2013-11-06 15:14 8798人阅读 评论(0) 收藏 举报 横竖屏切换 自适应 第一种:通过人为的办法改 ...

  5. iOS 之 设置横竖屏及ViewWillAppear及视图与导航控制器嵌套时的不同反应

    设置横竖屏不成功,可能跟所在导航控制器有关 视图没有导航控制器时,又有可能不调用ViewWillAppear,这是我遇到的问题.

  6. iOS横竖屏切换的一些坑(持续更新)

    最近在做视频类的App,遇到视频滚动播放的坑,紧接着就是横竖屏问题.之前太过天真不想做横竖屏配置.只是想旋转视频View,但是分享什么的包括AlertView还是竖屏样式,项目着急上线(1周提交一次也 ...

  7. 从零開始学android&lt;ScrollView滚动视图.十八.&gt;

    因为手机屏幕的高度有限.所以假设面对组件要显示多组信息的时候,ScrollView视图(滚动视图)能够有效的安排这些组件,浏览时能够自己主动的进行滚屏的操作. android.widget.Scrol ...

  8. Android零基础入门第76节:Activity数据保存和横竖屏切换

    在前面几期学习了Activity的创建.配置.启动和停止,还学了Activity的生命周期,本期一起来学习Activity有关的更多事儿. 一.数据保存 通过上一期 LogCat 窗口打印的日志可以看 ...

  9. iOS学习笔记——滚动视图(scrollView)

    滚动视图:在根视图中添加UIScrollViewDelegate协议,声明一些对象属性 @interface BoViewController : UIViewController<UIScro ...

随机推荐

  1. 6 MySQL视图

    目录: 1. 视图概述 1.1 为什么引入视图 1.2 什么是视图 1.3 视图的好处 1.4 视图的分类 2. 视图的建立和删除 3. 实验 1. 视图概述 1.1 为什么引入视图[1] 问题:假如 ...

  2. dedecms模板中使用php代码

    {dede:php} echo “test”: {/dede:php} 使用这段代码之前要在后台的系统--系统基本参数--其它选项 里找到 模板引擎禁用标签: php  将其删除

  3. Api 和 Spi

    目录 背景Java类库中的实例如何实现这种结构?备注 背景返回目录 Java 中区分 Api 和 Spi,通俗的讲:Api 和 Spi 都是相对的概念,他们的差别只在语义上,Api 直接被应用开发人员 ...

  4. asp.net内部原理3

    asp.net内部原理(三) 第三个版本 (最详细的版本) 前言: 今天继续吧这个系列补齐,这几天公司的项目比较忙,回到家已经非常的累了,所以也没顾得上天天来这里分享一些东西和大家一起探讨,但是今天晚 ...

  5. Python:高级主题之(属性取值和赋值过程、属性描述符、装饰器)

    Python:高级主题之(属性取值和赋值过程.属性描述符.装饰器) 背景 学习了Javascript才知道原来属性的取值和赋值操作访问的“位置”可能不同.还有词法作用域这个东西,这也是我学习任何一门语 ...

  6. Mathematics for Computer Graphics

    Mathematics for Computer Graphics 最近严重感觉到数学知识的不足! http://bbs.gameres.com/showthread.asp?threadid=105 ...

  7. CSS样式基础知识

    CSS样式基础知识 CSS样式概述 CSS是Cascading Style Sheet 的缩写.译作“层叠样式表单”.是用于(增强)控制网页样式并允许将样式信息与网页内容分离的一种标记性语言. 引用位 ...

  8. LoadTest中内存和线程Troubleshooting实战

    LoadTest中内存和线程Troubleshooting实战 在端午节放假的三天中,我对正在开发的Service进行了LoadTest,尝试在增大压力的条件下发现问题. 该Service为独立进程的 ...

  9. [修]python普通继承方式和super继承方式

    [转]python普通继承方式和super继承方式 原文出自:http://www.360doc.com/content/13/0306/15/9934052_269664772.shtml 原文的错 ...

  10. java微信平台,发源码

    最近写了一个微信平台的架构,采用servlet + spring3.0 + hibernate4.1.整体架构由我负责建设,我尽可能的把业务模块分出来.趁着刚搭好的框架,留着这版.代码是大部份都由其他 ...