CNCustomIndexView.swift 13.7 KB
//
//  CNCustomIndexView.swift
//  metaCode
//
//  Created by daojian on 2023/5/31.
//

import Foundation

typealias closeBlock = ()->Void;

class CNCustomIndexTopView : UIView{
    ///关闭按钮事件回调
    var closeAction: closeBlock?
    
    
    //MARK: - 懒加载
    ///标题
    lazy var titleLabel: UILabel = {
        let titleLabel = UILabel.init(frame: CGRectMake(10, 0, 75, 35))
        titleLabel.bottom = self.bottom - 5
        titleLabel.textColor = .white
        titleLabel.font = UIFont.systemFont(ofSize: 24, weight: .semibold)
        return titleLabel
    }()
    ///关闭按钮
    lazy var closeBtn: UIButton = {
        let  closeBtn = UIButton(type: .custom)
        closeBtn.frame = CGRect(x: self.width - 30, y: 0, width: 30, height: 30)
        closeBtn.centerY = self.titleLabel.centerY
        closeBtn.setImage(UIImage(named: "homePage_close_icon"), for: .normal)
        closeBtn.addTarget(self, action: #selector(closeBtnAction), for: .touchUpInside)
        return closeBtn
    }()
    //MARK: - 初始化
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.initUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func initUI(){
        self.addSubview(self.titleLabel)
        self.addSubview(self.closeBtn)
    }
    
    //MARK: - 公开方法
    public func setTitleString(title:String)->Void{
        self.titleLabel.text = title
    }
    
    //MARK: - 事件
    @objc func closeBtnAction(){
        closeAction?()
    }
}


protocol CNCustomIndexViewDelegate:NSObjectProtocol{
    /// 当前scrollView  将要开始滚动
    func customIndexViewWillBeiginScroll(scrollView :UIScrollView);
    ///当前scrollView 滚动中
    func customIndexViewDidScroll(scrollView :UIScrollView);
    ///当前scrollView 已经结束滚动
    func customIndexViewDidEndScroll(scrollView :UIScrollView);

}

class CNCustomIndexView:PGIndexBannerSubiew, UIScrollViewDelegate, WJColorChangeDelegate{
   
    ///记录开始拖拽时偏移量
    var beginDragOffset: CGFloat = 0.0
    
    ///颜色管理
    var colorChange: WJColorChange!
    
    ///代理
    weak var delegate:CNCustomIndexViewDelegate?
    
    ///关联的控制器的view
    weak var associatedVCView:UIView?
    {
       
        willSet
        {
            print("Will set an new value \(String(describing: newValue)) to age")
        }
        //我们需要在age属性发生变化后,更新一下nickName这个属性
        didSet
        {
            self.addColorManager()
        }
    }
    ///父视图ScrollView
    weak var superScrollView:UIScrollView?
    
    // MARK: - 懒加载
    
    ///颜色数据
    lazy var colorDataArr: NSMutableArray = {
        let colorDataArr = NSMutableArray(array: NSArray(objects: UIColor.white,KVCBackgroupColor!,UIColor("#004FE0")!))
        
        return colorDataArr
    }()
    
    ///自己的ScrollView,用来装载子视图
    lazy var baseScrollView:UIScrollView = {
        let baseScrollView : UIScrollView = UIScrollView.init(frame: CGRect(x: 0, y: 0, width: self.width, height: self.height))
        baseScrollView.contentSize = CGSizeMake(self.frame.size.width, self.frame.size.height*3) 
        baseScrollView.delegate = self 
        baseScrollView.bounces = false 
        baseScrollView.isPagingEnabled = true 
        baseScrollView.clipsToBounds = false 
        baseScrollView.showsHorizontalScrollIndicator = false 
        baseScrollView.showsVerticalScrollIndicator = false 
        if #available(iOS 11.0, *) {
            //系统版本高于11.0
            baseScrollView.contentInsetAdjustmentBehavior = .never 

        } else {
            //系统版本低于11.0
            baseScrollView.automaticallyAdjustsScrollIndicatorInsets = false 
        }
        return baseScrollView

    }()
    
    ///中间主界面
    lazy var mainView:CNMainView = {
        let W = self.width 
        let H = W*1.5
        let mainView = CNMainView.init(frame: CGRectMake(0, self.frame.size.height + KSreenHeight*0.16,W, H))
        return mainView
    }()
    
