Swift 仿支付宝\微信支付密码输入框,可自定义长度

2017-06-14  本文已影响595人  大猿媛
IMG_1851.PNG
重点:

输入框均分 6 小块儿,无光标显示,每输入一次就会出现个圆点,删除就会圆点消失

思路:

1、必然是用UITextField,设置文本内容为clearColor,可是textField会显示光标
2、为避免显示光标,所以UITextField上方覆盖个UIView,又要响应UITextField的firstResponder,所以UIView的userInterfaceEnabled为NO,那样式,就是在UIview上花很多线条,分成 6 个小格子
3、UITextField的代理方法,shouldChangeRange: WithString ,我们可以限制输入长度
4、在NSNotificationTextDidChange中,我们可以监听到文本长度改变,对UIView上要显示的圆点进行绘制,对的,这里 我用的是UIGraphics 画上去的圆点,每输入一次进行一次重绘制
5、按照这个思路唯一的一个问题(不明缘由),就是我用draw的前提下,用UIView创建的小格子的线条 显示的不太对,所以,只好连线条都是画上去的

主要代码:
1、负责UI以及相关UITextField代理的输入视图 PwdInputView,内部定义绘制视图shadeView:PaintView,响应输入的pwdTf:UITextField, 以及长度限制变量numberLimit: Int! ,创建的代码我就不写了,主要是代理和通知的响应

//MARK: 文本长度改变,对shadeView:PaintView重绘一次,圆点数就和输入长度一致了,输入完成就通过闭包 typealias FinishInputPWD = (_ inputText:String) -> Void将输入内容带回
      func textFieldDidChange(){
         self.shadeView.paintPoints(pointsNum: self.pwdTf.text!.characters.count)
//MARK: 输入完成就回收键盘,闭包带回输入内容
         if self.pwdTf.text?.characters.count == self.numberLimit{
             self.finishInputPwd(self.pwdTf.text!)
             self.endEditing(true)
          }
    }
    
    //MARK: ---------UITextFieldDelegate--,控制输入
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let length = textField.text!.characters.count - range.length + string.characters.count
        return length <= self.numberLimit
        
    }

2、负责绘制圆点的PaintView

   //MARK: 需要绘制的总个数,画线的时候用
   func totalPoints(pointNum:Int){
        self.points = pointNum
    }
    //MARK:绘制圆点,参数pointsNum:需要绘制的个数
    func paintPoints(pointsNum:Int){
        self.paintNum = pointsNum
        self.setNeedsDisplay()
    }

    //MARK: 初始化的时候会执行一次,所以如果此时self.paintNum==0 就表示是初始化,不进行圆点绘制
    override func draw(_ rect: CGRect) {
        super.draw(rect)
        
        let context = UIGraphicsGetCurrentContext()
        
        //设置填充色
        context?.setFillColor(UIColor.lightGray.cgColor)
        context?.setStrokeColor(UIColor.lightGray.cgColor)
        context?.setLineWidth(0.5)
        //画分割线
        let eachWidth = tfWidth/Float(self.points)
        
        for i in 1...self.points {
            let leftX = eachWidth * Float(i)
//            let rect = CGRect(x:CGFloat(leftX), y:0, width:0.2,height:CGFloat(tfHeight))
            context?.addLines(between: [CGPoint(x: CGFloat(leftX),y:CGFloat(0)),CGPoint(x: CGFloat(leftX),y:CGFloat(tfHeight))])
            
        }
        context?.strokePath()

        if self.paintNum == 0 {
            return
        }

        //画密码点 圆点
        let pointW = tfWidth/Float(self.points)/Float(2.2)
        let pointH = pointW
       
        let y = (tfHeight - pointH)/2.0
        for i in 0...(self.paintNum-1) {
            //计算原点位置
            let leftX = eachWidth*Float(i) + (eachWidth-pointW)/2.0
            let rect = CGRect(x:CGFloat(leftX), y:CGFloat(y), width:CGFloat(pointW), height:CGFloat(pointH))
            context?.addEllipse(in: rect)
        }
        context?.fillPath()
    }
上一篇下一篇

猜你喜欢

热点阅读