iOS swift 分页显示 pageView

0:代码简单 1分钟看完
1:乱点击不会产生错乱
2:可自行控制显示的时机 分为拖到一半加载 和 点击加载
3:并未进行分装 
4:如果你有时间分装一下,非常感谢

//
//  ViewController.swift
//  Secret
//
//  Created by point on 18/1/9.
//  Copyright © 2018年 dacai. All rights reserved.
//
import UIKit
import SnapKit


private let DCWidth = UIScreen.main.bounds.width //全部的宽
private let DCHeight = UIScreen.main.bounds.height //全部的高

/*  配置项 */
private let labelSize:CGFloat = 17 //字体的大小
private let titleViewMargin:CGFloat = 30 //字间距
private let titleViewHeight:CGFloat = 44 //标题高度
private let titles = ["1111", "2222", "bbbb趣", "hhh女", "值jjjj", "hhh女", "值jjjj"]
private let titlesID = ["100","1000","1000","33","33"]
private let normalColor: UIColor = UIColor(r: 0, g: 0, b: 0) //文字未选中的颜色
private let selectColor: UIColor = UIColor(r: 255, g: 127, b: 0) //文字选中的颜色
private let average:Bool = false //是否平均分配
private let botoomLineViewHeight:CGFloat = 2 //底线的高
private let botoomLineViewWidth:CGFloat = 50 //底线的宽
private let botoomLineViewColor:UIColor = UIColor.blue  //底线的颜色
private var isForbidScroll:Bool = false //点击禁止滚动
private var half:Bool = false //拖动到一半


class ViewController: UIViewController {
    //标题scroolView
    lazy var titleScrollView : UIScrollView = {
        return UIScrollView()
    }()
    //内容scroolView
    lazy var contentScrollView : UIScrollView = {
        return UIScrollView()
    }()
    //底部线条
    lazy var buttomView : UIView = {
        let buttomView = UIView()
        buttomView.backgroundColor = botoomLineViewColor
        return buttomView
    }()
    //当前布局最后一个label
    private var layoutLastLabel:UILabel = UILabel()
    //当前选择的Label
    var selLabel : UILabel = UILabel()
    //标题数组
    private lazy var titleLabels : [UILabel] = [UILabel]()
    //vc的高度
    private let vcHeight = DCHeight - 20 - titleViewHeight
    private var startOffsetX:CGFloat = 0  //拖拽前的偏移量
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.white
        setupChildViewController()
        setupUI()
        setUpTitleLabel()
    }
}


// MARK:- 设置UI
extension ViewController {
    
    //加载控制器
    fileprivate func setupChildViewController(){
        for (i,val) in titles.enumerated() {
            let workVc : OneViewController = OneViewController()
            workVc.title = val
            addChildViewController(workVc)
            
            //全部加载
            let offsetX = CGFloat(i) * DCWidth;
            let vc:UIViewController = self.childViewControllers[i];
            guard !vc.isViewLoaded else {
                return
            }
            vc.view.frame = CGRect(x:offsetX, y:0,width:DCWidth,height: vcHeight);
            contentScrollView.addSubview(vc.view)
            
        }
    }
    
    //加载UI
    fileprivate func setupUI(){
        //头部
        view.addSubview(titleScrollView)
        view.addSubview(contentScrollView)
        titleScrollView.addSubview(buttomView)
        titleScrollView.frame = CGRect(x: 0, y: 20, width: DCWidth, height: titleViewHeight)
        self.titleScrollView.showsHorizontalScrollIndicator = false
        titleScrollView.backgroundColor = UIColor.white
        
        //底部
        contentScrollView.frame = CGRect(x: 0, y: titleViewHeight + 20, width: DCWidth, height: DCHeight - titleViewHeight)
        contentScrollView.contentSize = CGSize(width:CGFloat(self.childViewControllers.count) * DCWidth, height:0);
        contentScrollView.showsHorizontalScrollIndicator = false
        contentScrollView.isPagingEnabled = true
        contentScrollView.bounces = false
        contentScrollView.backgroundColor = UIColor.white
        contentScrollView.delegate = self
        
        
        
    }
    