    ///下滑显示的VIew
    lazy var downSlideView: CNDownSlideView = {
        let collectionView = CNDownSlideView.init(frame: CGRectMake(-25, 0, self.frame.size.width + 50, self.frame.size.height))
        collectionView.backAction = {[weak self] in
            self?.baseScrollView.setContentOffset(CGPoint(x: 0, y: (self!.baseScrollView.height)), animated: true)
            self?.superScrollView?.isScrollEnabled = true
            
            let time = DispatchTime.now() + 0.5
            DispatchQueue.main.asyncAfter(deadline:time, execute: DispatchWorkItem(block: {
                //下滑提醒View回到初始位置
                self?.downSlideViewRemindView.top = -((self?.downSlideViewRemindView.height)! + 50)
            }))
           
        }
        return collectionView
    }()
    
    ///上滑显示的View
    lazy var upSlideView : CNUpSlideView = {
        let upSlideView = CNUpSlideView(frame: CGRectMake(-25, self.frame.size.height*2 + 120,self.frame.size.width+50, self.frame.size.height - 120))
        
        return upSlideView
    }()
    
    ///上滑提醒view
    lazy var upSlideViewRemindView: CNUpSlideViewRemindView = {
        let W: CGFloat = UIScreen.main.bounds.width-100
        let H: CGFloat = W/2
        let bottomView = CNUpSlideViewRemindView.init(frame: CGRectMake(25, self.height, W,H))
        bottomView.backgroundColor = UIColor.clear 
        return bottomView
    }()
    /// 下滑提醒view
    lazy var downSlideViewRemindView:CNDownSlideViewRemindView = {
        let W: CGFloat = UIScreen.main.bounds.width-100
        let H: CGFloat = W/2
        let topView = CNDownSlideViewRemindView.init(frame: CGRectMake(25, -H - 50, W,H))
        topView.backgroundColor = .clear
        
        return topView
    }()
    
    /// 顶部自定义导航
    lazy var topNavView: CNCustomIndexTopView = {
        let topNavView = CNCustomIndexTopView.init(frame: CGRect(x: 0, y: 0, width: self.width, height: KNavigationHeight))
        topNavView.alpha = 0
        topNavView.closeAction = { [weak self ] in
            self!.baseScrollView.setContentOffset(CGPoint(x: 0, y: self!.baseScrollView.height), animated: true)
            self?.superScrollView?.isScrollEnabled = true
        }
        return topNavView
    }()
    
    // MARK: - 初始化方法
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.initUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // MARK: - 添加UI
    func initUI(){
        self.addSubview(self.upSlideViewRemindView)
        self.addSubview(self.downSlideViewRemindView)

        self.addSubview(self.baseScrollView)
        self.addSubview(self.topNavView)
        self.topNavView.setTitleString(title: "志愿者")
        
        self.baseScrollView.addSubview(self.downSlideView)
        self.baseScrollView.addSubview(self.mainView)
        self.baseScrollView.addSubview(self.upSlideView)
        
        //默认偏移到中间
        self.baseScrollView.setContentOffset(CGPointMake(0, self.frame.size.height), animated: false)
    }
    
//    func addCustomGestureRecognizer(){
//        let singleTap: UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(singleCellTapAction))
//
//        self.addGestureRecognizer(singleTap)
//    }
    
    // MARK: - 设置颜色值跟随ScrollView滑动变化
    func addColorManager()
    {
        print(self.colorDataArr)
        let colorChange:WJColorChange = WJColorChange.init(type:SingleColor)
        colorChange.delegate = self 
        colorChange.offset = 100 
        colorChange.settingScrollView(self.baseScrollView, colorArray: self.colorDataArr as! [UIColor], needChangeColorView: self.associatedVCView)
        
        self.colorChange = colorChange
    }
    
    // MARK: - WJColorChange代理
    ///将要开始拖拽滚动
    func wjColorScrollViewWillBeginDragging(_ scrollView: UIScrollView!) {
        
        self.beginDragOffset = scrollView.contentOffset.y
        
        self.delegate?.customIndexViewWillBeiginScroll(scrollView: scrollView)
        
        //开始滑动把 baseScrollView 放到导航的上层
        self.bringSubviewToFront(self.baseScrollView)
        
        
    }
    
