iOS实现手势解锁操作

本文主要介绍通过手势识别实现手势解锁功能,这个方法被广泛用于手机解锁,密码验证,快捷支付等功能实现。事例效果如下所示。

 首先,我们先分析功能的实现过程,首先我们需要先看大致的实现过程:

1.加载九宫格页面

2.实现按钮被点击及滑动过程中按钮状态的改变

3.实现滑动过程中的连线

4.绘制完毕后判定密码是否正确,

5.密码判定后实现跳转。

下面我们就来用代码实现上述五个过程。

1.加载九宫格界面

1.1九宫格内控件的分布 3*3 ,我们可以自定义view(包含3*3个按钮),添加到viewController上。

//添加view中子控件

-(void)awakeFromNib

{

// 创建按钮

for (int i=0; i<9; i++) {

self.LineColor=[UIColor blueColor];

UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];

btn.userInteractionEnabled=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:UIControlStateDisabled];

[self addSubview:btn];

}

}

//布局view子控件

-(void)layoutSubviews

{

[super layoutSubviews];

CGFloat width=74;

CGFloat height=74;

CGFloat Margin=(self.bounds.size.width-3*width)/2;

// 遍历设置9个button的frame

[self.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

// 通过tag设置按钮的索引标识

obj.tag=idx;

int row=(int)idx/3;

int col=idx%3;

obj.frame=CGRectMake(col*(Margin + width), row*(Margin +height), width, height);

}];

}

1.2将定义好的view通过xib添加到viewController上

首先,定义一个blockview(九宫格view)的类方法,

// 加载xib文件

+(instancetype)lockView

{

return [[[NSBundle mainBundle]loadNibNamed:@"MYblockView" owner:nil options:nil]lastObject];

}

然后加载到控制器上。

// 设置控制器view的背景图片

self.view.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"bg"]];

MYblockView *blockView=[MYblockView lockView];

blockView.center=self.view.center;

// 将blockview添加到viewController上

[self.view addSubview:blockView];

2.实现按钮被点击及滑动过程中按钮状态的改变

2.1定义数组类型的成员属性,用来装被点击的按钮

@property(nonatomic,span)NSMutableArray *btnArr;

//懒加载

-(NSMutableArray *)btnArr

{

if (_btnArr==nil) {

_btnArr=[NSMutableArray array];

}

return _btnArr;

}

2.2创建路径,绘制图形

#pragma mark----绘制图形

-(void)drawRect:(CGRect)rect

{

if (self.btnArr.count==0 ) {

return;

}

// 创建路径

UIBezierPath *path=[UIBezierPath bezierPath];

// 遍历所有按钮进行绘制

[self.btnArr enumerateObjectsUsingBlock:^(__kindof UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

// 第一个按钮,中心点就是起点

if (idx==0) {

[path moveToPoint:obj.center];

}else

{

[path addLineToPoint:obj.center];

}

}];

[path addLineToPoint:self.currentPoint];

// 设置路径属性

path.lineWidth=10;

path.lineCapStyle=kCGLineCapRound;

path.lineJoinStyle=kCGLineJoinRound;

[self.LineColor setStroke];

// 渲染

[path stroke];

}

2.3开始触摸

#pragma mark-----开始触摸

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

// 获取触摸对象

UITouch *touch=touches.anyObject;

// 获取触摸点

CGPoint loc=[touch locationInView:self];

// 遍历按钮,判定触摸点是否在按钮上

[self.subviews enumerateObjectsUsingBlock:^(__kindof UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

BOOL isContains=CGRectContainsPoint(obj.frame, loc);

// 如果在按钮上,将当前按钮保存在数组中,并改变按钮状态

if (isContains&&obj.highlighted==NO) {

[self.btnArr addObject:obj];

obj.highlighted=YES;

}else

{

obj.highlighted=NO;

}

}];

}

2.4滑动过程中,重绘

#pragma mark----开始滑动

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

// 获取触摸对象

UITouch *touch=touches.anyObject;

// 获取触摸点

CGPoint loc=[touch locationInView:self];

self.currentPoint=loc;

// 遍历按钮,如果按钮在滑动路径上,就改变按钮状态

[self.subviews enumerateObjectsUsingBlock:^(__kindof UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

BOOL isContains=CGRectContainsPoint(obj.frame, loc);

if (isContains&&obj.highlighted==NO) {

[self.btnArr addObject:obj];

obj.highlighted=YES;

}

}];

// 重绘

[self setNeedsDisplay];

}

3.实现滑动过程中的连线和4.绘制完毕后判定密码是否正确

#pragma mark----停止滑动结束

-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

// 定义最后一个按钮

UIButton *lastBtn=[self.btnArr lastObject];

// 将最后一个按钮中心点定义为相对滑动的当前点

self.currentPoint=lastBtn.center;

// 重绘

[self setNeedsDisplay];

// 判定密码

self.password=[NSMutableString string];

[self.btnArr enumerateObjectsUsingBlock:^( UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

[self.password appendFormat:@"%@",@(obj.tag)];

}];

NSLog(@"%@",self.password);

BOOL isOk;

if ([self.delegate respondsToSelector:@selector(blockView:finishedWithPassword:)]) {

isOk= [self.delegate blockView:self finishedWithPassword:self.password];

}

if (isOk) {

[self.btnArr enumerateObjectsUsingBlock:^(UIButton* _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

obj.highlighted=NO;

}];

[self.btnArr removeAllObjects];

[self setNeedsDisplay];

NSLog(@"密码正确");

}else

{

NSLog(@"密码错误");

}

}

注意:我们在密码判定过程中是通过根据先前布局按钮的时候定义的按钮tag值进行字符串拼接,密码传值是通过代理实现。

#import <UIKit/UIKit.h>

@class MYblockView;

//声明代理

@protocol MYblockViewDelegate <NSObject>

@optional

//代理方法

-(BOOL) blockView:(MYblockView *)blockView finishedWithPassword:(NSString *)password;

@end

@interface MYblockView : UIView

+(instancetype)lockView;

//设置代理成员属性

@property(nonatomic,weak)id<MYblockViewDelegate>delegate;

@end

5.密码判定后实现跳转。

else

{

// 关闭用户交互

self.userInteractionEnabled=NO;

[self.btnArr enumerateObjectsUsingBlock:^(UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

self.LineColor=[UIColor redColor];

obj.highlighted=NO;

obj.enabled=NO;

[self setNeedsDisplay];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

// 回复按钮状态

[self.btnArr enumerateObjectsUsingBlock:^(UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

obj.enabled=YES;

}];

// 恢复线条的颜色

self.LineColor=[UIColor blueColor];

[self.btnArr removeAllObjects];

[self setNeedsDisplay];

});

}];

NSLog(@"密码错误");

}

self.userInteractionEnabled=YES;

}

代理判定密码并实现跳转

-(BOOL)blockView:(MYblockView *)blockView finishedWithPassword:(NSString *)password

{

if ([password isEqualToString:@"012"]) {

UIViewController *two=[UIViewController new];

two.view.backgroundColor=[UIColor greenColor];

[self.navigationController pushViewController:two animated:YES];

return YES;

}

else{

return NO;

}

}

最后设置控制器navigationbar属性

[self.navigationController.navigationBar setBackgroundColor:[UIColor redColor]];

[ self.navigationController.navigationBar setTitleTextAttributes:@{

NSForegroundColorAttributeName :[UIColor whiteColor]

}];

以上是 iOS实现手势解锁操作 的全部内容, 来源链接: utcz.com/z/346868.html

回到顶部