    //设置Label
    fileprivate func setUpTitleLabel () {
        let count = childViewControllers.count;
        var labelX:CGFloat = 0.0;
        let labelY:CGFloat = 0.0;
        let labelH:CGFloat = titleViewHeight;
        
        for i in 0 ..< count {
            let vc : UIViewController = childViewControllers[i]
            let label : UILabel = UILabel()
            label.backgroundColor = UIColor.white
            
            //当前文字的宽度
            var width:CGFloat = 0
            if average {
                //取得最后一个Label的最大X值
                labelX = layoutLastLabel.frame.maxX
                width = DCWidth / CGFloat(count)
                label.frame = CGRect(x:labelX,y: labelY,width: width,height: labelH)
            }else {
                //取得最后一个Label的最大X值
                labelX = layoutLastLabel.frame.maxX + titleViewMargin
                width = vc.title!.calculateRowWidth(labelSize)
                label.frame = CGRect(x:labelX,y: labelY,width: width,height: labelH)
            }
            label.backgroundColor = UIColor.randomColor()
            label.text = vc.title;
            label.textColor = normalColor
            label.tag = i;
            label.isUserInteractionEnabled = true
            label.textAlignment =  NSTextAlignment.center
            titleLabels.append(label)
            titleScrollView .addSubview(label)
            layoutLastLabel = label
            
            //建立手势识别器
            let gesture = UITapGestureRecognizer(target: self, action: #selector(titleClick(sender:)))
            //附加识别器到视图
            label.addGestureRecognizer(gesture)
            
            if(i==0) {
                selLabel = label
                let buttomwidth = average ? botoomLineViewWidth : selLabel.frame.width
                self.buttomView.frame = CGRect(x: 0, y: titleViewHeight - botoomLineViewHeight , width: buttomwidth, height: botoomLineViewHeight)
                self.buttomView.center.x = (selLabel.center.x)
                titleClick(sender: gesture)
            }
            
            self.titleScrollView.bringSubview(toFront: buttomView)
            
            
            
        }
        if average {
            self.titleScrollView.contentSize = CGSize(width: layoutLastLabel.frame.maxX, height: titleViewHeight)
        }else {
            self.titleScrollView.contentSize = CGSize(width: layoutLastLabel.frame.maxX + titleViewMargin, height: titleViewHeight)
        }
    }
}

// MARK:- 点击事件
extension ViewController {
    
    @objc func titleClick(sender: UITapGestureRecognizer){
        isForbidScroll = true //点击的就不需执行滚动
        half = false
        contentScrollView.isScrollEnabled =  false
        let time: TimeInterval = 0.25
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + time) {
            self.contentScrollView.isScrollEnabled =  true
        }
        let selLabel:UILabel = sender.view as! UILabel
        let index = selLabel.tag
        showVc(index: index , selLabel:selLabel)
        selectLabel(label: selLabel)
        let offsetX:CGFloat = CGFloat(index)*DCWidth;
        self.contentScrollView.contentOffset = CGPoint(x:offsetX,y: 0);
        setupTitleCenter(centerLabel: selLabel)
        resetLabel(index:index)
        let dc = self.childViewControllers[index] as! OneViewController
        dc.dcViewWillAppear()
    }
    
    
    func showVc(index:Int , selLabel:UILabel){
        let buttomwidth = average ? botoomLineViewWidth : selLabel.frame.width
        UIView.animate(withDuration: 0.15) {
            self.buttomView.frame = CGRect(x: 0, y: titleViewHeight - botoomLineViewHeight , width: buttomwidth, height: botoomLineViewHeight)
            self.buttomView.center.x = selLabel.center.x
        }
    }
    
    
    func selectLabel(label:UILabel){
        selLabel = label;
    }
    
}

// MARK:- 代理事件
extension ViewController:UIScrollViewDelegate {
    
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        
        guard startOffsetX != scrollView.contentOffset.x else {
            return
        }
        
        if (isForbidScroll) {
            return
        }
        
        // 1.定义targetIndex/progress
        var targetIndex = 0
        var progress : CGFloat = 0.0
        
