/*
说明:总共四个文件
包含:
ViewController.h
ViewController.h
FFFView.h
FFFView.h
*/
#import "ViewController.h"
#import "FFFView.h"
#import "TestViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet FFFView* passwordView;
@property (weak, nonatomic) IBOutlet UIImageView* imageView;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// 设置背景图片
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Home_refresh_bg"]];
self.passwordView.pwdBlock = ^(NSString* pwd, UIImage* img) {
// 密码
NSString* pwd1 = @"012";
if ([pwd isEqualToString:pwd1]) {
NSLog(@"密码正确");
// 跳转
TestViewController* vc = [[TestViewController alloc] init];
vc.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"main"]];
[self presentViewController:vc animated:YES completion:nil];
self.imageView.image = nil;
return YES;
}
else {
NSLog(@"密码错误");
self.imageView.image = img;
return NO;
}
};
}
@end
#import <UIKit/UIKit.h>
@interface FFFView : UIView
@property (nonatomic, copy) BOOL (^pwdBlock)(NSString*, UIImage*);
@end
#import "FFFView.h"
#import "SVProgressHUD.h"
#define kBtnCount 9
@interface CZView ()
@property (nonatomic, strong) NSMutableArray* btns;
@property (nonatomic, strong) NSMutableArray* lineBtns;
@property (nonatomic, assign) CGPoint currentPoint;
@end
@implementation FFFView
// 初始化 需要画线的数组
- (NSMutableArray*)lineBtns
{
if (!_lineBtns) {
_lineBtns = [NSMutableArray array];
}
return _lineBtns;
}
// 初始化 数组 所有的按钮
- (NSMutableArray*)btns
{
if (!_btns) {
_btns = [NSMutableArray array];
// 创建 9 个 btn
for (int i = 0; i < kBtnCount; i++) {
UIButton* btn = [[UIButton alloc] init];
// 绑定tag 相当于密码
btn.tag = i;
[btn setUserInteractionEnabled:NO];
// 设置默认的按钮样式
[btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
// 设置高亮的图片
[btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateHighlighted];
// 设置错误的样式
[btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_error"] forState:UIControlStateSelected];
// 添加到数组当中
[self.btns addObject:btn];
[self addSubview:btn];
}
}
return _btns;
}
// 触摸view的时候 调用
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
// 获取touch对象
UITouch* t = touches.anyObject;
// 获取点击的点
CGPoint point = [t locationInView:t.view];
// 遍历所有的按钮
for (int i = 0; i < self.btns.count; i++) {
UIButton* btn = self.btns[i];
// 按钮的frame是否包含了点击的点
if (CGRectContainsPoint(btn.frame, point)) {
btn.highlighted = YES;
// 判断这个按钮是不是已经添加到了 数组当中 如果没有再添加
if (![self.lineBtns containsObject:btn]) {
// 添加到需要连线的数组当中
[self.lineBtns addObject:btn];
}
}
}
}
// 手指移动
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
// 获取touch对象
UITouch* t = touches.anyObject;
// 获取点击的点
CGPoint point = [t locationInView:t.view];
// 获取移动时候手指的位置
self.currentPoint = point;
// 遍历所有的按钮
for (int i = 0; i < self.btns.count; i++) {
UIButton* btn = self.btns[i];
// 按钮的frame是否包含了点击的点
if (CGRectContainsPoint(btn.frame, point)) {
btn.highlighted = YES;
// 判断这个按钮是不是已经添加到了 数组当中 如果没有再添加
if (![self.lineBtns containsObject:btn]) {
// 添加到需要连线的数组当中
[self.lineBtns addObject:btn];
}
}
}
// 重绘
[self setNeedsDisplay];
}
// 手指抬起
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
// 解决 错误的时候 最后手指的位置不连接
self.currentPoint = [[self.lineBtns lastObject] center];
[self setNeedsDisplay];
NSString* password = @"";
// 输出密码
for (int i = 0; i < self.lineBtns.count; i++) {
// 拼接按钮的tag
password = [password stringByAppendingString:[NSString stringWithFormat:@"%ld", [self.lineBtns[i] tag]]];
}
for (int i = 0; i < self.lineBtns.count; i++) {
UIButton* btn = self.lineBtns[i];
btn.selected = YES;
btn.highlighted = NO;
}
// 开启上下文
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
// 获取上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
[self.layer renderInContext:ctx];
// 通过上下文获取图片
UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
// 关闭上下文
UIGraphicsEndImageContext();
if (self.pwdBlock) {
if (self.pwdBlock(password, image)) {
[SVProgressHUD showSuccessWithStatus:@"密码正确"];
[self clear];
}
else {
[SVProgressHUD showErrorWithStatus:@"密码错误"];
}
}
// 在恢复之前 不能让用户进行连线
[self setUserInteractionEnabled:NO];
// 显示错误的样式 1秒钟
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 恢复以后再把用户交互打开
[self setUserInteractionEnabled:YES];
[self clear];
});
}
// 恢复到初始的状态
- (void)clear
{
// 遍历所有的按钮
for (int i = 0; i < self.btns.count; i++) {
UIButton* btn = self.btns[i];
btn.highlighted = NO;
btn.selected = NO;
}
// 恢复原始状态
[self.lineBtns removeAllObjects];
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
// 创建路径对象
UIBezierPath* path = [UIBezierPath bezierPath];
for (int i = 0; i < self.lineBtns.count; i++) {
if (i == 0) {
[path moveToPoint:[self.lineBtns[i] center]];
}
else {
[path addLineToPoint:[self.lineBtns[i] center]];
}
}
if (self.lineBtns.count) {
// 连接到手指的位置
[path addLineToPoint:self.currentPoint];
}
// 设置颜色
[[UIColor whiteColor] set];
// 设置线宽
[path setLineWidth:10];
// 设置连接处的样式
[path setLineJoinStyle:kCGLineJoinRound];
// 设置头尾的样式
[path setLineCapStyle:kCGLineCapRound];
// 渲染
[path stroke];
}
// 布局九宫格
- (void)layoutSubviews
{
[super layoutSubviews];
// 计算九宫格位置
CGFloat w = 74;
CGFloat h = w;
int colCount = 3;
CGFloat margin = (self.frame.size.width - 3 * w) / 4;
for (int i = 0; i < self.btns.count; i++) {
CGFloat x = (i % colCount) * (margin + w) + margin;
CGFloat y = (i / colCount) * (margin + w) + margin;
[self.btns[i] setFrame:CGRectMake(x, y, w, h)];
}
}
@end