iOS開發之手勢解鎖,ios手勢解鎖

來源:互聯網
上載者:User

iOS開發之手勢解鎖,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,strong)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]                                                                         }];

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.