重點(diǎn):
輸入框均分 6 小塊兒,無光標(biāo)顯示扳肛,每輸入一次就會出現(xiàn)個圓點(diǎn)傻挂,刪除就會圓點(diǎn)消失
思路:
1、必然是用UITextField挖息,設(shè)置文本內(nèi)容為clearColor金拒,可是textField會顯示光標(biāo)
2、為避免顯示光標(biāo)套腹,所以UITextField上方覆蓋個UIView绪抛,又要響應(yīng)UITextField的firstResponder,所以UIView的userInterfaceEnabled為NO电禀,那樣式幢码,就是在UIview上花很多線條,分成 6 個小格子
3尖飞、UITextField的代理方法蛤育,shouldChangeRange: WithString ,我們可以限制輸入長度
4葫松、在NSNotificationTextDidChange中瓦糕,我們可以監(jiān)聽到文本長度改變,對UIView上要顯示的圓點(diǎn)進(jìn)行繪制腋么,對的咕娄,這里 我用的是UIGraphics 畫上去的圓點(diǎn),每輸入一次進(jìn)行一次重繪制
5珊擂、按照這個思路唯一的一個問題(不明緣由)圣勒,就是我用draw的前提下,用UIView創(chuàng)建的小格子的線條 顯示的不太對摧扇,所以圣贸,只好連線條都是畫上去的
主要代碼:
1、負(fù)責(zé)UI以及相關(guān)UITextField代理的輸入視圖 PwdInputView扛稽,內(nèi)部定義繪制視圖shadeView:PaintView吁峻,響應(yīng)輸入的pwdTf:UITextField, 以及長度限制變量numberLimit: Int! ,創(chuàng)建的代碼我就不寫了,主要是代理和通知的響應(yīng)
//MARK: 文本長度改變用含,對shadeView:PaintView重繪一次矮慕,圓點(diǎn)數(shù)就和輸入長度一致了,輸入完成就通過閉包 typealias FinishInputPWD = (_ inputText:String) -> Void將輸入內(nèi)容帶回
func textFieldDidChange(){
self.shadeView.paintPoints(pointsNum: self.pwdTf.text!.characters.count)
//MARK: 輸入完成就回收鍵盤啄骇,閉包帶回輸入內(nèi)容
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、負(fù)責(zé)繪制圓點(diǎn)的PaintView
//MARK: 需要繪制的總個數(shù)缸夹,畫線的時候用
func totalPoints(pointNum:Int){
self.points = pointNum
}
//MARK:繪制圓點(diǎn)痪寻,參數(shù)pointsNum:需要繪制的個數(shù)
func paintPoints(pointsNum:Int){
self.paintNum = pointsNum
self.setNeedsDisplay()
}
//MARK: 初始化的時候會執(zhí)行一次,所以如果此時self.paintNum==0 就表示是初始化虽惭,不進(jìn)行圓點(diǎn)繪制
override func draw(_ rect: CGRect) {
super.draw(rect)
let context = UIGraphicsGetCurrentContext()
//設(shè)置填充色
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
}
//畫密碼點(diǎn) 圓點(diǎn)
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) {
//計(jì)算原點(diǎn)位置
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()
}