一、手势密码
1、
1.1、用UIButton组成手势的节点。
1.2、当手指接触屏幕时,调用重写的 touchesBegan:withEvent方法(在touchesBegan里调用setNeedsDisplay,这样就会自动调用drawRect方法)。
1.3、当手指在屏幕上滑动时,调用重写的touchesEnded:withEvent方法。
这两个方法执行的操作是一样的:通过locationInView获取 触摸的坐标,然后用 CGRectContainsPoint 判断手指是否经过UIButton,如果经过按钮,就更换按钮的图片,同时 保存划过按钮的tag。
1.4、默认情况下 跳跃连线 第1个和第3个节点,中间的第2个节点 会被忽略,所以要单独进行处理。根据1和3节点 的2个UIButton的坐标 计算出第1个和第3个节点 中间的坐标,判断该坐标是否存在UIButton,如果存在就加入设置选中,并加入选中数组。
到这里 就已经实现了 手指滑过 节点的时候 节点被选中的效果:
// MARK: - Override
// 当手指接触屏幕时,就会调用touchesBegan:withEvent方法;
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
print("执行touchesBegan")
selectBtnTagArray.removeAll()
touchesChange(touches)
}
//当手指在屏幕上移动时,调用touchesMoved:withEvent方法;
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
touchesChange(touches)
}
//当触摸被取消(比如触摸过程中被来电打断),就会调用touchesCancelled:withEvent方法。
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
}
//当手指离开屏幕时,就会调用touchesEnded:withEvent方法;
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
print("执行touchesEnded")
var alertTitle = "请设置正确的手势"
var alertMessage = "手势密码不能少于4个"
var isSuccess = false
if selectBtnTagArray.count >= 4 {
alertTitle = "手势密码设置成功"
isSuccess = true
alertMessage = "密码为:(selectBtnTagArray)"
}
gestureLockDelegate!.gestureLockSuccess(isSuccess, title: alertTitle, message: alertMessage)
gesturePoint = CGPointZero;
self.setNeedsDisplay()
}
// MARK: - PrivateMethod
private func initButtons() {
for i in 0...8 {
//第几行
let row = i / 3
let loc = i % 3
//两个button的间距
let btnSpace = (screenWidth - 3*btnWH)/4
let btnX = btnSpace + (btnWH + btnSpace) * CGFloat(loc)
let btnY = 70 + btnSpace + (btnWH + btnSpace) * CGFloat(row)
let gestureNodeBtn = UIButton(frame:CGRectMake(btnX, btnY, btnWH, btnWH))
gestureNodeBtn.tag = i
gestureNodeBtn.userInteractionEnabled = false //不响应用户的交互。一定要加上这句
gestureNodeBtn.setImage(UIImage(named: btnImgNormal), forState: .Normal)
self.addSubview(gestureNodeBtn)
btnArray.append(gestureNodeBtn)
}
}
private func touchesChange(touches: Set<UITouch>) {
//获取 触摸对象 ,触摸对象的位置坐标来实现
gesturePoint = touches.first!.locationInView(self)
for btn in btnArray {
//判断 手指的坐标 是否在 button的坐标里
if !selectBtnTagArray.contains(btn.tag) && CGRectContainsPoint(btn.frame, gesturePoint) {
//处理跳跃连线
var lineCenterPoint:CGPoint = CGPoint()
if selectBtnTagArray.count > 0 {
lineCenterPoint = centerPoint(btn.frame.origin, endPoint: btnArray[selectBtnTagArray.last!].frame.origin)
}
//保存中间跳跃 过的节点
for btn in btnArray {
if !selectBtnTagArray.contains(btn.tag) && CGRectContainsPoint(btn.frame, lineCenterPoint) {
btn.setImage(UIImage(named: btnImgSelected), forState: .Normal)
selectBtnTagArray.append(btn.tag)
}
}
//保存划过的按钮的tag
selectBtnTagArray.append(btn.tag)
btn.setImage(UIImage(named: btnImgSelected), forState: .Normal)
}
}
//setNeedsDisplay会自动调用drawRect方法 进行画线
self.setNeedsDisplay()
}
//计算2个节点中心的坐标
private func centerPoint(startPoint: CGPoint, endPoint:CGPoint) -> CGPoint {
let rightPoint = startPoint.x > endPoint.x ? startPoint.x : endPoint.x
let leftPoint = startPoint.x < endPoint.x ? startPoint.x : endPoint.x
let topPoint = startPoint.y > endPoint.y ? startPoint.y : endPoint.y
let bottomPoint = startPoint.y < endPoint.y ? startPoint.y : endPoint.y
//x坐标: leftPoint +(rightPoint-leftPoint)/2 = (rightPoint+leftPoint)/2
return CGPointMake((rightPoint + leftPoint)/2 + btnWH/2, (topPoint + bottomPoint)/2 + btnWH/2);
}
func recoverNodeStatus() {
selectBtnTagArray.removeAll()
for btn in btnArray {
btn.setImage(UIImage(named: btnImgNormal), forState: .Normal)
}
self.setNeedsDisplay()
}











