iOS Quartz2D实战系列-手把手教你手势解锁
来源:互联网 发布:深圳信科网络 编辑:程序博客网 时间:2024/05/18 03:08
手势解锁
这是我模仿的QQ手势解锁部分界面~
密码输入错误效果
密码输入正确效果
界面粗糙,还请海涵~
接下来开始上代码了~
我是自定义了一个SpeedDailView继承于UIView的九宫格界面
解释都在注释里了
SpeedDialView.h
#import <UIKit/UIKit.h>@interface SpeedDialView : UIView//用来盛放选中的button@property (nonatomic,retain) NSMutableArray *btns;//输入的密码@property (nonatomic,strong) NSMutableString *code;//正确密码@property (nonatomic,strong) NSString *password;//触摸是否结束@property (nonatomic,assign) BOOL isEnd;@endSpeedDialView.m
#import "SpeedDialView.h"@implementation SpeedDialView- (instancetype)init{ self = [super init]; if (self) { } return self;}//懒加载- (NSMutableArray *)btns{ if (!_btns) { self.btns = [[NSMutableArray alloc]init]; } return _btns;}//创建9个按钮- (void)setUpBasicUI{ for (int i = 0; i < 9; i++) { UIButton *btn = [UIButton buttonWithType:(UIButtonTypeCustom)]; btn.tag = i; [self addSubview:btn]; }}//设置9个按钮的位置- (void)layoutSubviews{ [super layoutSubviews]; //这个方法只运行一次 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ [self setUpBasicUI]; }); //经典的9宫格算法 int totalColume = 3; CGFloat bWidth = 74; CGFloat bHeight = bWidth; CGFloat margin = (self.frame.size.width - bWidth * totalColume)/(totalColume + 1); for (int i = 0; i< self.subviews.count; i++) { int currentRow = i/totalColume; int currentColumn = i%totalColume; CGFloat originX = margin + (currentColumn * (margin + bWidth)); CGFloat originY = currentRow * (margin + bHeight); //设置Button的外观和大小 UIButton *btn = self.subviews[i]; [btn setImage:[UIImage imageNamed:@"xv"] forState:(UIControlStateNormal)]; [btn setImage:[UIImage imageNamed:@"shi"] forState:(UIControlStateSelected)]; btn.contentMode = UIViewContentModeCenter; btn.userInteractionEnabled = false; btn.frame = CGRectMake(originX, originY, bWidth, bHeight); } }//获取当前的触摸点的坐标- (CGPoint)pointWithTouches:(NSSet<UITouch *> *)touches{ UITouch *touch = [touches anyObject]; CGPoint point = [touch locationInView:touch.view]; return point;}//判断当前点在不在Button中- (UIButton *)buttonWithPoint:(CGPoint)point{ for (int i = 0; i < self.subviews.count; i++) { UIButton *btn = self.subviews[i]; CGFloat wh = btn.frame.size.width - 5; //找到Button中心附近25*25的面积 CGFloat frameX = btn.center.x - wh * 0.5; CGFloat frameY = btn.center.y - wh * 0.5; //判断这个点在button中心附近25*25的面积内的话就是它了 if (CGRectContainsPoint(CGRectMake(frameX, frameY, wh, wh), point)) { return btn; } } return nil;}//设置Button被选中的状态- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ //当触摸开始的时候将之前的痕迹抹掉 重新开始 self.code = [[NSMutableString alloc]init]; self.isEnd = NO; for (int i = 0; i < self.btns.count; i ++) { UIButton *btn = self.btns[i]; btn.selected = NO; } [self.btns removeAllObjects]; //找到touch到的点的位置(此处只有一个点 就是开始的那个点) CGPoint point = [self pointWithTouches:touches]; //判断这个点所在的Button UIButton *btn = [self buttonWithPoint:point]; if (btn != nil && btn.selected == false) { btn.selected = YES; //把button加到数组中 [self.btns addObject:btn]; //并记录走过的路线 用Button的tag拼接出的字符串 [self.code appendString:[NSString stringWithFormat:@"%ld",(long)btn.tag]]; } [self setNeedsDisplay];}- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ //找到touch到的点的位置 CGPoint point = [self pointWithTouches:touches]; //判断这个点所在的Button UIButton *btn = [self buttonWithPoint:point]; if (btn != nil && btn.selected == false) { btn.selected = YES; //把button加到数组中 [self.btns addObject:btn]; //并记录走过的路线 用Button的tag拼接出的字符串 [self.code appendString:[NSString stringWithFormat:@"%ld",(long)btn.tag]]; } [self setNeedsDisplay];}//使用touchend清空数据- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ //绘制选中的按钮少于3个的时候没有轨迹记录 if (self.btns.count < 3) { for (int i = 0; i < self.btns.count; i ++) { UIButton *btn = self.btns[i]; btn.selected = NO; } [self.btns removeAllObjects]; } else { //标志 结束 self.isEnd = YES; } [self setNeedsDisplay];}//优化 先判空-(void)drawRect:(CGRect)rect{ //如果没有选择的button 则不绘图 if (self.btns.count == 0) { return; } //使用贝塞尔曲线绘制路线 UIBezierPath * path = [UIBezierPath bezierPath]; for (int i = 0; i < self.btns.count; i ++) { UIButton *btn = self.btns[i]; if (i == 0) { [path moveToPoint:btn.center]; } else { [path addLineToPoint:btn.center]; } } //设置线的颜色 [[UIColor colorWithRed:23/255.0 green:171/255.0 blue:227/255.0 alpha:1] set]; //设置线的宽度 [path setLineWidth:3]; //设置连接风格 [path setLineJoinStyle:(kCGLineJoinRound)]; //判断是否结束 在touchEnd方法中更改isEnd的值 if (_isEnd == YES) { if (![self.code isEqualToString:self.password]) { //修改Path的颜色 [[UIColor redColor]set]; //发送通知 提醒ViewController更改Label上的文字 [[NSNotificationCenter defaultCenter] postNotificationName:@"changeLabel" object:nil]; } else { //发送通知 提醒ViewController更改Label上的文字 [[NSNotificationCenter defaultCenter]postNotificationName:@"changeLabel2" object:nil]; } } //渲染 [path stroke]; }@end使用方法
在ViewController的Xib里设计了界面,其中最下面正方形是关联SpeedDialView的View。
ViewController.m
<span style="font-size:18px;">@interface ViewController ()@property (weak, nonatomic) IBOutlet UILabel *label;@property (weak, nonatomic) IBOutlet SpeedDialView *speedDialView;@end@implementation ViewController- (void)viewWillAppear:(BOOL)animated{ self.label.text = @"请输入手势密码"; self.label.textColor = [UIColor darkGrayColor];}- (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(changeLabel) name:@"changeLabel" object:nil]; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(changeLabel2) name:@"changeLabel2" object:nil]; self.speedDialView.password = @"1345"; }- (void)changeLabel{ self.label.text = @"密码输入错误"; self.label.textColor = [UIColor redColor];}- (void)changeLabel2{ self.label.text = @"恭喜,密码输入正确"; self.label.textColor = [UIColor greenColor];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end</span>最后,就是成果展示了~
大功告成~
我对明天没有期待,因为我对今天满意~
UIButton图片提供
最后,提供Demo地址点击打开链接
我是写的OC版的,感谢简书作者王鑫20111Swift版传送门的无私分享~
实践所写,如有错误,还请指正,谢谢!
0 0
- iOS Quartz2D实战系列-手把手教你手势解锁
- 手把手教你使用Quartz2D制作彩色涂鸦板和手势解锁
- XMG Quartz2D 手势解锁(九宫格)
- 猫猫学IOS(三十五)UI之Quartz2D仿真支付宝手势解锁_代理获得密码。
- 手把手教你系列
- 手把手教你系列
- 手把手教你系列
- iOS 开发实战-锁屏界面(手势解锁)
- ios手势解锁
- IOS手势解锁
- iOS-手势解锁
- iOS手势解锁
- iOS简单手势解锁
- IOS手势解锁详解
- iOS 手势解锁密码
- iOS 一一 手势解锁
- (素材源码)猫猫学IOS(三十五)UI之Quartz2D仿真支付宝手势解锁_代理获得密码。
- (素材源码)猫猫学IOS(三十五)UI之Quartz2D仿真支付宝手势解锁_代理获得密码。
- java-IO 文件作为数据库的学生管理系统
- Dijkstra最短路径算法
- linux mysql
- String,StringBuffer,StringBuilder的区别
- leetcode:二叉树之Binary Tree Postorder Traversal
- iOS Quartz2D实战系列-手把手教你手势解锁
- 设计模式(九)模版方法模式
- HDU1024->线性DP
- PHP 闭包函数及Closure对象的总结
- dtrace 在redhat 6.2上 安装
- webview的两个方法:setWebChromeClient和setWebClient
- js实现CkeckBox全选与反选
- 密码盘 纪中 3067 状压dp
- poj 1698