        // 2.给targetIndex/progress赋值
        let currentIndex = Int(startOffsetX / scrollView.bounds.width)
        if startOffsetX < scrollView.contentOffset.x { // 左滑动
            targetIndex = currentIndex + 1
            if targetIndex > titles.count - 1 {
                targetIndex = titles.count - 1
            }
            progress = (scrollView.contentOffset.x - startOffsetX) / scrollView.bounds.width
            if (!half) {
                if scrollView.contentOffset.x >= ( CGFloat(currentIndex) * DCWidth ) +  (DCWidth * 0.5) {
                    let vc = self.childViewControllers[currentIndex + 1] as! OneViewController
                    vc.dc2ViewWillAppear()
                    half = true
                }
            }
        } else { // 右滑动
            targetIndex = currentIndex - 1
            if targetIndex < 0 {
                targetIndex = 0
            }
            progress = (startOffsetX - scrollView.contentOffset.x) / scrollView.bounds.width
            
            if (!half) {
                if scrollView.contentOffset.x <= ( CGFloat(currentIndex - 1) * DCWidth ) +  (DCWidth * 0.5) {
                    let vc = self.childViewControllers[currentIndex - 1] as! OneViewController
                    vc.dc2ViewWillAppear()
                    half = true
                }
            }
            
        }
        
        let targetLabel = titleLabels[targetIndex]
        
        // 2.颜色渐变
        let deltaRGB = UIColor.getRGBDelta(selectColor,normalColor)
        let selectRGB = selectColor.getRGB()
        let normalRGB = normalColor.getRGB()
        targetLabel.textColor = UIColor(r: normalRGB.0 + deltaRGB.0 * progress, g: normalRGB.1 + deltaRGB.1 * progress, b: normalRGB.2 + deltaRGB.2 * progress)
        selLabel.textColor = UIColor(r: selectRGB.0 - deltaRGB.0 * progress, g: selectRGB.1 - deltaRGB.1 * progress, b: selectRGB.2 - deltaRGB.2 * progress)
        
        //改变下划线
        self.buttomView.frame.origin.x =   selLabel.frame.minX + (targetLabel.frame.minX - selLabel.frame.minX) * progress
        var ld_frame: CGRect = self.buttomView.frame
        ld_frame.size.width = selLabel.frame.width + (targetLabel.frame.width - selLabel.frame.width) * progress
        self.buttomView.frame = ld_frame
        
        
        
        
    }
    
    
    
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { //减速停止
        //点击的时候 并不会走此方法
        if !decelerate { //真正的停下来
            endScrool(scrollView)
        } else {
            scrollView.isScrollEnabled =  false     //松手及执行
        }
    }
    
    
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { //将要拖拽的时候
        isForbidScroll = false //开始拖的时候起
        startOffsetX = scrollView.contentOffset.x
    }
    
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { //已经停止
        //点击的时候 并不会走此方法
        endScrool(scrollView)
        
    }
    
    /* 结束滚动所做的事情 */
    func endScrool(_ scrollView:UIScrollView) {
        
        // 计算滚动到哪一页
        let index = Int(scrollView.contentOffset.x / scrollView.bounds.size.width);
        // 2.把对应的标题选中
        selLabel = self.titleLabels[index];
        selectLabel(label: selLabel)
        //showVc(index: index ,selLabel: selLabel)
        setupTitleCenter(centerLabel: selLabel)
        resetLabel(index: index)
        scrollView.isScrollEnabled =  true
        half = false
        
    }
    
    func setupTitleCenter(centerLabel:UILabel) {
        // 计算偏移量
        var offsetX = centerLabel.center.x - DCWidth * 0.5
        if offsetX < 0 {
            offsetX = 0
        }
        // 获取最大滚动范围
        let maxOffsetX = self.titleScrollView.contentSize.width - DCWidth;
        if offsetX > maxOffsetX {
            offsetX = maxOffsetX
        }
        self.titleScrollView.setContentOffset(CGPoint(x:offsetX, y:0), animated: true)
    }
    
    /* 重置所有按钮 */
    func resetLabel(index:Int) {
        for (i , val)in titleLabels.enumerated() {
            let label = val
            if ( i == index) {
                label.textColor = selectColor;
            }else {
                label.textColor = normalColor;
            }
        }
    }
}

 

转载于:https://my.oschina.net/zhaodacai/blog/1604454

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值