(转 部分修改) IOS 手势密码(简单版)

//
//  Created by wangtouwang on 15/4/7.
//  Copyright (c) 2015年 wangtouwang. All rights reserved.
//

#import <UIKit/UIKit.h>

@class YYLockView;
@protocol YYLockViewDelegate <NSObject>
//自定义一个协议
 //协议方法,把当前视图作为参数
 -(void)LockViewDidClick:(YYLockView *)lockView andPwd:(NSString *)pwd;
@end

@interface YYLockView : UIView

//代理
@property(nonatomic,weak) IBOutlet id<YYLockViewDelegate>delegate;

@end
//
//  YYLockView.m
//  Created by wangtouwang on 15/4/7.
//  Copyright (c) 2015年 wangtouwang. All rights reserved.
//

#import "YYLockView.h"
// 设置获取屏幕长宽全局变量
#define KSCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define KSCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
#define BUTTON_HEIGHT_MIDDLE_WIDTH_RADIO 1.22

@interface YYLockView ()
{
    UIView *newView;
}
@property(nonatomic,strong)NSMutableArray *buttons;
@property(nonatomic,strong)NSMutableArray *includButtons;

//定义一个属性,记录当前点
@property(nonatomic,assign)CGPoint currentPoint;

@end

@implementation YYLockView

#pragma mark-懒加载
-(NSMutableArray *)buttons
{
    if (_buttons==nil) {
        _buttons=[NSMutableArray array];
    }
    return _buttons;
}

#pragma mark-懒加载
-(NSMutableArray *)includButtons
{
    if (_includButtons==nil) {
        _includButtons=[NSMutableArray array];
    }
    return _includButtons;
}

-(id)initWithCoder:(NSCoder *)aDecoder
{
    NSLog(@"断点 B 号 ");
    if (self=[super initWithCoder:aDecoder]) {
        [self setup];
    }
    return self;
}

//界面搭建
- (id)initWithFrame:(CGRect)frame
{
    NSLog(@"断点  1 号 ");
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
    }
    return self;
}

//在界面上创建9个按钮
-(void)setup
{
//    NSLog(@"断点 2 号 ");
//    newView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
//    newView.backgroundColor=[UIColor redColor];
//    [self addSubview:newView];
    //1.创建9个按钮
    for (int i=0; i<9; i++) {
        UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
        //2.设置按钮的状态背景
        [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
        [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];
        //3.把按钮添加到视图中
        [self  addSubview:btn];
        //将按钮添加到包含按钮数组中
        [[self includButtons] addObject:btn];
        //4.禁止按钮的点击事件
        btn.userInteractionEnabled=NO;
        //5.设置每个按钮的tag
        btn.tag=i+1;
    }
}

//4.设置按钮的frame
-(void)layoutSubviews
{
    NSLog(@"断点顺序 3 号 ");
    CGFloat inverst = KSCREEN_HEIGHT/4.5;
    inverst=0;
    //4.1需要先调用父类的方法
    [super layoutSubviews];

    for (int i=0; i<[self includButtons].count; i++) {
        //4.2取出按钮
        UIButton *btn=[self includButtons][i];
        //4.3九宫格法计算每个按钮的frame
        CGFloat row = i/3;
        CGFloat loc   = i%3;
//        NSLog(@"ROW=%f LOC=%f",row,loc);
        CGFloat btnW=74;
        CGFloat btnH=74;
        CGFloat padding=(self.frame.size.width-3*btnW)/4;
        CGFloat btnX=padding+(btnW+padding)*loc;
        CGFloat btnY=padding*BUTTON_HEIGHT_MIDDLE_WIDTH_RADIO+(btnW+padding)*row;
//        NSLog(@"BTNX-%f BTNY=%f ",btnX,btnY);
        btn.frame=CGRectMake(btnX, btnY+inverst, btnW, btnH);
    }
}

//重写drawrect:方法
-(void)drawRect:(CGRect)rect
{
    NSLog(@"断点顺序 4 号 ");

    //获取上下文
    CGContextRef ctx=UIGraphicsGetCurrentContext();

    //在每次绘制前,清空上下文
    CGContextClearRect(ctx, rect);

    //填充画布颜色
    [[self renderImageWithColor:[UIColor grayColor] inSize:CGSizeMake(KSCREEN_WIDTH, KSCREEN_HEIGHT)] drawInRect:CGRectMake(0, 0, KSCREEN_WIDTH, KSCREEN_HEIGHT)];//在坐标中画出图片

    //绘图(线段)
    for (int i=0; i<self.buttons.count; i++) {
        UIButton *btn=self.buttons[i];
        if (0==i) {
            //设置起点(注意连接的是中点)
            //            CGContextMoveToPoint(ctx, btn.frame.origin.x, btn.frame.origin.y);
            CGContextMoveToPoint(ctx, btn.center.x, btn.center.y);
        }else
        {
            //            CGContextAddLineToPoint(ctx, btn.frame.origin.x, btn.frame.origin.y);
            CGContextAddLineToPoint(ctx, btn.center.x, btn.center.y);
        }
    }

    //当所有按钮的中点都连接好之后,再连接手指当前的位置
    //判断数组中是否有按钮,只有有按钮的时候才绘制
    if (self.buttons.count !=0) {
        CGContextAddLineToPoint(ctx, self.currentPoint.x, self.currentPoint.y);
    }

    //渲染
    //设置线条的属性
    CGContextSetLineWidth(ctx, 10);
    CGContextSetLineJoin(ctx, kCGLineJoinRound);
    CGContextSetLineCap(ctx, kCGLineCapRound);
    CGContextSetRGBStrokeColor(ctx, 255/255.0, 0/255.0, 0/255.0, 1);

    CGContextStrokePath(ctx);

}

//填充画布颜色
- (UIImage *)renderImageWithColor:(UIColor *)color inSize:(CGSize)size
{
    CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

//5.监听手指的移动
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"断点 E 号 ");
    CGPoint starPoint=[self getCurrentPoint:touches];
    UIButton *btn=[self getCurrentBtnWithPoint:starPoint];

    if (btn && btn.selected != YES) {
        btn.selected=YES;
        [self.buttons addObject:btn];
    }
    //    [self setNeedsDisplay];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"断点 F 号 ");
    CGPoint movePoint=[self getCurrentPoint:touches];
    UIButton *btn=[self getCurrentBtnWithPoint:movePoint];
    //存储按钮
    //已经连过的按钮,不可再连
    if (btn && btn.selected != YES) {
        //设置按钮的选中状态
        btn.selected=YES;
        //把按钮添加到数组中
        [self.buttons addObject:btn];
    }
    //记录当前点(不在按钮的范围内)
    self.currentPoint=movePoint;
    //通知view重新绘制
    [self setNeedsDisplay];
}

