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()
}