ios手势密码Swift4.0
之前做的P2P项目用到了手势密码的功能,由于着急上线,所以在网上扒了一个,但是为了满足自己的代码需求,改了改别人的代码,过程是十分痛苦的.现在的新项目同样要用到手势密码的功能,所以我干脆就自己重新写了一个,由于我用的是Swift,所以这个手势密码也是用Swift4.0写的。
手势密码的实现其实还是很简单的,我的做法就是用贝塞尔曲线来展现出用户的滑动轨迹,用button来记录下用户设置的手势密码的具体值
用户设置手势密码的类中(实质就是一个UIView)中
创建九宫格排列的Button,用来显示和记录用户设置的手势密码的具体值,并给自己添加一个手势
extension HLGestureUnlockView {
///添加手势,创建按钮
func setup() {
//创建一个手势,添加给自己
let pan = UIPanGestureRecognizer.init(target: self, action: #selector(panAction(pan:)))
self.addGestureRecognizer(pan)
//创建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
///总列数
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)
}
}
}
在手势的方法中,我们需要记录下当前的点,如果当前的点较好在某一按钮的frame中,那么就是用户设置了这一个按钮,我们需要将该按钮变为选中的状态
//MARK: - 实现手势方法
extension HLGestureUnlockView {
@objc func panAction(pan: UIPanGestureRecognizer) {
//给当前点复制
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()
//手势结束的时候
var gesturePwd = ""
if pan.state == .ended {
for btn in self.selectedBtns {
gesturePwd += "\(btn.tag - 1000)"
btn.isSelected = false
}
self.selectedBtns.removeAll()
//手势密码绘制完成后的回调
if self.delegate != nil {
self.delegate?.gestureDidFinished(gesturePassword: gesturePwd)
}
}
}
}
最后就是在draw方法中实现画线的功能就好了
```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 {
//设置起点
path.move(to: btn.center)
} else {
//设置终点
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()
}
}
到这手势密码的这个类就基本写好了,在加一个设置好手势密码后的回调就OK了,其实看这个代码应该还是很清楚了,为了简化操作,我的demo中创建和验证手势密码的界面是用两个Controller来展示的,演示的图片就没搞了,不过,这个手势密码完全可以满足你项目的需求,demo地址:
网友评论