BOERLockView.h
// // BOERLockView.h // BoerScore // // Created by ChenQianPing on 16/2/18. // Copyright © 2016年 boer. All rights reserved. // #import <UIKit/UIKit.h> @class BOERLockView; @protocol BOERLockViewDelegate <NSObject> // 结束手势解锁代理事件 @optional - (void) boerLockView:(BOERLockView *) boerLockView didFinishedWithPath:(NSString *) path; @end @interface BOERLockView : UIView // 代理 @property(nonatomic, weak) IBOutlet id<BOERLockViewDelegate> delegate; @end
BOERLockView.m
// // BOERLockView.m // BoerScore // // Created by ChenQianPing on 16/2/18. // Copyright © 2016年 boer. All rights reserved. // #import "BOERLockView.h" #import "BOERLockButton.h" #define BUTTON_COUNT 9 #define BUTTON_COL_COUNT 3 @interface BOERLockView() // 已选择按钮数组 @property(nonatomic, strong) NSMutableArray *selectedButtons; // 触摸位置 @property(nonatomic, assign) CGPoint currentTouchLocation; @end @implementation BOERLockView // 初始化数组 - (NSMutableArray *)selectedButtons { if (nil == _selectedButtons) { _selectedButtons = [NSMutableArray array]; } return _selectedButtons; } #pragma mark - 初始化方法 // 使用文件初始化 - (id)initWithCoder:(NSCoder *)aDecoder { if (self = [super initWithCoder:aDecoder]) { [self initView]; } return self; } // 使用代码初始化 - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { [self initView]; } return self; } // 初始化view内的控件(按钮) - (void) initView { // 设置透明背景 self.backgroundColor = [[UIColor alloc] initWithRed:1 green:1 blue:1 alpha:0]; for (int i=0; i<BUTTON_COUNT; i++) { BOERLockButton *button = [BOERLockButton buttonWithType:UIButtonTypeCustom]; // 设置指标tag,用来记录轨迹 button.tag = i; // 加入按钮到lock view [self addSubview:button]; } } // 设置按钮位置尺寸 - (void)layoutSubviews { [super layoutSubviews]; // 取出所有按钮 for (int i=0; i<self.subviews.count; i++) { BOERLockButton *button = self.subviews[i]; CGFloat buttonWidth = 74; CGFloat buttonHeight = 74; // 此按钮所在列号 int col = i % BUTTON_COL_COUNT; // 此按钮所在行号 int row = i / BUTTON_COL_COUNT; // 等分水平多余空间,计算出间隙 CGFloat marginX = (self.frame.size.width - BUTTON_COL_COUNT * buttonWidth) / (BUTTON_COL_COUNT + 1); CGFloat marginY = marginX; // x坐标 CGFloat buttonX = marginX + col * (buttonWidth + marginX); // y坐标 CGFloat buttonY = marginY + row * (buttonHeight + marginY); button.frame = CGRectMake(buttonX, buttonY, buttonWidth, buttonHeight); } } #pragma mark - 触摸事件 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self touchesMoved:touches withEvent:event]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint touchLocation = [touch locationInView:touch.view]; // 检测哪个按钮被点中了 for (BOERLockButton *button in self.subviews) { // 如果触碰到了此按钮 if (CGRectContainsPoint(button.touchFrame, touchLocation)) { button.selected = YES; // 如果此按钮没有被触碰过才进行处理 if (![self.selectedButtons containsObject:button]) { // 加入到数组 [self.selectedButtons addObject:button]; } } // 当前触摸位置 self.currentTouchLocation = touchLocation; } // 重绘 [self setNeedsDisplay]; } - (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { // 轨迹序列 NSMutableString *passPath = [NSMutableString string]; // 合成轨迹序列 for (BOERLockButton *button in self.selectedButtons) { // 清除选中状态 button.selected = NO; // 添加到轨迹序列 [passPath appendFormat:@"%ld", button.tag]; } // NSLog(@"1 %@",passPath); // 调用代理方法 if ([self.delegate respondsToSelector:@selector(boerLockView:didFinishedWithPath:)]) { [self.delegate boerLockView:self didFinishedWithPath:passPath]; // NSLog(@"2 %@",passPath); } // 清除选中状态,发现这种方法在真机8.2系统中不能起作用 [self.selectedButtons makeObjectsPerformSelector:@selector(setSelected:) withObject:@(NO)]; // 清空数组 [self.selectedButtons removeAllObjects]; // 重绘 [self setNeedsDisplay]; } #pragma mark - 绘图方法 - (void)drawRect:(CGRect)rect { UIBezierPath *path = [UIBezierPath bezierPath]; // 遍历已选择按钮数组 for (int i=0; i<self.selectedButtons.count; i++) { BOERLockButton *button = self.selectedButtons[i]; if (0 == i) { [path moveToPoint:button.center]; } else { [path addLineToPoint:button.center]; } } if (self.selectedButtons.count) { [path addLineToPoint:self.currentTouchLocation]; } // 设置画笔 [[UIColor redColor] set]; [path setLineWidth:10]; [path setLineCapStyle:kCGLineCapRound]; [path setLineJoinStyle:kCGLineJoinBevel]; [path stroke]; } @end
BOERLockButton.h
// // BOERLockButton.h // BoerScore // // Created by ChenQianPing on 16/2/18. // Copyright © 2016年 boer. All rights reserved. // #import <UIKit/UIKit.h> @interface BOERLockButton : UIButton // 可触碰范围 @property(nonatomic, assign) CGRect touchFrame; @end
BOERLockButton.m
// // BOERLockButton.m // BoerScore // // Created by ChenQianPing on 16/2/18. // Copyright © 2016年 boer. All rights reserved. // #import "BOERLockButton.h" @implementation BOERLockButton // 使用文件创建会调用 - (id)initWithCoder:(NSCoder *)aDecoder { if (self = [super initWithCoder:aDecoder]) { [self initLockButton]; } return self; } // 使用代码创建会调用 - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { [self initLockButton]; } return self; } // 初始化 - (void) initLockButton { // 取消交互事件(点击) self.userInteractionEnabled = NO; // 设置普通状态图片 [self setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal]; // 设置选中状态图片 [self setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected]; } - (void)layoutSubviews { [super layoutSubviews]; // 可触碰范围 CGFloat touchWidth = 24; CGFloat touchHeight = 24; CGFloat touchX = self.center.x - touchWidth/2; CGFloat touchY = self.center.y - touchHeight/2; self.touchFrame = CGRectMake(touchX, touchY, 24, 24); } @end
ViewController.m
// // ViewController.m // BoerScore // // Created by ChenQianPing on 16/2/18. // Copyright © 2016年 boer. All rights reserved. // #import "ViewController.h" #import "BOERLockView.h" @interface ViewController () <BOERLockViewDelegate> //storyboard连线 @property (weak, nonatomic) IBOutlet BOERLockView *showView; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 设置背景 self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Home_refresh_bg"]]; self.showView.delegate = self; } // 设置状态栏样式 - (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)boerLockView:(BOERLockView *)boerLockView didFinishedWithPath:(NSString *)path { NSLog(@"手势解锁的输出序列:%@", path); } @end
时间: 2024-10-08 09:10:16