一. 九宫格解锁
1. 自定义一个View,初始化子控件,创建九个按钮
// 从xib中加载时调用- (void)awakeFromNib{[self setUp];}// 代码创建时调用- (instancetype)initWithFrame:(CGRect)frame{if (self = [super initWithFrame:frame]) {[self setUp];}return self;}
// 初始化子控件- (void)setUp{for (int i = 0; i < 9; ++i) {UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];[btn setImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];[btn setImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];[self addSubview:btn];btn.userInteractionEnabled = NO;btn.tag = i;}}
2. 设置frame
// 子控件设置frame- (void)layoutSubviews{[super layoutSubviews];int rowNum = 3;CGFloat line = 0;CGFloat row = 0;CGFloat btnHW = 74;CGFloat space = (self.bounds.size.width - btnHW * 3) / (rowNum + 1);for (int i = 0; i < self.subviews.count; ++i) {UIButton *btn = self.subviews[i];row = i / rowNum;line = i % rowNum;CGFloat btnX = space + line * (space + btnHW);CGFloat btnY = row * (space + btnHW);btn.frame = CGRectMake(btnX, btnY, btnHW, btnHW);}}
3. 监听开始触摸,判断当前触摸点是否在按钮上,如果在设置为选中状态并记录,将选中的按钮添加到一个数组中保存
// 获取当前触摸点- (CGPoint)getCurrentPointWithSet:(NSSet *)touches{// 1.获取触摸对象UITouch *touch = [touches anyObject];// 2.获取当前的触摸点return [touch locationInView:self];}// 判断当前触摸点是否在按钮上- (UIButton *)getButtonWithPoint:(CGPoint)point{// 3.判断当前点是否在按钮上for (UIButton *btn in self.subviews) {if (CGRectContainsPoint(btn.frame, point) && btn.selected == NO) {[self.selectedBtnArray addObject:btn];return btn;}}return nil;}// 开始触摸- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{// 获取当前触摸点CGPoint curP = [self getCurrentPointWithSet:touches];// 3.判断当前点是否在按钮上UIButton *btn = [self getButtonWithPoint:curP];if (btn) {btn.selected = YES;self.startBtn = btn;}}
4. 监听触摸移动,同样判断触摸点是否在按钮上,如果在则设置为选中状态并添加到数组中保存
重绘
// 移动触摸- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{// 获取当前触摸点CGPoint curP = [self getCurrentPointWithSet:touches];self.curP = curP;// 3.判断当前点是否在按钮上UIButton *btn = [self getButtonWithPoint:curP];if (btn) {btn.selected = YES;}// 重绘[self setNeedsDisplay];}
5. 绘制数组中的按钮
- (void)drawRect:(CGRect)rect {UIBezierPath *path = [UIBezierPath bezierPath];if (self.selectedBtnArray.count) {for (int i = 0; i < self.selectedBtnArray.count; ++i) {UIButton *btn = self.selectedBtnArray[i];if (i == 0) {[path moveToPoint:self.startBtn.center];} else {[path addLineToPoint:btn.center];}}[[UIColor redColor] set];[path setLineWidth:10];[path setLineJoinStyle:kCGLineJoinRound];[path setLineCapStyle:kCGLineCapRound];[path addLineToPoint:self.curP];[path stroke];}}
6. 停止触摸时将按钮选中状态取消,并重绘
// 停止触摸- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{NSMutableString *strM = [NSMutableString string];// 1.将选中按钮取消选中状态for (UIButton *btn in self.selectedBtnArray) {btn.selected = NO;[strM appendFormat:@"%zd", btn.tag];}// 2.清空选中按钮数组[self.selectedBtnArray removeAllObjects];// 3.重绘[self setNeedsDisplay];NSLog(@"%@", strM);// 4.将密码发给控制器判断密码是否登录if ([self.delegate respondsToSelector:@selector(lockView:loginToStr:)]) {[self.delegate lockView:self loginToStr:strM];}}