ios手勢密碼Swift4.0
之前做的P2P項目用到了手勢密碼的功能,由于著急上線,所以在網(wǎng)上扒了一個,但是為了滿足自己的代碼需求,改了改別人的代碼,過程是十分痛苦的.現(xiàn)在的新項目同樣要用到手勢密碼的功能,所以我干脆就自己重新寫了一個宪萄,由于我用的是Swift艺谆,所以這個手勢密碼也是用Swift4.0寫的。
手勢密碼的實現(xiàn)其實還是很簡單的拜英,我的做法就是用貝塞爾曲線來展現(xiàn)出用戶的滑動軌跡,用button來記錄下用戶設(shè)置的手勢密碼的具體值
用戶設(shè)置手勢密碼的類中(實質(zhì)就是一個UIView)中
創(chuàng)建九宮格排列的Button,用來顯示和記錄用戶設(shè)置的手勢密碼的具體值,并給自己添加一個手勢
extension HLGestureUnlockView {
///添加手勢,創(chuàng)建按鈕
func setup() {
//創(chuàng)建一個手勢,添加給自己
let pan = UIPanGestureRecognizer.init(target: self, action: #selector(panAction(pan:)))
self.addGestureRecognizer(pan)
//創(chuàng)建9個按鈕
for i in 0...8 {
let btn = UIButton.init(type: .custom)
btn.isUserInteractionEnabled = false
btn.setImage(UIImage.init(named: "gesture_node_normal.png"), for: .normal)
btn.setImage(UIImage.init(named: "gesture_node_pressed.png"), for: .selected)
btn.tag = 1000 + i + 1
self.addSubview(btn)
}
}
}
下面是layout中按鈕的布局
//MARK: - btn的布局
extension HLGestureUnlockView {
///btn的布局
func setBtnFrame() {
let count = self.subviews.count
///總列數(shù)
let cols = 3
var x: CGFloat = 0
var y: CGFloat = 0
let w: CGFloat = 58
let h: CGFloat = 58
///間距
let margin = (self.bounds.size.width - CGFloat(cols) * w) / (CGFloat(cols) + 1)
//開始布局
var col: CGFloat = 0
var row : CGFloat = 0
for i in 0..<count {
col = CGFloat(i % cols)
row = CGFloat(i / cols)
x = margin + (w + margin) * col
y = margin + (w + margin) * row
let btn = self.subviews[i] as! UIButton
btn.frame = CGRect(x: x, y: y, width: w, height: h)
}
}
}
在手勢的方法中,我們需要記錄下當(dāng)前的點,如果當(dāng)前的點較好在某一按鈕的frame中,那么就是用戶設(shè)置了這一個按鈕,我們需要將該按鈕變?yōu)檫x中的狀態(tài)
//MARK: - 實現(xiàn)手勢方法
extension HLGestureUnlockView {
@objc func panAction(pan: UIPanGestureRecognizer) {
//給當(dāng)前點復(fù)制
self.currentPoint = pan.location(in: self)
self.setNeedsDisplay()
for btn in self.subviews {
let btn = btn as! UIButton
if (btn.frame.contains(self.currentPoint) && btn.isSelected == false) {
btn.isSelected = true
self.selectedBtns.append(btn)
}
}
self.layoutIfNeeded()
//手勢結(jié)束的時候
var gesturePwd = ""
if pan.state == .ended {
for btn in self.selectedBtns {
gesturePwd += "\(btn.tag - 1000)"
btn.isSelected = false
}
self.selectedBtns.removeAll()
//手勢密碼繪制完成后的回調(diào)
if self.delegate != nil {
self.delegate?.gestureDidFinished(gesturePassword: gesturePwd)
}
}
}
}
最后就是在draw方法中實現(xiàn)畫線的功能就好了
```swift
//MARK: - 重寫drawRect
extension HLGestureUnlockView {
override func draw(_ rect: CGRect) {
//如果沒有選中按鈕的時候,直接返回
if self.selectedBtns.count == 0 {
return
}
//將所有的選中按鈕中心點連線
let path = UIBezierPath()
let count = self.selectedBtns.count
for i in 0..<count {
let btn = self.selectedBtns[i]
if i == 0 {
//設(shè)置起點
path.move(to: btn.center)
} else {
//設(shè)置終點
path.addLine(to: btn.center)
}
}
path.addLine(to: self.currentPoint)
UIColor.init(red: 15 / 255.0, green: 127 / 255.0, blue: 255 / 255.0, alpha: 1).set()
path.lineJoinStyle = .round
path.lineWidth = 8
path.stroke()
}
}
到這手勢密碼的這個類就基本寫好了,在加一個設(shè)置好手勢密碼后的回調(diào)就OK了,其實看這個代碼應(yīng)該還是很清楚了静汤,為了簡化操作,我的demo中創(chuàng)建和驗證手勢密碼的界面是用兩個Controller來展示的,演示的圖片就沒搞了,不過虫给,這個手勢密碼完全可以滿足你項目的需求藤抡,demo地址: