IOS-------制作手机图案解锁

一、要先进行页面布局
1、在View Controller里面添加操作图片

-(void)initUI{
    //创建操作图片
    UIImageView *opImageView = [[UIImageView alloc]initWithframe:CGRectMake:((self.view.frame.size.width-320)/2,100,320,460)];
    opImageView.image = [UIImage imageNamed:@"1.png"];
    [self.view addSubview:opImageView];
}


添加initUI方法到ViewDidLoad里面

[self initUI];


2、添加点和线 
到这里我们会发现我们要添加很多大量的图片,因此我们可以添加一个方法,以此来简化我们的代码

//创建一个UIImageView
-(void)createImageViewWithFrame:(CGRect)frame name:(NSString *)imageName{
    UIImageView *imageView = [[UIImageView alloc]initWithframe:frame];
    imageView.image = [UIImage imageNamed:imageName];
    [self.view addSubview:imageView];
    return imageView;
}


因此,第1步添加操作图片可以改为:

[self createImageViewWithFrame:CGRectMake:((self.view.frame.size.width-320)/2,100,320,460) name:@"1.png"];


3、添加9个点 再写一个方法

-(void)addLandDot{
    //控制行
    for(int i = 0; i < 3; i ++){
        //控制列
        for(int j = 0; j <3 ; j ++){
            [self createImageViewWithFrame:CGRectMake:((65+99*j,280+99*i,52,52) name:@"1.png"];
        }
    }
}


将addLandDot添加到initUI方法里面

[self addLandDot];


4、添加横线

-(void)addLandScapeLine{
    for(int i = 0; i < 6; i ++){
        [self createImageViewWithFrame:CGRectMake:(90+i%2*99,265+i/2*99,120,37) name:@"1.png"];
    }
}


将addLandScapeLine添加到initUI方法里面 在addLandDot前面,保证点在线上面

[self addLandScapeLine];


5、用同样的方式添加竖线

-(void)addPortraitLine{
    for(int i = 0; i < 6; i ++){
        [self createImageViewWithFrame:CGRectMake:(70+i%3*99,265+i/3*99,120,37) name:@"1.png"];
    }
}


将addPortraitLine添加到initUI方法里面 在addLandDot前面,保证点在线上面

[self addPortraitLine];


6、添加左右斜线

-(void)addDiagonaitLine{
    for(int i = 0; i < 4; i ++){
        //左斜线
        [self createImageViewWithFrame:CGRectMake:(80+i%2*120,265+i/2*100,120,120) name:@"斜.png"];
        //右斜线
        [self createImageViewWithFrame:CGRectMake:(73+i%2*99,265+i/2*99,120,120) name:@"斜.png"];
    }
}


将addDiagonaitLine添加到initUI方法里面 在addLandDot前面,保证点在线上面

[self addDiagonaitLine];


7、给addLandDot设置tag值

int index = 1;
UIImageView *dotImageView = [self createImageViewWithFrame:CGRectMake:((65+99*j,280+99*i,52,52) name:@"1.png"];
dotImageView.tag = index;
index ++;


建立一个数组,保存点的tag值

@property(nonatomic,strong) NSMutableArray *dotImageViewArray; 


在initUI里面初始化数组

self.dotImageViewArray = [NSMutableArray arrayWithCapacity:9];


在addNineDot里面将创建的对象放到数组里面去

[self.dotImageViewArray addObject:dotImageView];


点亮点。要将全部图片都隐藏,而只留下操作图片

imageView.hidden = YES;
UIImageView *opView = [self createImageViewWithFrame:CGRectMake:((self.view.frame.size.width-320)/2,100,320,460) name:@"1.png"];
opView.hidden = NO;


二、点亮点和线
1、点亮点

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self.view];
    //判断这个触摸点有木有在某一个点上
    for(UIImageView *dotView in dotImageView){
       // CGRectContainsPoint 判断某一个矩形区域内是否包含某个点
        if(CGRectContainsPoint(dotView.frame, location)){
            dotImageView.hidden = NO;
        }
    }
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self.view];
    //判断这个触摸点有木有在某一个点上
    for(UIImageView *dotView in dotImageView){
       // CGRectContainsPoint 判断某一个矩形区域内是否包含某个点
        if(CGRectContainsPoint(dotView.frame, location)){
            dotImageView.hidden = NO;
        }
    }
}


2、点亮线
触摸点必须在某一个圆点上,当前这个点没有被点亮过,上一个点和当前这个点得有线路(给每一条线添加一个tag值,最小的两位数)
1、横线
12 23 45 56 78 89
在addLandScapeLine里面:

int index = 12;
//得到这条横线这个对象
UIImageView *LineImageView = [self createImageViewWithFrame:CGRectMake:(90+i%2*99,265+i/2*99,120,37) name:@"1.png"];
LineImageView.tag = index;
index += 11;
if((i+1)%2 == 0){
    index += 11;
}


2、竖线:14 25 36 47 58 69

int index = 14;
//得到这条横线这个对象
UIImageView *LineImageView = [self createImageViewWithFrame:CGRectMake:(90+i%2*99,265+i/2*99,120,37) name:@"1.png"];
LineImageView.tag = index;
index += 11;


3、左斜线:24 35 57 68
    右斜线:15 26 48 59

int indexL = 24;
int indexR = 15
//得到这条横线这个对象
UIImageView *LineImageViewL = [self createImageViewWithFrame:CGRectMake:(80+i%2*120,265+i/2*100,120,120) name:@"斜.png"];
LineImageViewL.tag = indexL;
indexL += 11;
UIImageView *LineImageViewR = [self createImageViewWithFrame:CGRectMake:(73+i%2*99,265+i/2*99,120,120) name:@"斜.png"];
LineImageView.tag = indexR;
indexR += 11;
if((i+1) = 2){
    indexL += 11;
    indexR += 11;
}


4、建立一个数组,保存线的tag值
若数组里面有tag值,证明有这条路径,就可以显示这条线

@property(nonatomic,strong) NSMutableArray *LineViewArray; 


5、在initUI里面初始化数组

self.LineViewArray = [NSMutableArray array];


6、在所有线里面将创建的对象放到数组里面去(注意:在index += 11;改变之前加)

[self.dotImageViewArray addObject:@(index)];


7、定义一个变量,记录上一个被点亮的tag值

@property(nonatomic,assign) NSInteger lastSelectedDotTag; 


8、记录这个点的tag值

lastSelectedDotTag = dotView.tag;


9、在touchMoved里面判断是否点亮这个点

//判断这个点有木有被点亮
if(dotView.hidden = YES){
    //没有被点亮
    //判断是不是第一个点
    if(_lastSelectedTag == 0){
    //第一个点 直接点亮
    dotView.hidden = NO:
    _lastSelectedTag = dotView.tag;
} else{
    //判断上一个点和当前这个点之间有木有路径 即判断数组里面是否包含值
    //获取上一个点和当前点tag组成的最小两位数
        NSInteger lineTag = _lastSelectedDotTag > dotView.tag?dotView.tag*10+_lastSelectedDotTag:_lastSelectedDotTag*10+dotView.tag;
        //判断数组里面是否包含lineTag
        if(_lineTagArray containsObject:@(lineTag)){
            //有这条线 点亮点 点亮线
            dotView.hidden = NO;
            //通过tag得到一个视图
            UIImageView *lineImageView = [self.view viewWithTag:lineTag];
            lineImageView.hidden = NO;
            _lastSelectedDotTag = dotView.tag;
        }
    }
}


三、一放手让点和线都消失
1、定义一个数组,用于保存点亮的点和线

@property(nonatomic,strong) NSMutableArray *allSelectedViewArray; 


2.在initUI里面初始化数组

self.allSelectedViewArray = [NSMutableArray array];


3.在所有点亮的里面将创建的对象放到数组里面去

[_allSelectedViewArray addObject:……];


4.在touchesEnded里面

[self hideAllView];
-(void)hideAllView{
    for(UIImageView *imgView in allSelectedViewArray){
        imgView.hidden = YES;
}
    [_allSelectedViewArray reomveAllObjects];
}

5.显示画错的点

- (void)showWrong{
    for (ChangeableImageView *imgView in _allSelectedViewsArray) {
        [imgView changeImageWithStatus:kImageViewStatusWrong];
    }
    
    [self performSelector:@selector(hideAllView) withObject:nil afterDelay:1];
}

6.touchesBegin

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //获取触摸点的坐标
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self.view];
    
    //判断这个触摸点有没有在摸一个圆点上
    for (UIImageView *dotView in _dotImageViewArray) {
        if (CGRectContainsPoint(dotView.frame, location)){
            //点亮这个点
            dotView.hidden = NO;
            
            //记录这个点的tag值
            _lastSelectedDotTag = dotView.tag;
            
            //保存点亮的点
            [_allSelectedViewsArray addObject:dotView];
            
            //保存密码 拼接字符串
            [self.mPasswordString appendFormat:@"%ld",dotView.tag];
        }
    }
    
}

7.

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //获取触摸点的坐标
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self.view];
    
    //判断这个触摸点有没有在摸一个圆点上
    for (UIImageView *dotView in _dotImageViewArray) {
        if (CGRectContainsPoint(dotView.frame, location)){
            //判断这个点有没有被点亮
            if (dotView.hidden == YES){
                //没有被点亮
                //判断是不是第一个点
                if (_lastSelectedDotTag == 0){
                    //第一个点 直接点亮
                    dotView.hidden = NO;
                    
                    //保存这个tag值
                    _lastSelectedDotTag = dotView.tag;
                    
                    //保存点亮的点
                    [_allSelectedViewsArray addObject:dotView];
                    
                    //保存密码 拼接字符串
                    [self.mPasswordString appendFormat:@"%ld",dotView.tag];
                } else{
                    //判断上一个点和当前这个点之间有没有直接的线路
                    //获取上一个点和当前点的tag组成的最小两位数
                    NSInteger lineTag = _lastSelectedDotTag > dotView.tag ? dotView.tag * 10 + _lastSelectedDotTag : _lastSelectedDotTag * 10 + dotView.tag;
                    
                    //判断数组里面是否包含lineTag
                    if ([_lineTagsArray containsObject:@(lineTag)]){
                        //有这条线 点亮点
                        dotView.hidden = NO;
                        //点亮线
                        UIImageView *lineImageView = [self.view viewWithTag:lineTag];
                        lineImageView.hidden = NO;
                        
                        _lastSelectedDotTag = dotView.tag;
                        
                        //保存点亮的点
                        [_allSelectedViewsArray addObject:dotView];
                        //保存点亮的线
                        [_allSelectedViewsArray addObject:lineImageView];
                        
                        //保存密码 拼接字符串
                        [self.mPasswordString appendFormat:@"%ld",dotView.tag];
                    }
                }
            }
        }
    }
}

8.

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //判断是设置还是解锁
    if (_password.length == 0) {
        //设置或者确认密码
        if (_firstPasswordString.length == 0){
            //设置密码
            //保存刚才输入的密码
            self.firstPasswordString = [NSString stringWithString:_mPasswordString];
            
            //提示确认密码
            self.alertlabel.text = @"请确认密码图案";
        } else{
            //确认密码
            if ([_firstPasswordString isEqualToString:_mPasswordString]){
                self.alertlabel.text = @"设置成功";
                
                //保存密码
                [[NSUserDefaults standardUserDefaults] setObject:_mPasswordString forKey:@"password"];
            } else{
                self.alertlabel.text = @"两次图案不一致 请重新绘制";
                self.firstPasswordString = @"";
                [self showWrong];
            }
        }
    } else{
        //有过密码了
        if ([self.mPasswordString isEqualToString:_password]){
            //密码成功
            self.alertlabel.text = @"解锁成功";
        } else{
            //密码错误
            self.alertlabel.text = @"密码错误 请重新绘制";
            [self showWrong];
        }
    }
    

}

