一句话创建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. HTML5 CANVAS制图 基础总结

    一.基本绘图 首先,定义2D渲染变量ct(这里用了Jquery库): var ct = $(#canvasId).get(0).getContext('2d'); 以下是绘制各种基本图形的方法: // ...

  2. Coding Dojo

    Coding Dojo 发表于 2012-10-25 什么是Coding Dojo? Coding Dojo是一个学习的过程.一些程序员(通常是15-20人)在一起编程解决一个程序问题.一边编程,一边 ...

  3. C#通过接口与线程通信(捕获线程状态)介绍

    C#通过接口与线程通信(捕获线程状态)介绍 摘要:本文介绍C#通过接口与线程通信(捕获线程状态),并提供简单的示例代码供参考. 提示:本文所提到的线程状态变化,并不是指线程启动.暂停.停止,而是说线程 ...

  4. jquery mobile Checkbox动态添加刷新及事件绑定

    jquery mobile Checkbox动态添加刷新及事件绑定 在微信项目中,涉及到一个多选功能.数据来自后台数据库,需要动态加载. 项目结构:微信api+web app.使用jquery mob ...

  5. journaling保证意外故障下的数据完整性

    mongoDB研究笔记:journaling保证意外故障下的数据完整性   mongoDB的Journaling日志功能与常见的log日志是不一样的,mongoDB也有log日志,它只是简单记录了数据 ...

  6. 我的第一篇文章 —— IE6的那些css常见bug(汇总)

    我的微博终于在前几天建立了 虽说很早之前就知道博客园这个地方 但怕自己不能坚持去写一些东西一直没有建.这几天 我做了这个决定 把我的博客建起来 每周发一些看到的,听到了一些前端知识或者前沿技术. 另外 ...

  7. MVC4.0系统开发新手历程1

    MVC4.0系统开发新手历程(一) 接手了一个简单的销售奖金计算的项目,虽然不算大但是业务逻辑比较复杂,还夹杂了很多的特殊情况,毕竟是大公司什么样的人都有,好了不多说切入正题,项目是公司的一个前辈负责 ...

  8. 实战 ASP.NET MVC Web API

    实战 ASP.NET MVC Web API Web API 框架基于 ASP.NET MVC 框架开发,是一个面向 Http 协议的通信框架.相对于 WCF 而言,Web API 只面向于 Http ...

  9. php设计模式之抽象工厂模式

    之前总结了一下工厂模式,其实准确地说是简单 工厂模式,在它的基础上再进行抽象就可以得到一种新的模式:抽象工厂模式. 专业一点的定义为: 抽象工厂模式(Abstact Factory)是一种常见的软件设 ...

  10. Kafka consumer处理大消息数据问题

    案例分析 处理kafka consumer的程序的时候,发现如下错误: ERROR [2016-07-22 07:16:02,466] com.flow.kafka.consumer.main.Kaf ...