标签:
最近项目用到手势密码,第三方很多,但是都不喜欢,就自己写了个,分享下// // UnlockView.swift // XGestureUnlock // // Created by eduo_xiaoP on 15/4/6. // Copyright (c) 2015年 eduo. All rights reserved. // import Foundation import UIKit @objc protocol UnlockViewDelegate: NSObjectProtocol { optional func trackFinished(track: NSString) } class XUnlockView: UIView { struct Constant { static let Line_Width: CGFloat = 12 static let Line_Color = UIColor(red: 32/255.0, green: 210/255.0, blue: 254/255.0, alpha: 0.7) static let rows: Int = 3 static let cols: Int = 3 static let totalNodes = Constant.rows * Constant.cols } lazy var path: UIBezierPath = { let path = UIBezierPath() path.lineJoinStyle = kCGLineJoinBevel path.lineCapStyle = kCGLineCapRound path.lineWidth = Constant.Line_Width return path }() @IBOutlet var nodes = [Node]() weak var delegate: UnlockViewDelegate? var movePoint: CGPoint = CGPointMake(-1, -1) var selectNodes = [Node]() required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) buildNodes() } override init(frame: CGRect) { super.init(frame: frame) buildNodes() } func buildNodes() { for var index = 0; index < Constant.totalNodes; index++ { let node = Node.node() node.tag = index addSubview(node) nodes.append(node) } } override func layoutSubviews() { for var index = 0; index < Constant.totalNodes; index++ { let node = nodes[index] let marginX: CGFloat = 20 let marginY: CGFloat = 20 let nodeWidth = (bounds.size.width - 4 * marginX) / CGFloat(Constant.cols) let nodeHeight = nodeWidth let nodeRow = index / Constant.rows let nodeCol = index % Constant.cols let nodeX = CGFloat(nodeCol) * (nodeWidth + marginX) + marginX let nodeY = CGFloat(nodeRow) * (nodeHeight + marginY) + marginY node.frame = CGRectMake(nodeX, nodeY, nodeWidth, nodeHeight) } } override func drawRect(rect: CGRect) { if selectNodes.count == 0 { return } Constant.Line_Color.set() for index in 0..<selectNodes.count { let node = selectNodes[index] index == 0 ? path.moveToPoint(node.center) : path.addLineToPoint(node.center) } if movePoint != CGPointMake(-1, -1) { path.addLineToPoint(movePoint) } path.stroke() path.removeAllPoints() } func getPointWithTouches(touches: NSSet) -> CGPoint{ let touch = touches.anyObject() as UITouch return touch.locationInView(touch.view) } func getNodeWithPoint(point: CGPoint) -> Node? { for node in nodes { if node.frame.contains(point) && (node.selected == false) { return node } } return nil } override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { let point = getPointWithTouches(touches) if let node = getNodeWithPoint(point) { selectNodes.append(node) node.selected = true movePoint = point } setNeedsDisplay() } override func touchesMoved(touches: NSSet, withEvent event: UIEvent) { let point = getPointWithTouches(touches) if let node = getNodeWithPoint(point) { selectNodes.append(node) node.selected = true }else { movePoint = point } setNeedsDisplay() } override func touchesEnded(touches: NSSet, withEvent event: UIEvent) { var track = NSMutableString() for node in selectNodes { node.selected = false track.appendFormat("%d", node.tag) } if track.length != 0 { if delegate != nil && delegate!.respondsToSelector("trackFinished:") { delegate!.trackFinished!(track) } } selectNodes.removeAll(keepCapacity: false) movePoint = CGPointMake(-1, -1) setNeedsDisplay() } override func touchesCancelled(touches: NSSet!, withEvent event: UIEvent!) { touchesEnded(touches, withEvent: event) } } class Node: UIButton { required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) build() } override init(frame: CGRect) { super.init(frame: frame) build() } func build() { setBackgroundImage(UIImage(named: "gesture_node_normal"), forState: .Normal) setBackgroundImage(UIImage(named: "gesture_node_highlighted"), forState: .Selected) userInteractionEnabled = false } class func node() -> Node { return super.buttonWithType(.Custom) as Node } }
标签:
原文地址:http://blog.csdn.net/gxp1032901/article/details/45005607