ViewController.m
//
// ViewController.m
// 6A08.手势解锁
//
// Created by huan on 16/2/1.
// Copyright © 2016年 huanxi. All rights reserved.
//
#import "ViewController.h"
#import "CZLockView.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//添加背景
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Home_refresh_bg"]];
CZLockView *lockView = [[CZLockView alloc] init];
CGFloat screenW = [UIScreen mainScreen].bounds.size.width;
lockView.bounds = CGRectMake(0, 0, screenW, screenW);
lockView.backgroundColor = [UIColor clearColor];
lockView.center = self.view.center;
[self.view addSubview:lockView];
/**
* A.默认排版
*1.自定义一个View
*2.添加到控制器view
*3.自定义view添加按钮
* B.设置选中的按钮
1.判断当前这个触摸点在不在按钮的范围内,如果存在按钮范围内,设置按钮的选取状态
* C.设置按钮间的连线 UIBezierPath
* 1.记录所有选中按钮 放一个数组
* 2.遍历选中按钮的数组 进行绘制“线”
* 3.手指抬开的时候,取消连线
* D.添加最后一点的连线
* 1.添加一个属性记录最后的接触点
* 2.在drawRect方法,画线的时候,追加一个点
* E.选完密码后通知控制器
* 1.添加代理
* 2.拼接选中按钮的索引[touchesEnd] 012345
* 3.通知代理
*/
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
CZLockView.h
#import <UIKit/UIKit.h>
@class CZLockView;
@protocol CZLockViewDelegate<NSObject>
-(void)lockView:(CZLockView *)lockView didSeletedPassword:(NSString *)password;
@end
@interface CZLockView : UIView
@property (nonatomic, weak) id<CZLockViewDelegate>delegate;
@end
CZLockView.m
//
// CZLockView.m
// 6A08.手势解锁
//
// Created by huan on 16/2/1.
// Copyright © 2016年 huanxi. All rights reserved.
//
#import "CZLockView.h"
@interface CZLockView()
/**
* 选中的所有的按钮
*/
@property (nonatomic, strong) NSMutableArray *selectedBtns;
@property (nonatomic, assign) CGPoint lastPoint;
@end
@implementation CZLockView
-(NSMutableArray *)selectedBtns{
if (!_selectedBtns) {
_selectedBtns = [NSMutableArray array];
}
return _selectedBtns;
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
*/
- (void)drawRect:(CGRect)rect {
// Drawing code
//遍历所有有选中的按钮
NSInteger selectedCount = self.selectedBtns.count;
//CGPathAddLineToPoint(CGMutablePathRef _Nullable, const CGAffineTransform * _Nullable, CGFloat, CGFloat): no current point. 出现这样的问题,第一if语句可以解决。
if (selectedCount == 0) {
return;
}
//创建一个路径
UIBezierPath *path = [UIBezierPath bezierPath];
for (NSInteger i = 0; i < selectedCount; i++) {
CGPoint btnCenter = [self.selectedBtns[i] center];
if (i == 0) {
[path moveToPoint:btnCenter];
}else{
[path addLineToPoint:btnCenter];
}
}
//追加一个点的路径
[path addLineToPoint:self.lastPoint];
path.lineWidth = 5;
//连接点样式
path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinRound;
[[UIColor greenColor] set];
//渲染
[path stroke];
}
-(instancetype)initWithFrame:(CGRect)frame{
//初始化按钮
if (self = [super initWithFrame:frame]) {
[self setupBtns];
}
return self;
}
-(void)setupBtns{
//添加9个按钮
for (NSInteger i = 0; i < 9; i++) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
//绑定tag
btn.tag = i;
//设置默认图片
[btn setImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
//设置选中的图片
[btn setImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];
//设置按钮不可用
btn.userInteractionEnabled = NO;
[self addSubview:btn];
}
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
// 1.判断当前这个触摸点在不在按钮的范围内,如果存在按钮范围内,设置按钮的选取状态
//1.1 获取当前触摸点
UITouch *touch = [touches anyObject];
CGPoint touchP = [touch locationInView:touch.view];
//1.2 判断当前这个触摸点在不在按钮的范围内
//遍历所有的按钮
for (UIButton *btn in self.subviews) {
// 放在一个选中按钮的数组
if (CGRectContainsPoint(btn.frame, touchP)) {
if (btn.selected == NO) {
[self.selectedBtns addObject:btn];
}
//设置选中状态
btn.selected = YES;
NSLog(@"YES....");
}else{
//记录最后触摸点
self.lastPoint = touchP;
}
}
//重绘
[self setNeedsDisplay];
}
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSLog(@"选中按钮的个数 %ld", self.selectedBtns.count);
//拼接选中按钮的索引
NSMutableString *password = [NSMutableString string];
for (UIButton *selected in self.selectedBtns) {
[password appendFormat:@"%ld",selected.tag];
}
NSLog(@"password :%@", password);
// 手指抬开的时候,取消连线
//取消所有按钮的选中状态为NO
// [self.selectedBtns makeObjectsPerformSelector:@selector(setSelected:) withObject:@NO];// 这行代码并不能恢复按钮状态
for (UIButton *btn in self.subviews) {
// 放在一个选中按钮的数组
//设置选中状态
btn.selected = NO;
NSLog(@"YES....");
}
//移除所有选中的按钮
[self.selectedBtns removeAllObjects];
//重绘
[self setNeedsDisplay];
}
-(void)layoutSubviews{
[super layoutSubviews];
//重新布局9个按钮
CGFloat btW = 74;
CGFloat btH = 74;
NSInteger btnCount = self.subviews.count;
CGFloat padding = (self.frame.size.width - 3 * btW)/4;
for (NSInteger i = 0; i < btnCount; i++) {
UIButton *btn = self.subviews[i];
//当前按钮所处的列
NSInteger column = i % 3;
// 当前按钮所处的行
NSInteger row = i/3;
//计算每一个按钮的位置
// x = 间距 + (按钮的宽度 +间距)*列
CGFloat btnX = padding +(btW + padding) *column;
// y = 间距 +(按钮的高度 + 间距)*行
CGFloat btnY = padding + (btH + padding) *row;
btn.frame = CGRectMake(btnX, btnY, btW, btH);
}
}
@end