一、手势密码
1、
1.1、用UIButton组成手势的节点。
1.2、当手指接触屏幕时,调用重写的 touchesBegan:withEvent方法(在touchesBegan里调用setNeedsDisplay,这样就会自动调用drawRect方法)。
1.3、当手指在屏幕上滑动时,调用重写的touchesMoved: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() }