JXBanner 0.3.6

JXBanner 0.3.6

bboyXFX维护。



JXBanner 0.3.6

  • 作者
  • Code_TanJX

JXBanner

CI Status Version License Platform

(JXBanner 支持多种动画变换,包括纯代码布局和 Xib 布局)

JXBanner 依赖于 JXPageConytrol,并包含许多自定义接口,如变换动画、视图结构和设置


 

(如果有什么问题,可以留言,欢迎共同学习,欢迎 star )


安装

为了安装,只需将以下代码添加到 podfile

platform :ios, '8.0'

target 'TargetName' do
pod 'JXBanner'
end

UI 效果

  • middleTarget

添加控制代理方法到中心 Cell (当中心 Cell 显示/离开中心时:开发者可以使用自定义动作,例如中间 Cell,在离开中心时播放和停止视频)


  • scrollView

您需要设置 jxbannerparams->isPagingEnabled(false) 和 isAutoPlay(false)


  • 默认

您不需要设置 JXBanner-> JXBannerLayoutParams


  • JXBannerTransformLinear

---
  • JXBannerTransformCoverflow

---
  • 自定义

需要实现 JXBannerTransformable 协议,修改 UICollectionViewLayoutAttributes -> "transform3D" 或 "transform" 属性

---

框架设置

 

轮播图【旋转中的图框架的公共类文件】
  • API ---> 开发者可以调用的所有接口
  • Cell ---> 框架提供的单元格基类(如果需要自定义单元格内容,创建一个新的继承自 UICollectionViewCell 的单元格)
  • Common ---> 框架的常用类文件
  • Transform ---> 动画类文件(如果框架提供的动画效果无法满足开发者的需求,可以创建新的符合 JXBannerTransformable 协议的结构体/类,修改 UICollectionViewLayoutAttributes -> transform3D 或 transform 属性)
PageControl -- 指示器类文件
  • JXBannerPageControlBuilder ---> pageControl 的构建器类
  • JXBannerPageControlDefault ---> 默认的 pageControl 样式框架(可以通过 JXBannerDataSource -> 【 jxBanner (pageControl banner: numberOfPages: coverView: builder:) -> JXBannerPageControlBuilder 】 协议方法修改样式)

JXBanner : 重要的文档介绍

 

JXBannerParams 【轮播图基本属性】
  • isAutoPlay ---> 自动播放
  • isBounces ---> 是否可以超出边界滑动
  • isShowPageControl ---> 是否显示内部载入指示器(JXPageControl(框架功能)
  • timeInterval ---> 播放调度间隔
  • isPagingEnabled ---> 页面滚动模式
  • contentInset ---> 设置内边距
  • cycleWay ---> 循环模式(框架功能)(正向:无线右播放,skipEnd:从头到尾自定义动画跳转,rollingBack:左右滚动模式)
  • edgeTransitionType ---> CycleWay使用skipEnd来选择如何动画处理
  • edgeTransitionSubtype ---> CycleWay使用skipEnd来选择如何动画处理

JXBannerLayoutParams 【轮播布局,动画属性】
  • itemSize ---> 单元格大小。
  • itemSpacing ---> 单元格左右边距。
  • layoutType ---> 动画效果JXBannerTransformable(框架功能)
  • minimumScale ---> 单元格缩放因子。
  • minimumAlpha ---> 单元格透明系数。
  • maximumAngle ---> 单元格旋转系数。
  • rateOfChange ---> 单元格变化系数。
  • rateHorisonMargin ---> 单元格水平间距调整因子。

JXBannerCellRegister 【单元格注册构建器】
  • type ---> 要注册单元格类型,您必须是UICollectionViewCell的子类,当您不使用nib单元格文件时,您必须将'type'设置为单元格类!!
  • reuseIdentifier ---> 单元格重用标识符。如果您在您的应用程序中使用多个jxbanners,请设置不同的值以方便区分
  • nib ---> 当使用nib单元格文件时,必须进行nib参数赋值!!!
暂停或恢复自动滚动
let banner = JXBanner(frame: .zero)

// Pause
banner.pauseAutoScrolling()

// Resume
banner.resumeAutoScrolling()

JXBanner使用

 

示例 1
  • 默认实现示例

 


import SnapKit
import JXBanner

class JXDefaultVC: UIViewController {

    var pageCount = 5

    lazy 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: UICollectionViewCell)
        -> UICollectionViewCell {
            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)
    }

}



示例 2

 

  • 个性化设置

import SnapKit
import JXBanner
import JXPageControl

class JXCustomVC: UIViewController {

    var pageCount = 5

    lazy 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: UICollectionViewCell)
        -> UICollectionViewCell {
            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)
    }
}

示例 3

如果框架提供的动画不符合开发者的需求:

  • 1.旋转图动画风格的开发者可自定义实现,只要是一个新的实现 JXBannerTransformable 协议/类,修改 UICollectionViewLayoutAttributes -> transform3D 或 transform 属性

//
//  JXCustomTransform.swift
//  JXBanner_Example
//
//  Created by Coder_TanJX on 2019/7/30.
//  Copyright © 2019 CocoaPods. All rights reserved.
//

import UIKit
import JXBanner

struct 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 = CATransform3DIdentity


        let 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 = 0

        switch 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
    }

}


    1. 设置自定义实现动画

JXBannerDataSource -> 【jxBanner(_ banner: layoutParams: ) -> JXBannerLayoutParams】


// JXCustomTransform()

    func jxBanner(_ banner: JXBannerType,
        layoutParams: JXBannerLayoutParams)
        -> JXBannerLayoutParams {

        return layoutParams
            .layoutType(JXCustomTransform())
    }

查看更多示例 Demo地址

作者

Methods-TanJX, [email protected]

许可证

JXBanner 计可使用 MIT 许可证。更多信息请参阅 LICENSE 文件。