zoukankan      html  css  js  c++  java
  • Quartz2D复习(二) --- 手势解锁

    这次支付宝手机客户端升级,把手势解锁那个功能去掉了,引起很多人的抱怨,觉得少了手势解锁的保护,个人信息容易泄漏了。。。

    那么手势解锁功能是怎么是实现的呢,这里使用Quart2D来简单模拟一下,

    先看下截图效果:

             

    按钮的有两个背景图片,一个默认样式,一个用于选中样式:

       

    代码实现:

    自定义view, 用来绘制所有路径,自定义view名称为:GestureLockView

    GestureLockView.h文件:

    #import <UIKit/UIKit.h>
    
    @interface GestureLockView : UIView
    
    @end
    

    GestureLockView.m文件代码:

      1 //  手势解锁
      2 
      3 #import "GestureLockView.h"
      4 
      5 @interface GestureLockView()
      6 
      7 @property (nonatomic, retain) NSMutableArray *selectBtns;
      8 @property (nonatomic, assign) CGPoint moveP; //移动的点
      9 
     10 @end
     11 
     12 @implementation GestureLockView
     13 
     14 - (instancetype)initWithFrame:(CGRect)frame{
     15     if (self = [super initWithFrame:frame]){
     16         [self addBtns];
     17         NSLog(@"initWithFrame: %s", __func__);
     18     }
     19     return self;
     20 }
     21 
     22 //解析xib的时候调用
     23 - (instancetype)initWithCoder:(NSCoder *)aDecoder{
     24     if (self = [super initWithCoder:aDecoder]){
     25         NSLog(@"initWithCoder: %s", __func__);
     26         [self addBtns];
     27     }
     28     return self;
     29 }
     30 
     31 //添加子按钮
     32 - (void)addBtns{
     33     for (int i = 0; i < 9; i++) {
     34         UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
     35         [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
     36         [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];
     37         [btn setUserInteractionEnabled:NO]; //设置不能和用户进行交互
     38         [btn setTag:i + 1]; //设置标识
     39         [self addSubview:btn];
     40     }
     41 }
     42 
     43 - (NSMutableArray *)selectBtns{
     44     if (_selectBtns == nil){
     45         _selectBtns = [[NSMutableArray alloc] init];
     46     }
     47     return _selectBtns;
     48 }
     49 
     50 //触摸开始
     51 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
     52     NSLog(@"触摸开始...");
     53     
     54     self.moveP = [self getPoint:touches];
     55     UIButton *btn = [self getBtn:self.moveP];
     56     
     57     if (btn != nil){
     58         [self.selectBtns addObject:btn];
     59         btn.selected = YES;
     60     }
     61 }
     62 
     63 //触摸移动, 设置被选中的按钮
     64 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
     65     //NSLog(@"触摸移动");
     66     self.moveP = [self getPoint:touches];
     67     UIButton *btn = [self getBtn:self.moveP];
     68     
     69     if (btn != nil && btn.selected == NO){
     70         [self.selectBtns addObject:btn];
     71         btn.selected = YES;
     72     }
     73     
     74     [self setNeedsDisplay]; //从新绘制
     75 }
     76 
     77 //触摸结束,一切归空
     78 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
     79     NSMutableString *str = [[NSMutableString alloc] init];
     80     for (UIButton * btn in self.selectBtns) {
     81         [str appendFormat:@"%i", btn.tag];
     82         btn.selected = NO;
     83     }
     84     
     85     self.moveP = CGPointZero;
     86     [self setNeedsDisplay];
     87     [self.selectBtns removeAllObjects];
     88     
     89 //    UILabel *lbl = [[UILabel alloc] init];
     90 //    lbl.text = [NSString stringWithFormat:@"密码是:%@", str];
     91 //    lbl.frame = CGRectMake(80, 150, 200, 30);
     92 //    [lbl setBackgroundColor:[UIColor whiteColor]];
     93 //    [lbl setTextAlignment:NSTextAlignmentCenter];
     94 //    [self addSubview:lbl];
     95 //    
     96 //    [UIView animateWithDuration:5.0 animations:^{
     97 //        lbl.alpha = 0.1;
     98 //    } completion:^(BOOL finished) {
     99 //        [lbl removeFromSuperview];
    100 //    }];
    101     
    102     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"设置结果为" message:str delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
    103     [alert show];
    104 }
    105 
    106 //监听触摸移动,获取触摸坐标
    107 - (CGPoint)getPoint: (NSSet *)touches{
    108     UITouch *touch = [touches anyObject]; //获取当前接触点
    109     return [touch locationInView:self]; //获取当前触点在父对象中的位置
    110 }
    111 
    112 //根据坐标获取按钮对象
    113 - (UIButton *)getBtn: (CGPoint)point{
    114     for (UIButton * btn in self.subviews) {
    115         if (CGRectContainsPoint(btn.frame, point)){
    116             return btn;
    117         }
    118     }
    119     return nil;
    120 }
    121 
    122 //布局子控件的坐标位置
    123 - (void)layoutSubviews{
    124     CGFloat width = 74;
    125     CGFloat height = width;
    126     CGFloat cols = 3;
    127     CGFloat rows = cols;
    128     CGFloat margin = ([UIScreen mainScreen].bounds.size.width - width * cols) / (cols + 1);
    129     
    130     for (int i = 0; i < rows; i++) {
    131         for (int j = 0; j < cols; j++) {
    132             CGFloat x = j * (width + margin) + margin;
    133             CGFloat y = i * (height + margin) + margin;
    134             UIButton *btn = (UIButton *)[self.subviews objectAtIndex: (i * rows) + j];
    135             btn.frame = CGRectMake(x, y, width, height);
    136         }
    137     }
    138 }
    139 
    140 
    141 //
    142 // Only override drawRect: if you perform custom drawing.
    143 // An empty implementation adversely affects performance during animation.
    144 //从新绘制
    145 - (void)drawRect:(CGRect)rect {
    146     //1、获取当前上下文
    147     CGContextRef ctr = UIGraphicsGetCurrentContext();
    148     //2、绘制路径
    149     UIBezierPath *path = [UIBezierPath bezierPath];
    150     CGContextSetLineWidth(ctr, 8);  //设置线段宽度
    151     CGContextSetLineJoin(ctr, kCGLineJoinRound); //设置转折点
    152     [[UIColor whiteColor] set]; //设置路径颜色
    153     
    154     [path moveToPoint:self.moveP];
    155     
    156     for (int i = 0; i < self.selectBtns.count; i++) {
    157         UIButton *btn = (UIButton *)[self.selectBtns objectAtIndex:i];
    158         CGPoint point = btn.center;
    159         
    160         if (i == 0){
    161             [path moveToPoint:point];
    162         }
    163         else{
    164             [path addLineToPoint:point];
    165         }
    166     }
    167     
    168     if (!CGPointEqualToPoint(self.moveP, CGPointZero)){
    169         [path addLineToPoint:self.moveP]; //重点路径
    170     }
    171     //3、把路径添加到上下文中
    172     CGContextAddPath(ctr, path.CGPath);
    173 
    174     //4、渲染
    175     CGContextStrokePath(ctr);
    176 }
    177 
    178 
    179 @end
    View Code

    自定义控制器来展示自定义手势解锁view

    GestureLockViewController.h : 

    #import <UIKit/UIKit.h>
    
    @interface GestureLockViewController : UIViewController
    
    @end

    GestureLockViewController.m文件代码:

     1 #import "GestureLockViewController.h"
     2 #import "GestureLockView.h"
     3 
     4 @interface GestureLockViewController ()
     5 
     6 @end
     7 
     8 @implementation GestureLockViewController
     9 
    10 - (void)viewDidLoad {
    11     [super viewDidLoad];
    12     // Do any additional setup after loading the view.
    13     [self.view setBackgroundColor:[UIColor whiteColor]];
    14     
    15     //返回按钮
    16     UIButton *preBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    17     [preBtn setFrame:CGRectMake(10, 420, 80, 25)];
    18     [preBtn setBackgroundColor:[UIColor purpleColor]];
    19     [preBtn setTitle:@"返回" forState:UIControlStateNormal];
    20     [preBtn addTarget:self action:@selector(prePage) forControlEvents:UIControlEventTouchUpInside];
    21     [self.view addSubview:preBtn];
    22     
    23     //增加view
    24     CGSize size = [UIScreen mainScreen].bounds.size;
    25     GestureLockView *view = [[GestureLockView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.width + 30)];
    26     [view setBackgroundColor:[UIColor blackColor]];
    27     [self.view addSubview:view];
    28 }
    29 
    30 - (void)prePage{
    31     [self dismissViewControllerAnimated:YES completion:nil];
    32 }
    33 
    34 - (void)didReceiveMemoryWarning {
    35     [super didReceiveMemoryWarning];
    36     // Dispose of any resources that can be recreated.
    37 }
    38 
    39 /*
    40 #pragma mark - Navigation
    41 
    42 // In a storyboard-based application, you will often want to do a little preparation before navigation
    43 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    44     // Get the new view controller using [segue destinationViewController].
    45     // Pass the selected object to the new view controller.
    46 }
    47 */
    48 
    49 @end
    View Code
  • 相关阅读:
    php 有趣的头像拼图
    php基础篇-二维数组排序姐妹篇
    php基础篇-二维数组排序 array_multisort
    php应用篇-百度图片的防盗链
    《留给自己,也留给每一位在青春里迷茫找不到自己的年轻人》 爱你现在的时光——白岩松
    没有什么能一下打垮你,就像没有什么能一下拯救你
    php基础篇-双引号、单引号的区别
    TortoiseSVN Start
    cover-view文案被切割:加全角空格
    canvas不显示,必须设置canvas-id
  • 原文地址:https://www.cnblogs.com/tandaxia/p/4672044.html
Copyright © 2011-2022 走看看