1 #import <UIKit/UIKit.h> 2 @class NJLockView; 3 4 @protocol NJLockViewDelegate <NSObject> 5 6 - (void)lockViewDidClick:(NJLockView *)lockView andPwd:(NSString *)pwd; 7 8 @end 9 10 @interface NJLockView : UIView 11 12 @property (nonatomic, weak)IBOutlet id<NJLockViewDelegate> delegate; 13 @end 14 15 16 17 @interface NJLockView () 18 19 @property (nonatomic, strong) NSMutableArray *buttons; 20 /** 21 * 定义属性,记录用户当前手指的位置(非按钮范围内) 22 */ 23 @property (nonatomic, assign) CGPoint currentPoint; 24 @end 25 26 @implementation NJLockView 27 28 29 - (NSMutableArray *)buttons 30 { 31 if (_buttons == nil) { 32 _buttons = [NSMutableArray array]; 33 } 34 return _buttons; 35 } 36 37 // 当视图是通过代码创建出来的就会调用initWithFrame 38 - (id)initWithFrame:(CGRect)frame 39 { 40 self = [super initWithFrame:frame]; 41 if (self) { 42 // Initialization code 43 // NSLog(@"initWithFrame"); 44 [self setup]; 45 } 46 return self; 47 } 48 49 // 当视图从xib或storyboard中创建出来就会调用 50 - (id)initWithCoder:(NSCoder *)aDecoder 51 { 52 if (self = [super initWithCoder:aDecoder]) { 53 // 创建9个按钮 54 // NSLog(@"initWithCoder"); 55 [self setup]; 56 57 } 58 return self; 59 } 60 61 /** 62 * 创建9个按钮添加到自定view中 63 */ 64 - (void)setup 65 { 66 for (int i = 0; i < 9; i++) { 67 // 1.创建按钮 68 UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 69 // 2.设置按钮的背景图片 70 [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal]; 71 72 [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected]; 73 74 // 3.添加按钮到View 75 [self addSubview:btn]; 76 77 // btn.backgroundColor = [UIColor redColor]; 78 79 // 4.禁止按钮的点击事件(因为我们需要监听触摸事件) 80 btn.userInteractionEnabled = NO; 81 82 // 5.设置按钮的tag作为唯一标识 83 btn.tag = i; 84 } 85 } 86 87 - (void)layoutSubviews 88 { 89 [super layoutSubviews]; 90 // 设置按钮的frame 91 for (int i = 0; i < self.subviews.count; i++) { 92 // 1.取出对应位置的按钮 93 UIButton *btn = self.subviews[i]; 94 95 // 2.设置frame 96 CGFloat btnW = 74; 97 CGFloat btnH = 74; 98 // 2.1计算间距 99 CGFloat margin = (self.frame.size.width - (3 * btnW)) / 4; 100 int col = i % 3; // 列号 101 int row = i / 3; // 行号 102 // 间距 + 列号 * (按钮宽度+ 间距) 103 CGFloat btnX = margin + col * (btnW + margin); 104 CGFloat btnY = margin + row * (btnW + margin); 105 106 btn.frame = CGRectMake(btnX, btnY, btnW, btnH); 107 } 108 109 110 } 111 112 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 113 { 114 // 1.获取按下的点 115 CGPoint startPoint = [self getCurrentTouchPoint:touches]; 116 117 // 2.判断触摸的位置是否在按钮的范围内 118 UIButton *btn = [self getCurrentBtnWithPoint:startPoint]; 119 120 // 存储按钮 121 if (btn) 122 { 123 // 设置选中状态 124 btn.selected = YES; 125 // 将按钮保存到数组中 126 [self.buttons addObject:btn]; 127 } 128 129 btn.selected = YES; 130 131 // [self setNeedsDisplay]; 132 133 } 134 135 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 136 { 137 // 1.获取按下的点 138 CGPoint movePoint = [self getCurrentTouchPoint:touches]; 139 // 2.获取触摸的按钮 140 UIButton *btn = [self getCurrentBtnWithPoint:movePoint]; 141 142 // 存储按钮 143 if (btn && btn.selected != YES) 144 { 145 // 设置选中状态 146 btn.selected = YES; 147 // 将按钮保存到数组中 148 [self.buttons addObject:btn]; 149 } 150 // 记录当前手指移动的位置 151 self.currentPoint = movePoint; 152 153 // 通知view绘制线段 154 [self setNeedsDisplay]; 155 156 } 157 158 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 159 { 160 161 // 取出用户输入的密码 162 NSMutableString *result = [NSMutableString string]; 163 for (UIButton *btn in self.buttons) { 164 [result appendFormat:@"%d", btn.tag ]; 165 } 166 // NSLog(@"result = %@", result); 167 // 通知代理,告诉代理用户输入的密码 168 if ([self.delegate respondsToSelector:@selector(lockViewDidClick:andPwd:)]) { 169 [self.delegate lockViewDidClick:self andPwd:result]; 170 } 171 172 [self.buttons makeObjectsPerformSelector:@selector(setSelected:) withObject:@(NO)]; 173 174 // 清空数组 175 [self.buttons removeAllObjects]; 176 [self setNeedsDisplay]; 177 178 // 清空currentPoint 179 self.currentPoint = CGPointZero; 180 } 181 182 183 - (void)drawRect:(CGRect)rect 184 { 185 186 CGContextRef ctx = UIGraphicsGetCurrentContext(); 187 188 // 清空上下文 189 CGContextClearRect(ctx, rect); 190 191 // 从数组中取出所有的按钮, 连接所有按钮的中点 192 for (int i = 0; i < self.buttons.count; i++) { 193 // 取出按钮 194 UIButton *btn = self.buttons[i]; 195 if (0 == i) { 196 CGContextMoveToPoint(ctx, btn.center.x, btn.center.y); 197 }else 198 { 199 CGContextAddLineToPoint(ctx, btn.center.x, btn.center.y); 200 } 201 } 202 203 // 判断如果当前点是00就不会只 204 // if (!CGPointEqualToPoint(self.currentPoint, CGPointZero)) { 205 // 206 // // 当所有的按钮的中点都连接号之后再连接手指当前的位置 207 // CGContextAddLineToPoint(ctx, self.currentPoint.x, self.currentPoint.y); 208 // } 209 210 // 判断数组中是否有按钮, 如果有按钮就有起点, 有起点就不会报错 211 if (self.buttons.count != 0) { 212 213 CGContextAddLineToPoint(ctx, self.currentPoint.x, self.currentPoint.y); 214 } 215 216 217 // [[UIColor greenColor] set]; 218 219 [[UIColor colorWithRed:18/255.0 green:102/255.0 blue:72/255.0 alpha:0.5] set]; 220 CGContextSetLineWidth(ctx, 10); 221 CGContextSetLineJoin(ctx, kCGLineJoinRound); 222 CGContextSetLineCap(ctx, kCGLineCapRound); 223 CGContextStrokePath(ctx); 224 } 225 226 /** 227 * 根据系统传入的UITouch集合获取当前触摸的点 228 * @return 当初触摸的点 229 */ 230 - (CGPoint)getCurrentTouchPoint:(NSSet *)touches 231 { 232 // 1.获取按下的点 233 UITouch *touch = [touches anyObject]; 234 CGPoint point = [touch locationInView:touch.view]; 235 return point; 236 } 237 238 /** 239 * 根据触摸点获取触摸到的按钮 240 * @return 触摸的按钮 241 */ 242 - (UIButton *)getCurrentBtnWithPoint:(CGPoint)point 243 { 244 // 2.判断触摸的位置是否在按钮的范围内 245 for (UIButton *btn in self.subviews) { 246 // 247 if (CGRectContainsPoint(btn.frame, point)) { 248 return btn; 249 } 250 } 251 return nil; 252 } 253 @end
时间: 2024-10-25 21:34:45