美文网首页
swift 自定义 UIStepper

swift 自定义 UIStepper

作者: flyrr | 来源:发表于2016-10-28 17:08 被阅读103次

    系统自带的UIStepper没有显示当前value值得控件,需要自行添加label来显示。而此控件自带一个label来显示当前值。而且,与系统UIStepper的属性一样都可以设置的。
    控件类型分为普通类型,以及外层带有圆圈的。在这里,左边的减号,右边的加号,以及当类型为circle时的圆圈是通过CAShapeLayer和UIBezierPath画出来的,非UIButton控件。

    /**
     控件类型
     
     - custome: 默认
     - circle:  外层带圆圈
     */
    enum StepType {
        case custom
        case circle
    }
    
    ![Simulator Screen Shot 2016年10月28日 下午4.53.15.png](https://img.haomeiwen.com/i1421310/f8095d5df825347d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

    控件的初始化方法,可选择闭包处理点击事件,或者选择代理

    /**
         初始化方法
         
         - parameter frame: 控件frame--若想circle类型时,成圆形,最好宽高比为10:3
         - parameter type:  控件类型
         - action: 点击闭包,可选代理或者闭包,二选1
         
         - returns: 此控件
         */
        init(frame: CGRect, type: StepType, action: TypeClouse?) {
            self.stepType = type
            self.action = action
            super.init(frame: frame)
            defaultAppearance()
        }
    

    控件有个属性,是设置控件外观的。里面有个属性观察器didSet方法---当设置外观的时候调用draw()方法~~~
    此方法,先reset UI--即清除UI上所有的控件以及layer,然后在重新布置界面---如果不设置的话,会使用默认设置

    var appearance: Appearance! {
            didSet {
                self.draw()
            }
        }
    
    
    private func reset() {
        //清除控件
            for sub in subviews {
                sub.removeFromSuperview()
            }
    //清除layer
            if let layers = layer.sublayers {
                for lay in layers {
                    lay.removeFromSuperlayer()
                }
            }
        }
        
        private func draw() {
            reset()
            let centerY = frame.size.height * 0.5
            let width = frame.size.width
            let linePath = UIBezierPath()
            defer {
                linePath.closePath()
            }
            //(- : label : +) = (3:4:3)
            // 画减号
            //(空白:-:空白) = (3:4:3)
            //线条宽度/高度
            let lineHeight = frame.size.height / 3
            // 减号起始点
            let startX1 = width * 0.3 * 0.3
            linePath.moveToPoint(CGPoint(x: startX1, y: centerY))
            linePath.addLineToPoint(CGPoint(x: startX1 + lineHeight, y: centerY))
            // 画加号
            //(空白:+:空白) = (3:4:3)
            //横线
            // 加号起始点
            let startX2 = width - width * 0.3 * 0.3 - lineHeight
            linePath.moveToPoint(CGPoint(x: startX2, y: centerY))
            linePath.addLineToPoint(CGPoint(x: startX2 + lineHeight, y: centerY))
            //竖线
            linePath.moveToPoint(CGPoint(x: startX2 + lineHeight * 0.5, y: centerY - lineHeight * 0.5))
            linePath.addLineToPoint(CGPoint(x: startX2 + lineHeight * 0.5, y: centerY + lineHeight * 0.5))
            
            let lineLayer = CAShapeLayer()
            lineLayer.path = linePath.CGPath
            lineLayer.strokeColor = appearance.actionColor.CGColor
            lineLayer.lineWidth = 1
            self.layer.addSublayer(lineLayer)
            
            let (leftFrame, remainFrame) = bounds.divide(bounds.size.width * 0.3, fromEdge: .MinXEdge)
            let (middleFrame, rightFrame) = remainFrame.divide(remainFrame.size.width * 4 / 7, fromEdge: .MinXEdge)
     
            label.frame = middleFrame
            addSubview(label)
            label.textAlignment = .Center
            label.textColor = appearance.textColor
            label.font = appearance.textFont
            label.adjustsFontSizeToFitWidth = true
            
            //添加action
            let reduceC = UIControl(frame: leftFrame)
            reduceC.addTarget(self, action: #selector(reduce), forControlEvents: .TouchUpInside)
            addSubview(reduceC)
            
            let addC = UIControl(frame: rightFrame)
            addC.addTarget(self, action: #selector(add), forControlEvents: .TouchUpInside)
            addSubview(addC)
            
            switch stepType {
            case .circle:
                let scale: CGFloat = 0.7
                let reduceFrame = CGRect(x: leftFrame.size.width * 0.5 * (1 - scale), y: centerY - leftFrame.size.height * scale * 0.5, width: leftFrame.size.width * scale, height: leftFrame.size.height * scale)
                let reducePath = UIBezierPath(ovalInRect: reduceFrame)
                let reduceLayer = CAShapeLayer()
                reduceLayer.path = reducePath.CGPath
                reduceLayer.fillColor = appearance.fillColor.CGColor
                reduceLayer.strokeColor = appearance.strokeColor.CGColor
                reduceLayer.lineWidth = 1
                layer.addSublayer(reduceLayer)
                
                let addFrame = CGRect(x: startX2 + lineHeight * 0.5 - rightFrame.size.width * scale * 0.5, y: centerY - rightFrame.size.height * scale * 0.5, width: rightFrame.size.width * scale, height: rightFrame.size.height * scale)
                let addPath = UIBezierPath(ovalInRect: addFrame)
                let addLayer = CAShapeLayer()
                addLayer.path = addPath.CGPath
                addLayer.fillColor = appearance.fillColor.CGColor
                addLayer.strokeColor = appearance.strokeColor.CGColor
                addLayer.lineWidth = 1
                layer.addSublayer(addLayer)
            case .custom:
                return
            }
        }
    

    外界调用代码:

    stepV = ZGJStepView(frame: CGRect(x: 50, y: 400, width: 300, height: 90), type: .custom, action: nil)
            
            stepV.backgroundColor = UIColor.lightGrayColor()
            stepV.minimumValue = 2
            stepV.maximumValue = 10
            stepV.stepValue = 1
            stepV.delegate = self
            stepV.appearance = Appearance(
                actionColor: UIColor.redColor(),
                strokeColor: UIColor.redColor(),
                fillColor: UIColor.clearColor(),
                textColor: UIColor.blackColor(),
                textFont: UIFont.systemFontOfSize(15))
            view.addSubview(stepV)
    

    下面是控件一些可设置的属性,与系统UIStepper的属性非常相识,可以无痛转接

    /// 最小值  默认0
        var minimumValue: Double = 0 {
            didSet {
                self.value = minimumValue
                if minimumValue % 1.0 == 0.0 {
                  label.text = "\(Int(minimumValue))"
                } else {
                  label.text = "\(minimumValue)"
                }
            }
        }
        /// 最大值默认 100
        var maximumValue: Double = 100
        /// 每一次点击增减值 默认1
        var stepValue: Double = 1
        /// 当前值---默认0
        var value: Double = 0 {
            didSet {
                if stepValue % 1.0 == 0.0 && minimumValue % 1.0 == 0.0 {
                    label.text = "\(Int(value))"
                } else {
                    label.text = "\(value)"
                }
            }
        }
    

    然后是可以设置控件的外观

    /**
     *  控件的基本设置
     */
    struct Appearance {
        /// ➕/➖的颜色
        var actionColor: UIColor
        /// circle类型时,外围圆圈颜色
        var strokeColor: UIColor
        var fillColor: UIColor
        /// 字体颜色
        var textColor: UIColor
        /// 字体
        var textFont: UIFont
    }
    

    git地址:https://github.com/guijie20140501/ZGJStepView.git

    相关文章

      网友评论

          本文标题:swift 自定义 UIStepper

          本文链接:https://www.haomeiwen.com/subject/hajeuttx.html