    ///WJColorChange 代理方法 滚动时候回调 传出当前的滚动视图
    func wjColorScrollViewScroll(_ scrollView: UIScrollView!) {
        
        let tag: NSInteger = self.tag 
        let defaultOffset: CGFloat = self.frame.size.height 
        
        let currentOffset: CGFloat = scrollView.contentOffset.y 
        
        /**隐藏左右view*/
        let fabsOffset: CGFloat = abs(defaultOffset - currentOffset)
        
        let leftView:UIView? = self.superScrollView?.viewWithTag(tag-1) 
        let rightView:UIView? = self.superScrollView?.viewWithTag(tag+1)
        if fabsOffset > 70 {
            leftView?.alpha = 0
            rightView?.alpha = 0
        }
        else{
            leftView?.alpha = (70-fabsOffset)/70.00
            rightView?.alpha = (70-fabsOffset)/70.00
        }
        
        //当self.baseScrollView的偏移量大于 self.baseScrollView.height时,显示上滑提醒view
        if(currentOffset > self.baseScrollView.height){
            self.upSlideViewRemindView.top =  self.height - (currentOffset - self.baseScrollView.height)*1.5
        }
        //上滑滑动到临近值,让upSlideViewRemindView位置一直停留在底部,并慢慢消失
        if (self.upSlideViewRemindView.top < self.height - self.upSlideViewRemindView.height) {
            /**让upSlideViewRemindView位置一直停留在底部*/
            self.upSlideViewRemindView.top = self.height - self.upSlideViewRemindView.height
            
            /**渐渐隐藏upSlideViewRemindView,缓冲距离为20*/
            let upSlideViewRemindViewMaxOffset: CGFloat = self.baseScrollView.height+self.upSlideViewRemindView.height
            self.upSlideViewRemindView.alpha = (20-(currentOffset - upSlideViewRemindViewMaxOffset))/20.00
            
        }
        
        //当self.baseScrollView的偏移量小于 self.baseScrollView.height时,显示下滑提醒view
        if(currentOffset < self.baseScrollView.height){
            self.downSlideViewRemindView.bottom = (self.baseScrollView.height - currentOffset)*1.5
        }
        //下滑滑动到临近值,让downSlideViewRemindView位置一直停留在顶部,并慢慢消失
        if (self.downSlideViewRemindView.bottom > self.downSlideViewRemindView.height) {
            
            /**让downSlideViewRemindView位置一直停留在底部*/
            self.downSlideViewRemindView.bottom = self.downSlideViewRemindView.height

            /**渐渐隐藏downSlideViewRemindView,缓冲距离为20*/
            let downSlideViewRemindViewMinOffset: CGFloat = self.baseScrollView.height-self.downSlideViewRemindView.height
            self.downSlideViewRemindView.alpha = (20-(downSlideViewRemindViewMinOffset - currentOffset))/20.00
            
            //让系统及时更新downSlideViewRemindView
//            self.downSlideViewRemindView.setNeedsLayout()
//            self.downSlideViewRemindView.layoutIfNeeded()
        }
        
        
        /**控制缩放范围在一定范围*/
//        let mainViewOffset:CGFloat = abs(currentOffset - self.baseScrollView.height)
//        if (mainViewOffset < 100) {
//            var scale: CGFloat = 1.0
//            
//            if (currentOffset < self.baseScrollView.height) {
//                //下滑时,计算scale方法
//                scale = currentOffset/self.baseScrollView.height
//            }
//            else {
//                //上滑时,计算scale方法
//                scale = self.baseScrollView.height/currentOffset
//            }
//
//            self.mainView.scaledView(scale: scale)
//        }
        
        /**隐藏顶部导航**/
        let topNavViewAlpha: CGFloat = 1.0 - (self.baseScrollView.height * 2 - currentOffset)/(self.baseScrollView.height*0.5)
        if(topNavViewAlpha > 0){
            self.topNavView.alpha = topNavViewAlpha
        }
        else{
            self.topNavView.alpha = 0
        }
    
        //隐藏downSlideView的bottomView
        if scrollView.contentOffset.y > 10{
            self.downSlideView.bottomView.isHidden = true
            self.downSlideView.contentView.backgroundColor = .clear
        }
        
        delegate?.customIndexViewDidScroll(scrollView: self.baseScrollView)
        
    }
    
    ///WJColorChange 代理方法 滚动结束时候回调
    func wjColorEndScroll(_ scrollView: UIScrollView!) {
        
        
        let defaultOffset: CGFloat = self.frame.size.height
        
        let currentOffset: CGFloat = scrollView.contentOffset.y
        
        if ((currentOffset < (defaultOffset + 1))  &&
            (currentOffset > (defaultOffset - 1))
            ) {
            self.superScrollView?.isScrollEnabled = true
        }
        else{
            self.superScrollView?.isScrollEnabled = false
        }
        
        
        if scrollView.contentOffset.y == 0{
            //滚动到第一页,显示downSlideView的底部view
            self.downSlideView.bottomView.isHidden = false
            self.downSlideView.contentView.backgroundColor = KVCBackgroupColor
        }
        
        
        //滑动结束 把topNavView 放到scrollView的上层
        self.bringSubviewToFront(self.topNavView)
        
        //下滑提醒View回到初始位置
        self.downSlideViewRemindView.top = -(self.downSlideViewRemindView.height + 50)
        
        //外部代理
        self.delegate?.customIndexViewDidEndScroll(scrollView: scrollView)
    }
    
}