源码0306-手势解锁
现搭建页面
// VCView.h // 06-手势解锁 #import <UIKit/UIKit.h> @interface VCView : UIView @end // VCView.m // 06-手势解锁 #import "VCView.h" @implementation VCView - (void)drawRect:(CGRect)rect { // 绘图图像 UIImage *image = [UIImage imageNamed:@"Home_refresh_bg"]; [image drawInRect:rect]; } @end // LockView.h // 06-手势解锁 #import <UIKit/UIKit.h> @interface LockView : UIView @end // LockView.m // 06-手势解锁 #import "LockView.h" @implementation LockView // 加载完xib的时候调用 - (void)awakeFromNib { // 创建9个按钮 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]; } } // 为什么要在这个方法布局子控件,因为只要一调用这个方法,就表示父控件的尺寸确定 - (void)layoutSubviews { [super layoutSubviews]; NSUInteger count = self.subviews.count; int cols = 3; CGFloat x = 0; CGFloat y = 0; CGFloat w = 74; CGFloat h = 74; CGFloat margin = (self.bounds.size.width - cols * w) / (cols + 1); CGFloat col = 0; CGFloat row = 0; for (NSUInteger i = 0; i < count; i++) { UIButton *btn = self.subviews[i]; // 获取当前按钮的列数 col = i % cols; row = i / cols; x = margin + col * (margin + w); y = row * (margin + w); btn.frame = CGRectMake(x, y, w, h); } } @end
07-手势解锁(按钮选中和连线)
// VCView.m // 06-手势解锁 #import "VCView.h" @implementation VCView - (void)drawRect:(CGRect)rect { // 绘图图像 UIImage *image = [UIImage imageNamed:@"Home_refresh_bg"]; [image drawInRect:rect]; } @end
// LockView.m // 06-手势解锁 #import "LockView.h" @interface LockView () @property (nonatomic, strong) NSMutableArray *selectedsBtn; @property (nonatomic, assign) CGPoint curP; @end @implementation LockView - (NSMutableArray *)selectedsBtn { if (_selectedsBtn == nil) { _selectedsBtn = [NSMutableArray array]; } return _selectedsBtn; } - (IBAction)pan:(UIPanGestureRecognizer *)pan { // 获取触摸点 _curP = [pan locationInView:self]; // 判断触摸点在不在按钮上 for (UIButton *btn in self.subviews) { // 点在不在某个范围内,并且按钮没有被选中 if (CGRectContainsPoint(btn.frame, _curP) && btn.selected == NO) { // 点在按钮上 btn.selected = YES; // 保存到数组中 [self.selectedsBtn addObject:btn]; } } // 重绘 [self setNeedsDisplay]; if (pan.state == UIGestureRecognizerStateEnded) { // 创建可变字符串 NSMutableString *strM = [NSMutableString string]; // 保存输入密码 for (UIButton *btn in self.selectedsBtn) { [strM appendFormat:@"%ld",btn.tag]; } NSLog(@"%@",strM); // 还原界面 // 取消所有按钮的选中 [self.selectedsBtn makeObjectsPerformSelector:@selector(setSelected:) withObject:@(NO)]; // 清除画线,把选中按钮清空 [self.selectedsBtn removeAllObjects]; } } // 加载完xib的时候调用 - (void)awakeFromNib { // 创建9个按钮 for ( int i = 0; i < 9; i++) { UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; // 不允许用户交互,按钮就不能点击,也就不能达到高亮状态 btn.userInteractionEnabled = NO; [btn setImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal]; [btn setImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected]; btn.tag = i; [self addSubview:btn]; } } // 为什么要在这个方法布局子控件,因为只要一调用这个方法,就表示父控件的尺寸确定 - (void)layoutSubviews { [super layoutSubviews]; NSUInteger count = self.subviews.count; int cols = 3; CGFloat x = 0; CGFloat y = 0; CGFloat w = 74; CGFloat h = 74; CGFloat margin = (self.bounds.size.width - cols * w) / (cols + 1); CGFloat col = 0; CGFloat row = 0; for (NSUInteger i = 0; i < count; i++) { UIButton *btn = self.subviews[i]; // 获取当前按钮的列数 col = i % cols; row = i / cols; x = margin + col * (margin + w); y = row * (margin + w); btn.frame = CGRectMake(x, y, w, h); } } // 只要调用这个方法,就会把之前绘制的东西全部清掉,重新绘制 - (void)drawRect:(CGRect)rect { // 没有选中按钮,不需要连线 if (self.selectedsBtn.count == 0) return; // 把所有选中按钮中心点连线 UIBezierPath *path = [UIBezierPath bezierPath]; NSUInteger count = self.selectedsBtn.count; // 把所有选中按钮之间都连好线 for (int i = 0; i < count; i++) { UIButton *btn = self.selectedsBtn[i]; if (i == 0) { // 设置起点 [path moveToPoint:btn.center]; }else{ [path addLineToPoint:btn.center]; } } // 连线到手指的触摸点 [path addLineToPoint:_curP]; [[UIColor greenColor] set]; path.lineWidth = 10; path.lineJoinStyle = kCGLineJoinRound; [path stroke]; } @end
本人无商业用途,仅仅是学习做个笔记,特别鸣谢小马哥,学习了IOS,另日语学习内容有需要文本和音频请关注公众号:riyuxuexishuji