三、创建图片类

1.创建头文件ChangeableImageView.h

typedef enum{
    kImageViewStatusNormal,
    kImageViewStatusWrong
} kImageViewStatus;

@interface ChangeableImageView : UIImageView

@property (nonatomic, strong) NSString *normalImageName;
@property (nonatomic, strong) NSString *wrongImageName;

- (void)changeImageWithStatus:(kImageViewStatus)status;

+ (ChangeableImageView *)imageViewWithNormalImageName:(NSString *)normal andWrongImageName:(NSString *)wrong frame:(CGRect)frame father:(UIView *)contetView;

2.ChangeableImageView.m

@implementation ChangeableImageView

- (void)changeImageWithStatus:(kImageViewStatus)status{
    if (status == kImageViewStatusNormal){
        self.image = [UIImage imageNamed:_normalImageName];
    } else{
        self.image = [UIImage imageNamed:_wrongImageName];
    }
}

+ (ChangeableImageView *)imageViewWithNormalImageName:(NSString *)normal andWrongImageName:(NSString *)wrong frame:(CGRect)frame father:(UIView *)contetView{
    ChangeableImageView *img = [[ChangeableImageView alloc] initWithFrame:frame];
    img.normalImageName = normal;
    img.wrongImageName = wrong;
    img.hidden = YES;
    img.image = [UIImage imageNamed:normal];
    [contetView addSubview:img];
    
    return img;
}

四、整体完整代码

#import "ViewController.h"
#import "ChangeableImageView.h"

@interface ViewController ()
//保存9个圆点的对象
@property (nonatomic, strong) NSMutableArray *dotImageViewArray;
//保存所有线的tag
@property (nonatomic, strong) NSMutableArray *lineTagsArray;
//保存上一次被点亮的点的tag值
@property (nonatomic, assign) NSInteger lastSelectedDotTag;
//保存所有点亮的点或者线
@property (nonatomic, strong) NSMutableArray *allSelectedViewsArray;
//记录密码
@property (nonatomic, strong) NSMutableString *mPasswordString;
//提示用户操作的label
@property (nonatomic, strong) UILabel *alertlabel;
//保存原始的密码
@property (nonatomic, strong) NSString *password;
//保存设置密码中第一次输入的密码
@property (nonatomic, strong) NSString *firstPasswordString;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //初始化数组
    self.dotImageViewArray = [NSMutableArray arrayWithCapacity:9];
    self.lineTagsArray = [NSMutableArray array];
    self.allSelectedViewsArray = [NSMutableArray array];
    self.mPasswordString = [NSMutableString string];
    
    [self initUI];
}

/** 创建一个UIImageView */
- (UIImageView *)createImageViewWithFrame:(CGRect)frame name:(NSString *)imageName{
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
    imageView.image = [UIImage imageNamed:imageName];
    imageView.hidden = YES; //隐藏
    [self.view addSubview:imageView];
    
    return imageView;
}

//界面布局
- (void)initUI{
    //背景图片 UIImageView  UIImage
    UIImageView *bg =[self createImageViewWithFrame:self.view.bounds name:@"Main_BG"];
    bg.hidden = NO;
    
    //添加操作图片
    UIImageView *opView = [self createImageViewWithFrame:CGRectMake((self.view.frame.size.width-320)/2, 100, 320, 460) name:@"Unlock_DotLock1_Normal"];
    opView.hidden = NO;
    
    //创建label
    self.alertlabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 180, self.view.frame.size.width, 50)];
    _alertlabel.textAlignment = NSTextAlignmentCenter;
    _alertlabel.textColor = [UIColor whiteColor];
    [self.view addSubview:_alertlabel];
    
    //获取UserDefaults里面保存的密码
    self.password = [[NSUserDefaults standardUserDefaults] objectForKey:@"password"];
    if (_password.length == 0){
        //设置密码
        _alertlabel.text = @"请设置密码图案";
    } else{
        //输入密码
        _alertlabel.text = @"请绘制解锁图案";
    }
    
    //横线
    [self addLandScapeLine];
    
    //竖线
    [self addPortraitLine];
    
    //斜线
    [self addDiagonalLine];
    
    //添加9个点
    [self addNineDot];
    
}

