1. 程式人生 > >IOS-------製作手機圖案解鎖

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