//手指离开的时候清除线条
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"断点 G 号 ");
    //取出用户输入的密码
    //创建一个可变的字符串,用来保存用户密码
    NSMutableString *result=[NSMutableString string];
    for (UIButton *btn in self.buttons) {
        [result appendFormat:@"%lu",btn.tag];
    }
    NSLog(@"用户输入的密码为:%@",result);
    //通知代理,告知用户输入的密码
    if ([self.delegate respondsToSelector:@selector(LockViewDidClick:andPwd:)]) {
        [self.delegate LockViewDidClick:self andPwd:result];
    }

    //重置按钮的状态
    //    for (UIButton *btn in self.buttons) {
    //        btn.selected=NO;
    ////        [btn setSelected:NO];
    //    }

    //调用该方法,它就会让数组中的每一个元素都调用setSelected:方法,并给每一个元素传递一个NO参数
    [self.buttons makeObjectsPerformSelector:@selector(setSelected:) withObject:@(NO)];
    //清空数组
    [self.buttons removeAllObjects];
    [self setNeedsDisplay];

    //清空当前点
    self.currentPoint=CGPointZero;
}

//对功能点进行封装
-(CGPoint)getCurrentPoint:(NSSet *)touches
{
    NSLog(@"断点 H 号 ");
    UITouch *touch=[touches anyObject];
    CGPoint point=[touch locationInView:touch.view];
    return point;
}
-(UIButton *)getCurrentBtnWithPoint:(CGPoint)point
{
    NSLog(@"断点 J 号 ");
    for (int i=0;i<_includButtons.count;i++) {
        UIButton *btn =_includButtons[i];
        if (CGRectContainsPoint(btn.frame, point)) {
            return btn;
        }
    }
    return Nil;
}

@end
时间: 2025-01-18 06:17:25

(转 部分修改) IOS 手势密码(简单版)的相关文章

一个ios手势密码功能实现

ipad/iphone 都可以用 没有使用图片,里面可以通过view自己添加 keychain做的数据持久化,利用苹果官方KeychainItemWrapper类 keychain存储的数据不会因为删除app而清除记录,请调用-(void)clear清除储存密码. 简单使用方式 下载后直接把 GesturePassword 下的GesturePassword文件丢到项目中去 在 TARGETS - Build Phases - "KeychainItemWrapper.m" - Com

APP手势密码绕过

之前写的文章收到了很多的好评,主要就是帮助到了大家学习到了新的思路.自从发布了第一篇文章,我就开始筹备第二篇文章了,最终打算在07v8首发,这篇文章我可以保障大家能够学习到很多思路.之前想准备例子视频,请求了很多家厂商进行授权,但是涉及漏洞信息方面的,厂商都是很严谨的,所以,整个过程没有相关的实际例子,但是我尽可能的用详细的描述让大家能够看得懂.大家不要睡着呦~ 说到APP手势密码绕过的问题,大家可能有些从来没接触过,或者接触过,但是思路也就停留在那几个点上,这里我总结了我这1年来白帽子生涯当中