- (void)addNineDot{
    int index = 1;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            ChangeableImageView *dotImageView = [ChangeableImageView imageViewWithNormalImageName:@"Unlock_DotLock1_Selected" andWrongImageName:@"Unlock_DotLock_Wrong1" frame:CGRectMake(63 + 99 * j, 265 + 99*i, 52, 52) father:self.view];
            
            //设置tag值
            dotImageView.tag = index;
            index++;
            
            //将创建的这个对象放到数组里面去
            [self.dotImageViewArray addObject:dotImageView];
        }
    }
}

/*
 12 23
 45 56
 78 89
 */
- (void)addLandScapeLine{
    int index = 12;//第一条线的tag值
    for (int i = 0; i < 6; i++) {
        ChangeableImageView *lineImageView = [ChangeableImageView imageViewWithNormalImageName:@"Unlock_DotLock1_Normal_Highlight1" andWrongImageName:@"Unlock_DotLock1_Wrong_Highlight1" frame:CGRectMake(70 + i%2*99, 270+i/2*99, 120, 37) father:self.view];
        lineImageView.tag = index;
        
        //将tag值添加到数组中
        //NSNumber *num = [NSNumber numberWithInt:index];
        [self.lineTagsArray addObject:@(index)];
        
        index += 11;
        
        if (((i+1) % 2 == 0) && i != 0){
            index += 11;
        }
    }
}

/*
 14 25 36
 47 58 69
 */
- (void)addPortraitLine{
    int index = 14;
    for (int i = 0; i < 6; i++) {
        ChangeableImageView *lineImageView = [ChangeableImageView imageViewWithNormalImageName:@"Unlock_DotLock1_Normal_Highlight2" andWrongImageName:@"Unlock_DotLock1_Wrong_Highlight2" frame:CGRectMake(70 + i%3*99, 270+i/3*99, 37, 120) father:self.view];
        lineImageView.tag = index;
        
        //将tag值添加到数组中
        [self.lineTagsArray addObject:@(index)];
        
        index += 11;
    }
}

/*
 24 35
 57 68
 
 15 26
 48 59
 */
