1、有图有真相
2、设计思路
2.1、以屏幕宽度为边长创建一个正方形View;
2.2、一个for循环创建9个按钮并自动布局;
2.3、监听该view的触摸事件,触摸区域落在某按钮区域则按钮发光
2.4、记录发光的按钮,输出按钮顺序(可以在for循环创建按钮时给按钮做tag标记,这样就有对应关系了,从而把按钮转换成字符串密码)
3、代码示例
SAScreenLockView.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // //? SAScreenLockView.h //? SAScreenLock // //? Created by 余西安 on 14/12/27. //? Copyright (c) 2014年 Sian. All rights reserved. // ? #import <UIKit/UIKit.h> ? /***************代理协议***************/ ? @class SAScreenLockView; ? @protocol SAScreenLockViewDelegate ? - (void)screenLock:(SAScreenLockView *)screenLockView didFinishPaht:(NSNumber *)path; ? @end ? /***************圆圈控件***************/ ? @interface SACircle : UIButton ? @end ? /***************解锁视图***************/ ? @interface SAScreenLockView : UIView ? @property (nonatomic, weak) id delegate; ? - (id)initWithDelegate:(id)delegate; ? @end |
SAScreenLockView.m
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | // //? SAScreenLockView.m //? SAScreenLock // //? Created by 余西安 on 14/12/27. //? Copyright (c) 2014年 Sian. All rights reserved. // ? #import "SAScreenLockView.h" ? /*********************圆圈控件*********************/ ? @implementation SACircle ? - (id)initWithCoder:(NSCoder *)aDecoder { ????if (self = [super initWithCoder:aDecoder]) { ????????[self setup]; ????} ????return self; } ? - (id)initWithFrame:(CGRect)frame { ????self = [super initWithFrame:frame]; ????if (self) { ????????[self setup]; ????} ????return self; } ? - (void)setup { ????self.userInteractionEnabled = NO; ????UIImage *normal = [UIImage imageNamed:@"gesture_node_normal.png"]; ????UIImage *selected = [UIImage imageNamed:@"gesture_node_highlighted"]; ????[self setImage:normal forState:UIControlStateNormal]; ????[self setImage:selected forState:UIControlStateSelected]; } @end ? /*********************解锁视图*********************/ ? @interface SAScreenLockView () ? @property (nonatomic, strong) NSMutableArray *circles; ? @property (nonatomic, assign) CGPoint??????? position; ? @end ? @implementation SAScreenLockView ? #pragma mark - 初始化方法 - (id)initWithDelegate:(id)delegate { ????if (self = [super init]) { ????????self.delegate = delegate; ????} ????return self; } // xib创建时调用 - (id)initWithCoder:(NSCoder *)aDecoder { ????if (self = [super initWithCoder:aDecoder]) { ????????[self setup]; ????} ????return self; } // 代码创建时调用 - (id)initWithFrame:(CGRect)frame { ????self = [super initWithFrame:frame]; ????if (self) { ????????[self setup]; ????} ????return self; } // 初始化9个子控件 - (void)setup { ????self.backgroundColor = [UIColor clearColor]; ????CGFloat width = [[UIScreen mainScreen] bounds].size.width; ????self.frame = (CGRect){CGPointZero, width, width}; ????for (int i = 0; i < 9; i++) { ????????SACircle *circle = [SACircle buttonWithType:UIButtonTypeCustom]; ????????circle.tag = i + 1; ????????[self addSubview:circle]; ????} } // 被选中的子控件 - (NSMutableArray *)circles { ????if (_circles == nil){ ????????_circles = [NSMutableArray array]; ????} ????return _circles; } // 子控件位置调整 - (void)layoutSubviews { ????NSInteger columns = 3; ????CGFloat width = self.frame.size.width; ????CGFloat dimeter = 64.0f; ????CGFloat margic = (width - dimeter * columns) / (columns + 1); ????for (SACircle *circle in self.subviews) { ????????CGFloat x = (circle.tag - 1) % columns * (dimeter + margic) + margic; ????????CGFloat y = (circle.tag - 1) / columns * (dimeter + margic); ????????CGFloat w = dimeter; ????????CGFloat h = dimeter; ????????circle.frame = (CGRect){x, y, w, h}; ????} ????CGRect rect = self.frame; ????rect.size.height = dimeter * 3 + margic * 2; ????self.frame = rect; } ? #pragma mark - 触摸交互事件处理 - (CGPoint)pointWithTouch:(NSSet *)touches { ????UITouch *touch = [touches anyObject]; ????return [touch locationInView:self]; } ? - (SACircle *)circleWithTouches:(NSSet *)touches { ????CGPoint pos = [self pointWithTouch:touches]; ????// 判断当前触摸位置是否进入9个圆圈内 ????for (SACircle *circle in self.subviews) { ????????CGRect touchArea = circle.frame; ????????CGFloat w = touchArea.size.width; ????????touchArea.origin.x += w / 4; ????????touchArea.origin.y += w / 4; ????????touchArea.size.width -= w / 2; ????????touchArea.size.height -= w / 2; ????????if (CGRectContainsPoint(touchArea, pos)){ ????????????return circle; ????????} ????} ????return nil; } ? - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { ????self.position = CGPointZero; ????SACircle *circle = [self circleWithTouches:touches]; ????// 如果进入圆圈内并且当前圆圈未被选中则加入到选中数组 ????if (circle && !circle.selected){ ????????circle.selected = YES; ????????[self.circles addObject:circle]; ????} ????[self setNeedsDisplay]; } ? - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { ????self.position = [self pointWithTouch:touches]; ????SACircle *circle = [self circleWithTouches:touches]; ????// 如果进入圆圈内并且当前圆圈未被选中则加入到选中数组 ????if (circle && !circle.selected){ ????????circle.selected = YES; ????????[self.circles addObject:circle]; ????} ????[self setNeedsDisplay]; } ? - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { ????NSMutableString *path = [NSMutableString string]; ????for (SACircle *circle in self.circles) { ????????circle.selected = NO; ????????[path appendFormat:@"%d", (int)circle.tag]; ????} ????// 当选中的圆圈不为空,并且代理有实现代理方法时通知代理 ????if ([self.delegate respondsToSelector:@selector(screenLock:didFinishPaht:)] && self.circles.count) ????????[self.delegate screenLock:self didFinishPaht:@([path longLongValue])]; ????? ????[self.circles removeAllObjects]; ????[self setNeedsDisplay]; } ? - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { ????[self touchesEnded:touches withEvent:event]; } ? #pragma mark - 视图绘制方法 - (void)drawRect:(CGRect)rect { ????if (self.circles.count == 0) return; ????UIBezierPath *path = [UIBezierPath bezierPath]; ????path.lineWidth = 8; ????path.lineCapStyle = kCGLineCapRound; ????path.lineJoinStyle = kCGLineJoinRound; ????for (int i = 0; i < self.circles.count; i++) { ????????SACircle *circle = self.circles[i]; ????????if (i == 0) { ????????????[path moveToPoint:circle.center]; ????????} else { ????????????[path addLineToPoint:circle.center]; ????????} ????} ????if (!CGPointEqualToPoint(self.position, CGPointZero)) ????????[path addLineToPoint:self.position]; ????[[UIColor colorWithRed:122/255.0 green:214/255.0 blue:250/255.0 alpha:0.7] set]; ????[path stroke]; } ? @end |
4、Demo下载:SAScreenLock