写的不好 ~ swift3.0 可自定义轮播内容
/* _ _____ __ _ _____ _ _ __ __
| | | ____| | \ | | / ___/ | | / / \ \ / /
| | | |__ | \| | | |___ | |/ / \ \/ /
| | | __| | |\ | \___ \ | |\ \ \ /
| |___ | |___ | | \ | ___| | | | \ \ / /
|_____| |_____| |_| \_| /_____/ |_| \_\ /_/ */
import UIKit
// ================ 代理协议 ======================
@objc protocol CycleScrollViewDelegate:NSObjectProtocol {
//当前点击的是第几页
@objc optional func cycleDidTapWithIndex(page:Int,cycleScrollView:CycleScrollView)
@objc optional func cycleDidScrollPage(page:Int,cycleScrollView:CycleScrollView)
}
@objc protocol CycleScrollViewDataSource:CycleScrollViewDelegate {
//如果是自定义的cell 必须实现下面的代理方法
func cycleCustomView(index:Int,cycleScrollView:CycleScrollView) -> UIView
//给自定义View 进行赋值 currentView 当前的View data 要赋值的数据
func cycleCustomViewConfigerData(currentView:UIView,data:Any)
}
// ============================================
//================== 枚举类型 ====================
//循环类型
enum CyScrollViewType {
case Horizontal //横向
case Vertical //纵向
}
// ============================================
//轮播 view 使用三张图片实现 同样可以使用CollectionView 使用假象 这种用法可能有点诡异
class CycleScrollView : UIImageView,UIScrollViewDelegate {
//当前选中的是第几个
private var index:Int = 0
private var imgArray:Array<Any> = []
private var _timer:Timer?
private var placehodeImg:UIImage?
private var imgViews:Array<UIImageView> = []
private var isHiddenPage:Bool = false
private var isCustom:Bool = false
private var scrollType:CyScrollViewType = .Horizontal //默认是横向滚动
//代理协议书写方式 使用 weak open var
weak open var lgdelegate : CycleScrollViewDelegate?
weak open var lgDataSource:CycleScrollViewDataSource?
//设置滚动类型
/*
* 上下滚动还是左右滚动
*/
func configerScrollType(aScrollType:CyScrollViewType){
invailTimer()
scrollType = aScrollType
layoutSubviews()
index = 0
if scrollType == .Horizontal {
scrollView.setContentOffset(CGPoint(x: scrollView.bounds.width, y: 0), animated: true)
}else{
scrollView.setContentOffset(CGPoint(x: 0, y: scrollView.bounds.height), animated: true)
}
if imgArray.count > 1 {
startTimer()
}
changeIndex()
}
// TODO: 设置自定义的代理
func configerCustom(dataSource:CycleScrollViewDataSource) {
//从新赋值代理
invailTimer()
//是自定义的
isCustom = true
lgdelegate = dataSource
lgDataSource = dataSource
//添加子控件
var num:Int = 0
for imgV in imgViews {
//移除子控件
imgV.subviews.forEach { (v) in
v.removeFromSuperview()
}
let subV = dataSource.cycleCustomView(index: num, cycleScrollView: self)
//添加到控件上
imgV.addSubview(subV)
num = num + 1
}
layoutSubviews()
if imgArray.count > 1 {
startTimer()
}
changeIndex()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.addSubview(scrollView)
scrollView.delegate = self
self.isUserInteractionEnabled = true
imgArray = []
pageControl.currentPage = index
pageControl.currentPageIndicatorTintColor = .red
pageControl.pageIndicatorTintColor = .lightGray
pageControl.isUserInteractionEnabled = false
pageControl.numberOfPages = imgArray.count
for _ in 0..<3 {
let imgV = UIImageView()
imgV.contentMode = .scaleAspectFill
imgV.clipsToBounds = true
imgViews.append(imgV)
scrollView.addSubview(imgV)
imgV.isUserInteractionEnabled = false
}
let tap = UITapGestureRecognizer(target: self, action: #selector(tapImgViewAction))
//滚动视图上添加手势
scrollView.addGestureRecognizer(tap)
addSubview(pageControl)
changeIndex()
startTimer()
}
@objc func tapImgViewAction(tap:UITapGestureRecognizer){
if tap.state == .ended {
//点击结束
if imgArray.count > 0 {
lgdelegate?.cycleDidTapWithIndex?(page: index, cycleScrollView: self)
}
}
}
//设置占位图
func configerPlacehoder(placeImg:UIImage) -> Void {
placehodeImg = placeImg
self.image = placeImg
}
//设置图片数组
func configerImgs(imgs:Array<Any>) {
imgArray = imgs
pageControl.numberOfPages = imgArray.count
invailTimer()
if imgArray.count > 1 {
if isHiddenPage == false {
pageControl.isHidden = false
}
startTimer()
scrollView.isScrollEnabled = true
}else{
scrollView.isScrollEnabled = false
if imgArray.count == 0 {
pageControl.isHidden = true
self.image = placehodeImg
self.clipsToBounds = true
self.contentMode = .scaleAspectFit
//图片全部滞空
for v in imgViews {
v.image = nil
}
}else{
self.image = nil
pageControl.isHidden = false
}
}
//修改索引值
index = 0
changeIndex()
}
private func startTimer(){
//先销毁定时器
invailTimer()
//启动定时器
_timer = Timer(timeInterval: 2, target: self, selector: #selector(onTimeAction), userInfo: nil, repeats: true)
RunLoop.current.add(_timer!, forMode: .commonModes)
}
private func invailTimer(){
_timer?.invalidate()
_timer = nil
}
//定时器调用
func onTimeAction(){
//当前应当是第几张
if scrollType == .Horizontal {
scrollView.setContentOffset(CGPoint(x: scrollView.bounds.width*2, y: 0), animated: true)
}else{
scrollView.setContentOffset(CGPoint(x: 0, y: scrollView.bounds.height*2), animated: true)
}
}
//TODO: 修改索引值 关键代码
func changeIndex() {
if imgArray.count <= 0 {
scrollView.isHidden = true
return
}
scrollView.isHidden = false
pageControl.currentPage = index
//这里没写完呢!
let imgName1 = (index == 0) ? (imgArray.last ?? "") : imgArray[index - 1]
let imgName2 = (imgArray.count == 1) ? (imgArray.first ?? "") : ((imgArray.count > 0) ? imgArray[index] : "")
let imgName3 = (index == imgArray.count - 1) ? (imgArray.first ?? "") : ( (imgArray.count == 1) ? (imgArray.first ?? ""):imgArray[index + 1])
let imgV1 :UIImageView = imgViews[0]
let imgV2 :UIImageView = imgViews[1]
let imgV3 :UIImageView = imgViews[2]
if isCustom {
//修改占位图
self.image = nil
lgDataSource?.cycleCustomViewConfigerData(currentView: imgV1.subviews.first!, data: imgName1)
lgDataSource?.cycleCustomViewConfigerData(currentView: imgV2.subviews.first!, data: imgName2)
lgDataSource?.cycleCustomViewConfigerData(currentView: imgV3.subviews.first!, data: imgName3)
return
}
let str1 = imgName1 as! String
let str2 = imgName1 as! String
let str3 = imgName1 as! String
//是否是不是http 开头 的
if str1.hasPrefix("http") {
imgV1.sd_setImage(with: URL(string: imgName1 as! String), completed: nil)
}else{
imgV1.image = UIImage(named: str1)
}
if str2.hasPrefix("http") {
imgV2.sd_setImage(with: URL(string: imgName2 as! String), completed: nil)
}else{
imgV2.image = UIImage(named: str2)
}
if str3.hasPrefix("http") {
imgV3.sd_setImage(with: URL(string: imgName3 as! String), completed: nil)
}else{
imgV3.image = UIImage(named: str3)
}
lgdelegate?.cycleDidScrollPage?(page: index, cycleScrollView: self)
}
//TODO: 滚动视图代理方法
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
invailTimer()
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if scrollType == .Horizontal {
scrollView.contentOffset = CGPoint(x: scrollView.bounds.width, y: 0)
}else{
scrollView.contentOffset = CGPoint(x: 0, y: scrollView.bounds.height)
}
changeIndex()
startTimer()
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollType == .Horizontal { //横向滚动
if scrollView.contentOffset.x >= scrollView.bounds.width*2 {
scrollView.contentOffset = CGPoint(x: scrollView.bounds.width, y: 0)
index = index + 1
if index > ( imgArray.count - 1) {//回到起点
index = 0
}
changeIndex()
}else if scrollView.contentOffset.x <= 0{
scrollView.contentOffset = CGPoint(x: scrollView.bounds.width, y: 0)
index = index - 1
if index < 0 {
index = ( imgArray.count - 1)
}
changeIndex()
}
}else{
if scrollView.contentOffset.y >= scrollView.bounds.height*2 {
scrollView.contentOffset = CGPoint(x: 0, y: scrollView.bounds.height)
index = index + 1 //回到起点
if index > ( imgArray.count - 1) {
index = 0
}
changeIndex()
}else if scrollView.contentOffset.y <= 0{
scrollView.contentOffset = CGPoint(x: 0, y: scrollView.bounds.height)
index = index - 1
if index < 0 {
index = ( imgArray.count - 1)
}
changeIndex()
}
}
}
override func layoutSubviews() {
super.layoutSubviews()
let arrayCount = 3
scrollView.frame = CGRect(x: 0, y: 0, width: self.bounds.width, height: self.bounds.height)
pageControl.frame = CGRect(x: 0, y: self.bounds.height - 12.0, width: self.bounds.width, height: 10)
if scrollType == .Horizontal {
let containtWidth = self.bounds.width * CGFloat(arrayCount)
scrollView.contentSize = CGSize(width: containtWidth, height: 0)
scrollView.contentOffset = CGPoint(x: scrollView.bounds.width, y: 0)
for i in 0..<imgViews.count {
let v = imgViews[i]
v.frame = CGRect(x: self.bounds.width * CGFloat(i), y: 0, width: self.bounds.width, height: self.bounds.height)
if isCustom == true {
v.subviews.forEach { (subV) in //如果是自定义View 修改自定义Viewframe
subV.frame = CGRect(x: 0, y: 0, width: v.bounds.width, height: bounds.height)
}
}
}
}else{
let containtHeight = self.bounds.height * CGFloat(arrayCount)
scrollView.contentSize = CGSize(width:self.bounds.width, height: containtHeight)
scrollView.contentOffset = CGPoint(x: scrollView.bounds.height, y: 0) //放到中间
for i in 0..<imgViews.count {
let v = imgViews[i]
v.frame = CGRect(x: 0, y: self.bounds.height * CGFloat(i), width: self.bounds.width, height: self.bounds.height)
if isCustom == true { //如果是自定义View 修改自定义Viewframe
v.subviews.forEach { (subV) in
subV.frame = CGRect(x: 0, y: 0, width: v.bounds.width, height: bounds.height)
}
}
}
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//TODO: 懒加载 ====================
lazy var scrollView = {()->UIScrollView in
let scrollV = UIScrollView()
scrollV.isPagingEnabled = true
scrollV.showsVerticalScrollIndicator = false
scrollV.showsHorizontalScrollIndicator = false
return scrollV
}()
lazy var pageControl = {() -> UIPageControl in
let page = UIPageControl()
return page
}()
//TODO: 设置set 方法
var isHiddenPageControl:Bool{
get {
return isHiddenPage
}
set {
isHiddenPage = newValue
pageControl.isHidden = isHiddenPage
}
}
}
let cycleScrollView = CycleScrollView.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
cycleScrollView.lgdelegate = self
//cycleScrollView.configerCustom(dataSource: self)
//是否隐藏 pageControl
cycleScrollView.isHiddenPageControl = true
tableHeader.addSubview(cycleScrollView)
cyScrollView = cycleScrollView
cycleScrollView.snp.makeConstraints { (make) in
make.left.right.top.bottom.equalTo(0)
}
cycleScrollView.configerPlacehoder(placeImg: UIImage(named: "home_banner_img") ?? UIImage())
cycleScrollView.configerScrollType(aScrollType: .Horizontal)
//必须实现的自定义代理方法
func cycleCustomView(index: Int, cycleScrollView: CycleScrollView) -> UIView {
let v = CustomCyItem()
return v;
}
func cycleCustomViewConfigerData(currentView: UIView, data: Any) {
let v:CustomCyItem = currentView as! CustomCyItem
v.titleLable.text = data as? String
}
//协议方法
func cycleDidTapWithIndex(page: Int, cycleScrollView: CycleScrollView) {
//LGLog("点击了第" + String(page) + "页")
}
func cycleDidScrollPage(page: Int, cycleScrollView: CycleScrollView) {
//LGLog("滚动到第" + String(page) + "页")
}
网友评论