- (void)addDiagonalLine{
    int indexL = 24;
    int indexR = 15;
    for (int i = 0; i < 4; i++) {
        ChangeableImageView *LLineView = [ChangeableImageView imageViewWithNormalImageName:@"Unlock_DotLock1_Normal_Highlight4" andWrongImageName:@"Unlock_DotLock1_Wrong_Highlight4" frame:CGRectMake(85 + i%2*99, 270+i/2*99, 120, 120) father:self.view];
        LLineView.tag = indexL;
        //将tag值添加到数组中
        [self.lineTagsArray addObject:@(indexL)];
        
        indexL += 11;
        
        ChangeableImageView *RLineView = [ChangeableImageView imageViewWithNormalImageName:@"Unlock_DotLock1_Normal_Highlight3" andWrongImageName:@"Unlock_DotLock1_Wrong_Highlight3" frame:CGRectMake(73 + i%2*99, 270+i/2*99, 120, 120) father:self.view];
        RLineView.tag = indexR;
        //将tag值添加到数组中
        [self.lineTagsArray addObject:@(indexR)];
        indexR += 11;
        
        if ((i+1) == 2){
            indexL += 11;
            indexR += 11;
        }
    }
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //获取触摸点的坐标
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self.view];
    
    //判断这个触摸点有没有在摸一个圆点上
    for (UIImageView *dotView in _dotImageViewArray) {
        if (CGRectContainsPoint(dotView.frame, location)){
            //点亮这个点
            dotView.hidden = NO;
            
            //记录这个点的tag值
            _lastSelectedDotTag = dotView.tag;
            
            //保存点亮的点
            [_allSelectedViewsArray addObject:dotView];
            
            //保存密码 拼接字符串
            [self.mPasswordString appendFormat:@"%ld",dotView.tag];
        }
    }
    
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //获取触摸点的坐标
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInView:self.view];
    
    //判断这个触摸点有没有在摸一个圆点上
    for (UIImageView *dotView in _dotImageViewArray) {
        if (CGRectContainsPoint(dotView.frame, location)){
            //判断这个点有没有被点亮
            if (dotView.hidden == YES){
                //没有被点亮
                //判断是不是第一个点
                if (_lastSelectedDotTag == 0){
                    //第一个点 直接点亮
                    dotView.hidden = NO;
                    
                    //保存这个tag值
                    _lastSelectedDotTag = dotView.tag;
                    
                    //保存点亮的点
                    [_allSelectedViewsArray addObject:dotView];
                    
                    //保存密码 拼接字符串
                    [self.mPasswordString appendFormat:@"%ld",dotView.tag];
                } else{
                    //判断上一个点和当前这个点之间有没有直接的线路
                    //获取上一个点和当前点的tag组成的最小两位数
                    NSInteger lineTag = _lastSelectedDotTag > dotView.tag ? dotView.tag * 10 + _lastSelectedDotTag : _lastSelectedDotTag * 10 + dotView.tag;
                    
                    //判断数组里面是否包含lineTag
                    if ([_lineTagsArray containsObject:@(lineTag)]){
                        //有这条线 点亮点
                        dotView.hidden = NO;
                        //点亮线
                        UIImageView *lineImageView = [self.view viewWithTag:lineTag];
                        lineImageView.hidden = NO;
                        
                        _lastSelectedDotTag = dotView.tag;
                        
                        //保存点亮的点
                        [_allSelectedViewsArray addObject:dotView];
                        //保存点亮的线
                        [_allSelectedViewsArray addObject:lineImageView];
                        
                        //保存密码 拼接字符串
                        [self.mPasswordString appendFormat:@"%ld",dotView.tag];
                    }
                }
            }
        }
    }
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //判断是设置还是解锁
    if (_password.length == 0) {
        //设置或者确认密码
        if (_firstPasswordString.length == 0){
            //设置密码
            //保存刚才输入的密码
            self.firstPasswordString = [NSString stringWithString:_mPasswordString];
            
            //提示确认密码
            self.alertlabel.text = @"请确认密码图案";
        } else{
            //确认密码
            if ([_firstPasswordString isEqualToString:_mPasswordString]){
                self.alertlabel.text = @"设置成功";
                
                //保存密码
                [[NSUserDefaults standardUserDefaults] setObject:_mPasswordString forKey:@"password"];
            } else{
                self.alertlabel.text = @"两次图案不一致 请重新绘制";
                self.firstPasswordString = @"";
                [self showWrong];
            }
        }
    } else{
        //有过密码了
        if ([self.mPasswordString isEqualToString:_password]){
            //密码成功
            self.alertlabel.text = @"解锁成功";
        } else{
            //密码错误
            self.alertlabel.text = @"密码错误 请重新绘制";
            [self showWrong];
        }
    }
    

}

- (void)showWrong{
    for (ChangeableImageView *imgView in _allSelectedViewsArray) {
        [imgView changeImageWithStatus:kImageViewStatusWrong];
    }
    
    [self performSelector:@selector(hideAllView) withObject:nil afterDelay:1];
}

- (void)hideAllView{
    for (ChangeableImageView *imgView in _allSelectedViewsArray) {
        imgView.hidden = YES;
        [imgView changeImageWithStatus:kImageViewStatusNormal];
    }
    
    //清空
    [_allSelectedViewsArray removeAllObjects];
    _lastSelectedDotTag = 0;
    [_mPasswordString setString:@""];
}
@end

猜你喜欢

转载自blog.csdn.net/psn1028/article/details/83472483
今日推荐