Xamarin.Forms 手势密码实现

Xamarin.Forms 手势密码实现 在前面的文章中,讲到了Xamarin.Android.Xamarin.iOS.UWP分别实现手势密码功能,现在我们在Xamarin.Forms中来实现这个功能.    原理和Xamarin.Android.Xamarin.iOS.UWP一样,关键就是如何使用ViewRenderer. 首先我们新建Xamarin.Forms项目: 在项目中创建GuestureLockView继承View(官方文档: 自定义Renderer). 接下来分别在Android.

Appium+Robotframework实现iOS应用的自动化测试-6:手势密码的解决方案

手势密码在很多应用都会运到,手势密码都要求至少连接4个点,但AppiumLibrary并没有提供对应的关键字,本人尝试连续使用Swipe关键字两次解决该问题,为什么要用两次呢?因为Swipe的参数只是起点和终点,如果直接给出手势密码的起点和重点,则会忽略中间的点,连续使用两次Swipe关键字在Android中偶尔可以成功,但在iOS中则没有一次成功过,为了彻底解决该问题,本人仔细看了Appium的文档,终于所有发现,请看来自于Appium的官方网站的如下截图: 从中我得知手势密码的问题一定可以解

iOS下的手势密码实现

一.iOS下的手势 1 #import "ViewController.h" 2 3 @interface ViewController () 4 5 @property (weak, nonatomic) IBOutlet UILabel *genstureLabel; 6 7 8 @end 9 10 @implementation ViewController 11 12 - (void)viewDidLoad { 13 [super viewDidLoad]; 14 15 16

手把手教你修改iOS版QQ的运动步数

手把手教你修改iOS版QQ的运动步数 字数669 阅读4770 评论30 喜欢33 现在很多软件都加上了运动模块,比如QQ和微信,而且还有排行榜,可以和好友比较谁的运动步数多,任何东西只要添加了比较功能,就变得不一样了.今天教大家用代码去修改QQ上的运动步数,修改完效果是这样的: 屏幕快照 2016-06-21 下午5.02.56.png 本帖子是抱着学习的心态来看待这个功能的,如果不喜欢请略过. 1准备工作 你需要一个iOS程序员所需要的设备:一个mac系统的电脑.一个Xcode.一个开发者账

iOS 应用2.0版怎么做(转)

移动互联网如火如荼,iOS 应用+ Android 应用+ 手机站似乎成了所有互联网公司的标配,你的网站要是还没有个iOS 应用,似乎都不好意思跟人打招呼.iOS 应用诞生毕竟才只有不到5年的时间,各个方面还都处在起步阶段.不管是出于团队缺乏经验,还是那个“唯快不破”的铁律,往往这些iOS 应用的第一个版本都比较简陋,尤其在技术架构上.这篇文章,我想跟大家探讨的就是这个问题,当你的iOS应用已经有一个版本在线的情况下,如何去构建一款可以支持高效迭代,快速响应的2.0版.首先,应用的架构要层次清晰

支付宝钱包手势密码破解实战

背景 随着移动互联网的普及以及手机屏幕越做越大等特点,在移动设备上购物.消费已是人们不可或缺的一个生活习惯了.随着这股浪潮的兴起,安全.便捷的移动支付需求也越来越大.因此,各大互联网公司纷纷推出了其移动支付平台.其中,用的比较多的要数腾讯的微信和阿里的支付宝钱包了.就我而言,平时和同事一起出去AA吃饭,下班回家打车等日常生活都已经离不开这两个支付平台了. 正所谓树大招风,移动支付平台的兴起,也给众多一直徘徊在网络阴暗地带的黑客们又一次重生的机会.因为移动平台刚刚兴起,人们对移动平台的安全认识度还

支付宝钱包手势密码破解实战(root过的手机可直接绕过手势密码)

/* 本文章由 莫灰灰 编写,转载请注明出处. 作者:莫灰灰    邮箱: [email protected] */ 背景 随着移动互联网的普及以及手机屏幕越做越大等特点,在移动设备上购物.消费已是人们不可或缺的一个生活习惯了.随着这股浪潮的兴起,安全.便捷的移动支付需求也越来越大.因此,各大互联网公司纷纷推出了其移动支付平台.其中,用的比较多的要数腾讯的微信和阿里的支付宝钱包了.就我而言,平时和同事一起出去AA吃饭,下班回家打车等日常生活都已经离不开这两个支付平台了. 正所谓树大招风,移动支付