iOS 滑动控件自定义UISegmentedControl实现

我们经常会用到滑动控件,但是系统自带的UISegmentedControl一般不满足需求,自己写了一个滑动控件,可以实现拖拽滑动的功能

 

初始化一些基本视图  JWSegmentControl

class JWSegmentControl: UIView {

 

//根据自己的需要可以改变下面的值

var defaultSegment = 1  //默认选择第一个

    var segmentSpace = 4  //tab间距

    var selectedColor:UIColor = .white //选中的背景色

    var backColor:UIColor = .gray //未选中背景色

    var title:[String] = ["第一个","第二个","第三个","第四个"] //tab标题

    var selectIndex:((_ button:UIButton)->())?

    

    var segmentCount:Int{

        get{

            return title.count

        }

    }

    var segmentBackView:UIView?

    var segmentBtnBackView:UIView?

    var segmentBtn:UIButton?

    var segSliderBtn:UIButton?

    var segments = [UIButton]()

    var canDrag:Bool = true

    var segmentBtnW:Int{

        get{

            return Int((self.frame.size.width - CGFloat(segmentSpace) * CGFloat(segmentCount + 1)) / CGFloat(segmentCount))

        }

    }

    

    override init(frame: CGRect) {

        super.init(frame: frame)

        self.backgroundColor = .clear

        self.isUserInteractionEnabled = true

    }

    

    override func willMove(toSuperview newSuperview: UIView?) {

        superview?.willMove(toSuperview: newSuperview)

        

        if newSuperview != nil{

            self.setupUI()

        }

        

    }

    

    func setupUI() {

        segmentBackView = UIView.init(frame: self.bounds)

        segmentBackView?.backgroundColor = backColor

        segmentBackView!.layer.cornerRadius = CGFloat(self.frame.height/2)

        segmentBackView!.layer.masksToBounds = true

        self.addSubview(segmentBackView!)

        

        //滑动button

        let h = Int(self.frame.height) - segmentSpace*2

        segSliderBtn = UIButton.init(type: .custom)

        segSliderBtn!.layer.cornerRadius = CGFloat(h/2)

        segSliderBtn!.layer.masksToBounds = true

        segSliderBtn!.backgroundColor = selectedColor

        segmentBackView!.addSubview(segSliderBtn!)

        

        segmentBtnBackView = UIView.init(frame: segmentBackView!.bounds)

        segmentBtnBackView?.backgroundColor = .clear

        segmentBtnBackView!.layer.cornerRadius = CGFloat(self.frame.height/2)

        segmentBtnBackView!.layer.masksToBounds = true

        segmentBtnBackView?.isUserInteractionEnabled = true

        segmentBackView?.addSubview(segmentBtnBackView!)

        

        //添加滑动手势

        let getsture = UIPanGestureRecognizer.init(target: self, action: #selector(panGesture(geture:)))

        self.addGestureRecognizer(getsture)

        

        //创建tab

        for i in 0..<segmentCount {

            let button = UIButton.init(type: .custom)

            let x = segmentSpace + (i%segmentCount)*(segmentBtnW + segmentSpace)

            let h = Int(self.frame.height) - segmentSpace*2

            button.frame = CGRect.init(x:x, y: segmentSpace, width: segmentBtnW, height:h)

            button.setTitle(title[i], for: .normal)

            button.setTitleColor(.black, for: .normal)

            button.layer.cornerRadius = CGFloat(h/2)

            button.layer.masksToBounds = true

            button.isUserInteractionEnabled = true

            button.addTarget(self, action: #selector(tabAction(sender:)), for: .touchUpInside)

            button.tag = 1000 + i

            button.backgroundColor = .clear

            segmentBtnBackView!.addSubview(button)

            segments.append(button)

        }

        

        //创建tab之后改变滑动buttom的frame

        segSliderBtn?.frame = segments[defaultSegment - 1].frame

        

    

    }

 

 具体实现拖拽切换的步骤

@objc func panGesture(geture:UIPanGestureRecognizer){

        let pointA = geture.location(in: self.segmentBackView)

        

        if geture.state == .began{

            if(!(self.segSliderBtn?.frame.contains(pointA))!){

                canDrag = false

                return

            }

        }

        

        if geture.state == .changed{

            

            if canDrag == false{

                return

            }

            //改变滑动button的位置

            for i in 0..<segments.count {

                let button = segments[i]

                if pointA.x > button.frame.minX && pointA.x < button.frame.maxX{

                    UIView.animate(withDuration: 0.1) {[weak self] in

                        self!.segSliderBtn?.center = self!.segments[i].center

                        self!.defaultSegment = i;

                    }

                    break;

                }

            }

    

        }

        

        geture.setTranslation(.zero, in: self.segmentBackView)

        

        if geture.state == .ended{

            canDrag = true

            if let selectIndex = selectIndex{

                selectIndex(segments[defaultSegment])

            }

        }

        

    }

    

    /**

     点击切换到其他按钮

     */

    @objc func tabAction(sender:UIButton){

        

        let button = segments[sender.tag - 1000]

        

        UIView.animate(withDuration: 0.2) { [weak self] in

            self!.segSliderBtn!.center = button.center

        }

        

        defaultSegment = sender.tag - 1000 + 1

        

        if let selectIndex = selectIndex{

            selectIndex(sender)

        }

    }

}

 

调用方式

        let jwSegment = JWSegmentControl.init(frame: CGRect.init(x: 0, y: 200, width: UIScreen.main.bounds.width, height: 40))

        jwSegment.defaultSegment = 1   //默认显示第几个tab

        jwSegment.selectedColor = .white //选中的背景色

        jwSegment.backColor = .gray //未选中的背景色

        jwSegment.title = ["第一个","第二个","第三个","第四个"] //tab标题

        jwSegment.selectIndex = { (button:UIButton) ->Void in

            print(button.tag - 1000)

        }

        self.view.addSubview(jwSegment)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值