iOS|iOS JXBanner - (多功能无限轮播图框架)
(JXBanner 支持多种动画变换, 支持纯代码布局和Xib布局)
JXBanner依赖于JXPageControl,并包含许多自定义接口,如转换动画、视图结构和设置
-
- 开发环境: Xcode 7
-
- 运行条件: iOS(8.0+)
- 开源框架:github地址
【iOS|iOS JXBanner - (多功能无限轮播图框架)】(如果使用有什么问题,可以留言,欢迎一起学习,欢迎star)
Installation [安装]
安装,只需将以下面代码添加到您的Podfile:
platform :ios, '8.0'target 'TargetName' do
pod 'JXBanner'
end
UI效果
- default
文章图片
default.gif
- JXBannerTransformLinear
文章图片
linear.gif
- JXBannerTransformCoverflow
文章图片
coverflow.gif
- custom
文章图片
custom.gif Frame set [框架集合]
Banner 轮播图框架公用类文件
- API ---> 开发者可以调用的所有接口
- Cell ---> 框架提供cell基类 (如果想自定义cell内容, 可以新建cell继承于JXBannerBaseCell)
- Common ---> 框架公用类文件
- Transform ---> 动画效果类文件 ( 如果框架提供的动画效果不能满足开发者需求, 可以新建实现JXBannerTransformable协议的struct/class, 修改 UICollectionViewLayoutAttributes -> transform3D 或 transform 属性)
- JXBannerPageControlBuilder ---> pageControl的构建者类
- JXBannerPageControlDefault ---> 框架默认的pageControl样式 (可以通过实现JXBannerDataSource -> 【jxBanner(pageControl banner: numberOfPages: coverView: builder:) -> JXBannerPageControlBuilder】协议方法修改样式)
JXBannerParams 【banner 属性】
- isAutoPlay ---> 自动播放
- isBounces ---> 边界能否越界滑动
- timeInterval ---> 播放调度间隔
- isShowPageControl ---> 是否加载内部指示器(JXPageControl(框架特色))
- cycleWay ---> 轮播方式(框架特色) (forward:无线向右播放, skipEnd:首尾自定义动画跳转, rollingBack:左右回滚模式)
- edgeTransitionType ---> cycleWay 使用 skipEnd 中 可以选取动画方式
- edgeTransitionSubtype ---> cycleWay 使用 skipEnd 中 可以选取动画方式
- itemSize ---> cell大小。
- itemSpacing --->cell左右边距。
- layoutType ---> 动画效果JXBannerTransformable(框架特色)
- minimumScale ---> cell 缩放系数。
- minimumAlpha ---> cell 透明度系数。
- maximumAngle ---> cell 旋转系数。
- rateOfChange ---> cell 变化系数。
- rateHorisonMargin ---> cell 水平间距调整系数。
- type ---> 注册cell的类型,必须是JXBannerBaseCell的子类
- reuseIdentifier ---> cell重用标识
var type: JXBannerBaseCell.Type
var reuseIdentifier: String
Example 1
- 默认实现示例
import SnapKit
import JXBannerclass JXDefaultVC: UIViewController {var pageCount = 5lazy var banner: JXBanner = {
let banner = JXBanner()
banner.backgroundColor = UIColor.black
banner.placeholderImgView.image = UIImage(named: "banner_placeholder")
banner.delegate = self
banner.dataSource = self
return banner
}()override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(banner)
banner.snp.makeConstraints { (maker) in
maker.left.right.equalTo(view)
maker.height.equalTo(250)
maker.top.equalTo(view.snp_top).offset(100)
}
self.automaticallyAdjustsScrollViewInsets = false
}deinit {
print("\(#function) ----------> \(#file.components(separatedBy: "/").last?.components(separatedBy: ".").first ?? #file)")
}
}//MARK:- JXBannerDataSource
extension JXDefaultVC: JXBannerDataSource {// 注册重用Cell标识
func jxBanner(_ banner: JXBannerType)
-> (JXBannerCellRegister) {
return JXBannerCellRegister(type: JXBannerCell.self,
reuseIdentifier: "JXDefaultVCCell")
}// 轮播总数
func jxBanner(numberOfItems banner: JXBannerType)
-> Int { return pageCount }// 轮播cell内容设置
func jxBanner(_ banner: JXBannerType,
cellForItemAt index: Int,
cell: JXBannerBaseCell)
-> JXBannerBaseCell {
let tempCell: JXBannerCell = cell as! JXBannerCell
tempCell.layer.cornerRadius = 8
tempCell.layer.masksToBounds = true
tempCell.imageView.image = UIImage(named: "banner_placeholder")
tempCell.msgLabel.text = String(index) + "---来喽来喽,他真的来喽~"
return tempCell
}// banner基本设置(可选)
func jxBanner(_ banner: JXBannerType,
layoutParams: JXBannerLayoutParams)
-> JXBannerLayoutParams {
return layoutParams
.itemSize(CGSize(width: UIScreen.main.bounds.width - 40, height: 200))
.itemSpacing(20)
}
}//MARK:- JXBannerDelegate
extension JXDefaultVC: JXBannerDelegate {// 点击cell回调
public func jxBanner(_ banner: JXBannerType,
didSelectItemAt index: Int) {
print(index)
}}
Example 2
- 个性化设置
import SnapKit
import JXBanner
import JXPageControlclass JXCustomVC: UIViewController {var pageCount = 5lazy var linearBanner: JXBanner = {[weak self] in
let banner = JXBanner()
banner.placeholderImgView.image = UIImage(named: "banner_placeholder")
banner.backgroundColor = UIColor.black
banner.indentify = "linearBanner"
banner.delegate = self
banner.dataSource = self
return banner
}()lazy var converflowBanner: JXBanner = {
let banner = JXBanner()
banner.placeholderImgView.image = UIImage(named: "banner_placeholder")
banner.backgroundColor = UIColor.black
banner.indentify = "converflowBanner"
banner.delegate = self
banner.dataSource = self
return banner
}()override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(linearBanner)
view.addSubview(converflowBanner)
linearBanner.snp.makeConstraints {(maker) in
maker.left.right.equalTo(view)
maker.height.equalTo(200)
maker.top.equalTo(view.snp_top).offset(100)
}converflowBanner.snp.makeConstraints {(maker) in
maker.left.right.height.equalTo(linearBanner)
maker.top.equalTo(linearBanner.snp_bottom).offset(100)
}self.automaticallyAdjustsScrollViewInsets = false
}deinit {
print("\(#function) ----------> \(#file.components(separatedBy: "/").last?.components(separatedBy: ".").first ?? #file)")
}
}//MARK:- JXBannerDataSource
extension JXCustomVC: JXBannerDataSource {// 注册重用Cell标识
func jxBanner(_ banner: JXBannerType)
-> (JXBannerCellRegister) {if banner.indentify == "linearBanner" {
return JXBannerCellRegister(type: JXBannerCell.self,
reuseIdentifier: "LinearBannerCell")
}else {
return JXBannerCellRegister(type: JXBannerCell.self,
reuseIdentifier: "ConverflowBannerCell")
}
}// 轮播总数
func jxBanner(numberOfItems banner: JXBannerType)
-> Int { return pageCount }// 轮播cell内容设置
func jxBanner(_ banner: JXBannerType,
cellForItemAt index: Int,
cell: JXBannerBaseCell)
-> JXBannerBaseCell {
let tempCell: JXBannerCell = cell as! JXBannerCell
tempCell.layer.cornerRadius = 8
tempCell.layer.masksToBounds = true
tempCell.imageView.image = UIImage(named: "banner_placeholder")
tempCell.msgLabel.text = String(index) + "---来喽来喽,他真的来喽~"
return tempCell
}// banner基本设置(可选)
func jxBanner(_ banner: JXBannerType,
params: JXBannerParams)
-> JXBannerParams {if banner.indentify == "linearBanner" {
return params
.timeInterval(2)
.cycleWay(.forward)
}else {
return params
.timeInterval(3)
.cycleWay(.forward)
}
}// banner布局、动画设置
func jxBanner(_ banner: JXBannerType,
layoutParams: JXBannerLayoutParams)
-> JXBannerLayoutParams {if banner.indentify == "linearBanner" {
return layoutParams
.layoutType(JXBannerTransformLinear())
.itemSize(CGSize(width: 250, height: 190))
.itemSpacing(10)
.rateOfChange(0.8)
.minimumScale(0.7)
.rateHorisonMargin(0.5)
.minimumAlpha(0.8)
}else {
return layoutParams
.layoutType(JXBannerTransformCoverflow())
.itemSize(CGSize(width: 300, height: 190))
.itemSpacing(0)
.maximumAngle(0.25)
.rateHorisonMargin(0.3)
.minimumAlpha(0.8)
}
}// 自定义pageControl样式、布局
//(基于jxPageControl, 如果不适用JXPageControl, 设置isShowPageControl = false, 内部pageControl将不会再次加载 )
func jxBanner(pageControl banner: JXBannerType,
numberOfPages: Int,
coverView: UIView,
builder: JXBannerPageControlBuilder) -> JXBannerPageControlBuilder {if banner.indentify == "linearBanner" {
let pageControl = JXPageControlScale()
pageControl.contentMode = .bottom
pageControl.activeSize = CGSize(width: 15, height: 6)
pageControl.inactiveSize = CGSize(width: 6, height: 6)
pageControl.activeColor = UIColor.red
pageControl.inactiveColor = UIColor.lightGray
pageControl.columnSpacing = 0
pageControl.isAnimation = true
builder.pageControl = pageControl
builder.layout = {
pageControl.snp.makeConstraints { (maker) in
maker.left.right.equalTo(coverView)
maker.top.equalTo(coverView.snp_bottom).offset(10)
maker.height.equalTo(20)
}
}
return builder}else {
let pageControl = JXPageControlExchange()
pageControl.contentMode = .bottom
pageControl.activeSize = CGSize(width: 15, height: 6)
pageControl.inactiveSize = CGSize(width: 6, height: 6)
pageControl.activeColor = UIColor.red
pageControl.inactiveColor = UIColor.lightGray
pageControl.columnSpacing = 0
builder.pageControl = pageControl
builder.layout = {
pageControl.snp.makeConstraints { (maker) in
maker.left.right.equalTo(coverView)
maker.top.equalTo(coverView.snp_bottom).offset(10)
maker.height.equalTo(20)
}
}
return builder
}}}//MARK:- JXBannerDelegate
extension JXCustomVC: JXBannerDelegate {// 点击cell回调
public func jxBanner(_ banner: JXBannerType,
didSelectItemAt index: Int) {
print(index)
}// 设置自定义覆盖View, 比如添加自定义外部pageControl和布局
func jxBanner(_ banner: JXBannerType, coverView: UIView) {
let title = UILabel()
title.frame = CGRect(x: 0, y: 0, width: 100, height: 30)
title.text = "JXBanner"
title.textColor = UIColor.red
title.font = UIFont.systemFont(ofSize: 16)
coverView.addSubview(title)
}// 最中心显示cell 索引
func jxBanner(_ banner: JXBannerType, center index: Int) {
print(index)
}
}
Example 3 如果框架提供的动画效果不能满足开发者需求:
-
- 轮播图动画样式开发者可以自定义实现, 只要是新建实现JXBannerTransformable协议的struct/class, 修改 UICollectionViewLayoutAttributes -> transform3D 或 transform 属性)
//
//JXCustomTransform.swift
//JXBanner_Example
//
//Created by 谭家祥 on 2019/7/30.
//Copyright ? 2019 CocoaPods. All rights reserved.
//import UIKit
import JXBannerstruct JXCustomTransform: JXBannerTransformable {public func transformToAttributes(collectionView: UICollectionView,
params: JXBannerLayoutParams,
attributes: UICollectionViewLayoutAttributes) {let collectionViewWidth = collectionView.frame.width
if collectionViewWidth <= 0 { return }let centetX = collectionView.contentOffset.x + collectionViewWidth * 0.5;
let delta = abs(attributes.center.x - centetX)
let calculateRate = 1 - delta / collectionViewWidth
let angle = min(delta / collectionViewWidth * (1 - params.rateOfChange), params.maximumAngle)
let alpha = max(calculateRate, params.minimumAlpha)applyCoverflowTransformToAttributes(viewCentetX: centetX,
attributes: attributes,
params: params,
angle: angle,
alpha: alpha,
calculateRate: calculateRate)
}func applyCoverflowTransformToAttributes(viewCentetX: CGFloat,
attributes: UICollectionViewLayoutAttributes,
params: JXBannerLayoutParams,
angle: CGFloat,
alpha: CGFloat,
calculateRate: CGFloat) -> Void {
var transform3D: CATransform3D = CATransform3DIdentitylet location = JXBannerTransfrom.itemLocation(viewCentetX: viewCentetX,
itemCenterX: attributes.center.x)var _angle = angle
var _alpha = alpha
var _translateX: CGFloat = 0
var _translateY: CGFloat = 0
attributes.zIndex = 0switch location {
case .left:
_angle = angle
_translateX = 0.2 * attributes.size.width * (1 - calculateRate) / 4
_translateY = 0.4 * attributes.size.height * (1 - calculateRate)case .right:
_angle = -angle
_translateX = -0.2 * attributes.size.width * (1 - calculateRate) / 4
_translateY = 0.4 * attributes.size.height * (1 - calculateRate)case .center:
_angle = 0
_alpha = 1
_translateY = 0
attributes.zIndex = 10000
}transform3D = CATransform3DTranslate(transform3D, _translateX, _translateY, 0)
transform3D = CATransform3DRotate(transform3D, -CGFloat.pi * _angle, 0, 0, 1)
attributes.alpha = _alpha
attributes.transform3D = transform3D
}}
-
- 设置自定义实现动画
// JXCustomTransform()func jxBanner(_ banner: JXBannerType,
layoutParams: JXBannerLayoutParams)
-> JXBannerLayoutParams {return layoutParams
.layoutType(JXCustomTransform())
}
更多设置可以参考示例 Demo地址
推荐阅读
- 2020-04-07vue中Axios的封装和API接口的管理
- iOS中的Block
- 记录iOS生成分享图片的一些问题,根据UIView生成固定尺寸的分享图片
- 2019-08-29|2019-08-29 iOS13适配那点事
- Hacking|Hacking with iOS: SwiftUI Edition - SnowSeeker 项目(一)
- iOS面试题--基础
- 接口|axios接口报错-参数类型错误解决
- iOS|iOS 笔记之_时间戳 + DES 加密
- iOS,打Framework静态库
- 常用git命令总结