国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 系統(tǒng) > iOS > 正文

iOS實(shí)現(xiàn)手勢(shì)滑動(dòng)解鎖功能簡(jiǎn)析

2019-10-21 18:43:59
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

題記

在平常的生活中,我們大概經(jīng)常遇見(jiàn)手勢(shì)滑動(dòng)解鎖---也就是九宮格啊,已經(jīng)出現(xiàn)好久了,雖然隨著Apple的指紋解鎖的發(fā)展手勢(shì)解鎖雖然還有但是因?yàn)槠洳蝗缰讣y解鎖方便也用的也少了,但是在大多數(shù)APP中這兩種方式都是并存的,比如qq,微信,支付寶等等,最近項(xiàng)目里面也剛好有這個(gè)需求,趁著剛完成抽出時(shí)間來(lái)記錄下來(lái)當(dāng)時(shí)的一些思路,可能有的地方理解的不到位,還需多總結(jié),閑言少敘了,看重點(diǎn)。

功能描述如圖:大概說(shuō)一下思路,這個(gè)功能用來(lái)做相當(dāng)于密令,用于兩端的匹配,教師端設(shè)置了路徑生成密碼,儲(chǔ)存在本地,學(xué)生端用來(lái)滑動(dòng)輸入進(jìn)行驗(yàn)證。然后根據(jù)各種情況上部的label給與各種提示信息,這里只是一個(gè)比較原始簡(jiǎn)陋的demo,也只是實(shí)現(xiàn)了我們最常見(jiàn)的功能,所以重在領(lǐng)會(huì)其中的精神了,哈哈哈。

iOS,手勢(shì)滑動(dòng)解鎖,手勢(shì)解鎖

功能模塊分析

根據(jù)GIF可以簡(jiǎn)單的把這塊兒功能分為幾個(gè)部分來(lái)理解,第一個(gè)就是首頁(yè):ViewController,首頁(yè)里面有兩個(gè)Controller分別是StudViewController和TeacViewController用來(lái)分作不同功能的載體。在StudViewController中分為三部分上中下statusLabel GestureLockView clearBtn,其中GestureLockView是手勢(shì)解鎖界面。在TeacViewController中也是分為三部分,statusLabel GestureLockView BottomView下方的bottomView分為兩個(gè)button resetBtn重置按鈕和sureBtn確定按鈕。說(shuō)完大體的結(jié)構(gòu),接下來(lái)分部分說(shuō)一下每個(gè)功能的實(shí)現(xiàn)思路。

拆解分析

首先說(shuō)一下GestureLockView這個(gè)view控件:

首先在.h 文件中

定義兩個(gè)枚舉:分別用來(lái)定義兩端的不同類型,stu端用ResultKindType來(lái)對(duì)畫(huà)的手勢(shì)結(jié)果進(jìn)行分類分為這四類,下面都會(huì)用到,并說(shuō)明用途。teac端用TeacKindType來(lái)分兩類:

//檢測(cè)手勢(shì)密碼答案情況 對(duì)/錯(cuò)/不夠4個(gè)數(shù)字typedef NS_ENUM(NSUInteger, ResultKindType) {  ResultKindTypeTrue,  ResultKindTypeFalse,  ResultKindTypeNoEnough,  ResultKindTypeClear};typedef NS_ENUM(NSUInteger, TeacKindType) {  TeacKindTypeNoEnough,  TeacKindTypeTrue};

協(xié)議:用來(lái)監(jiān)聽(tīng)手勢(shì)變化時(shí)傳出的轉(zhuǎn)化的密碼(這個(gè)密碼是用button的tag值來(lái)表示的),因?yàn)槭謩?shì)是在變化的,所以這里用了NSMutableString向外傳遞。

@protocol GestureLockDelegate <NSObject>- (void)gestureLockView:(GestureLockView *)lockView drawRectFinished:(NSMutableString *)gesturePassword;@end

屬性:

  1. @property (nonatomic, weak) id<GestureLockDelegate> delegate;
  2. @property (nonatomic, assign) BOOL isTeac;//教師端 用來(lái)驗(yàn)證是否是教師端

方法:

- (void)clearLockView;//清除布局 重新開(kāi)始- (void)checkPwdResult:(ResultKindType)resultType;//檢測(cè)學(xué)生端的結(jié)果- (void)checkTeacResult:(TeacKindType)resultType;//檢測(cè)老師端的結(jié)果

.m文件中(具體創(chuàng)建和應(yīng)用的方法)

聲明變量供下方使用:

@interface GestureLockView ()@property (strong, nonatomic) NSMutableArray *selectBtns;//選中的按鈕數(shù)組@property (nonatomic, strong) NSMutableArray *errorBtns;//錯(cuò)誤的按鈕數(shù)組@property(nonatomic, assign)BOOL finished;//是否完成@property (nonatomic, assign) CGPoint currentPoint;//當(dāng)前觸摸點(diǎn)@property (nonatomic, assign) ResultKindType resultType;//學(xué)生端結(jié)果@property (nonatomic, assign) TeacKindType teacResultType;//教師端結(jié)果@end

懶加載初始化數(shù)組

- (NSMutableArray *)selectBtns {  if (!_selectBtns) {    _selectBtns = [NSMutableArray array];  }  return _selectBtns;}- (NSMutableArray *)errorBtns {  if (!_errorBtns) {    _errorBtns = [NSMutableArray array];  }  return _errorBtns;}

子視圖初始化:在這里創(chuàng)建9個(gè)按鈕并將它們add到self中,并給self 添加UIPanGestureRecognizer *pan手勢(shì)

- (void)initSubviews {  self.backgroundColor = [UIColor clearColor];  UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];  [self addGestureRecognizer:pan];    //創(chuàng)建9個(gè)按鈕  for (NSInteger i = 0; i < 9; i++) {    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];    btn.userInteractionEnabled = NO;    [btn setImage:[UIImage imageNamed:@"sign_img_circle_n"] forState:UIControlStateNormal];    [btn setImage:[UIImage imageNamed:@"sign_img_circle_s"] forState:UIControlStateSelected];    btn.tag = i+1;    [self addSubview:btn];  }}

界面布局:

  CGFloat minWidth = MIN(self.bounds.size.height, self.bounds.size.width);  CGFloat boundsWidth = self.bounds.size.width;  CGFloat margin = (minWidth - cols * w) / (cols + 1);//間距  CGFloat xMargin = (boundsWidth-2*margin-3*w)/2;

這里這一塊是對(duì)不同機(jī)型進(jìn)行的適配,因?yàn)檫@個(gè)控件有可能會(huì)被添加在一個(gè)height<width的view上,所以在這里margin是指比較短的長(zhǎng)度也就是上下的height,xMargin是用來(lái)對(duì)width進(jìn)行伸展的,這塊是這個(gè)邏輯,應(yīng)該可以通用的。

- (void)layoutSubviews {  [super layoutSubviews];  NSUInteger count = self.subviews.count;  int cols = 3;//總列數(shù)  CGFloat x = 0,y = 0,w = 0,h = 0;  if (SCREEN_WIDTH == 320) {    w = 50;    h = 50;  } else {    w = 60;    h = 60;  }  CGFloat minWidth = MIN(self.bounds.size.height, self.bounds.size.width);  CGFloat boundsWidth = self.bounds.size.width;  CGFloat margin = (minWidth - cols * w) / (cols + 1);//間距  CGFloat xMargin = (boundsWidth-2*margin-3*w)/2;    CGFloat col = 0;  CGFloat row = 0;  for (int i = 0; i < count; i++) {    col = i % cols;    row = i / cols;    if (i == 0 || i == 3 || i == 6) {      x = xMargin;    } else if (i == 1 || i == 4 || i == 7) {      x = xMargin + w + margin;    } else {      x = xMargin + 2 * (margin+w);    }    y = (w+margin)*row;    UIButton *btn = self.subviews[i];    btn.frame = CGRectMake(x, y, w, h);  }}

手勢(shì)代理方法: 在手勢(shì)代理方法中監(jiān)聽(tīng)手勢(shì)滑動(dòng)位置的改變,當(dāng)pan.state == UIGestureRecognizerStateBegan開(kāi)始滑動(dòng)的時(shí)候,從盛放顯示錯(cuò)誤狀態(tài)的button改變?yōu)槠胀ǔ跏紶顟B(tài),并且將self.errorBtns數(shù)組清除。將_currentPoint = [pan locationInView:self];檢測(cè)當(dāng)滑動(dòng)時(shí)當(dāng)前的位置point,如果劃過(guò)的位置包含在button的范圍內(nèi),如果button.selected == NO那么將button.selected = YES;//設(shè)置為選中并且將button添加到self.selectBtns數(shù)組中[self.selectBtns addObject:button];調(diào)用[self setNeedsDisplay];方法進(jìn)行重繪,調(diào)用setNeedsDisplay方法系統(tǒng)會(huì)自動(dòng)調(diào)用drawReact方法進(jìn)行界面的重新布局。最后監(jiān)聽(tīng)手指是否松開(kāi)//監(jiān)聽(tīng)手指松開(kāi) if (pan.state == UIGestureRecognizerStateEnded) { self.finished = YES; }如果松開(kāi)將self.finished = YES;

#pragma mark 手勢(shì)- (void)pan:(UIPanGestureRecognizer *)pan {    if (pan.state == UIGestureRecognizerStateBegan) {    for (UIButton *btn in _errorBtns) {      [btn setImage:[UIImage imageNamed:@"sign_img_circle_n"] forState:UIControlStateNormal];      [btn setImage:[UIImage imageNamed:@"sign_img_circle_s"] forState:UIControlStateSelected];    }    [self.errorBtns removeAllObjects];  }  _currentPoint = [pan locationInView:self];    for (UIButton *button in self.subviews) {    if (CGRectContainsPoint(button.frame, _currentPoint)) {      if (button.selected == NO) {        //點(diǎn)在按鈕上        button.selected = YES;//設(shè)置為選中        [self.selectBtns addObject:button];      } else {              }    }  }    //重繪  [self setNeedsDisplay];  //監(jiān)聽(tīng)手指松開(kāi)  if (pan.state == UIGestureRecognizerStateEnded) {    self.finished = YES;  }}

傳遞設(shè)置的手勢(shì)密碼方法

//傳遞設(shè)置的手勢(shì)密碼- (NSMutableString *)transferGestureResult {  //創(chuàng)建可變字符串  NSMutableString *result = [NSMutableString string];  for (UIButton *btn in self.selectBtns) {    [result appendFormat:@"%ld", btn.tag - 1];  }  return result;}

兩端的外部操作對(duì)內(nèi)部狀態(tài)的改變:

case ResultKindTypeFalse:_errorBtns = [NSMutableArray arrayWithArray:self.selectBtns];break;

這里如果繪制錯(cuò)誤,將之前選中的按鈕放在 _errorBtns盛放錯(cuò)誤按鈕的數(shù)組中

case ResultKindTypeClear:{[[UIColor clearColor] set];for (int i = 0; i < self.errorBtns.count; i++) {UIButton *btn = [self.errorBtns objectAtIndex:i];[btn setImage:[UIImage imageNamed:@"sign_img_circle_n"] forState:UIControlStateNormal];}[self.errorBtns removeAllObjects];}break;

當(dāng)外界改變狀態(tài)為“清除”時(shí),將路徑置為透明 并改變errorBtns數(shù)組中button的背景色狀態(tài),并且將errorBtns清空,這里為什么在這里做這些改變呢?這是因?yàn)樵趯W(xué)生端進(jìn)行清除操作的時(shí)候,手勢(shì)的狀態(tài)已經(jīng)是finish并且這是后代理方法已經(jīng)走完,并且我們?cè)谡{(diào)用clearLockView方法的時(shí)候也將selectBtns數(shù)組清空了,因此在setNeedsDisplay被調(diào)用,drawReact進(jìn)行重繪的時(shí)候,檢測(cè)到if (_selectBtns.count == 0) return;也就不再繼續(xù)往下進(jìn)行了。

//學(xué)生端狀態(tài)改變- (void)checkPwdResult:(ResultKindType)resultType {  self.resultType = resultType;  switch (resultType) {    case ResultKindTypeFalse:      _errorBtns = [NSMutableArray arrayWithArray:self.selectBtns];      break;      case ResultKindTypeTrue:      break;      case ResultKindTypeNoEnough:      break;      case ResultKindTypeClear:    {      [[UIColor clearColor] set];      for (int i = 0; i < self.errorBtns.count; i++) {        UIButton *btn = [self.errorBtns objectAtIndex:i];        [btn setImage:[UIImage imageNamed:@"sign_img_circle_n"] forState:UIControlStateNormal];      }      [self.errorBtns removeAllObjects];    }      break;    default:      break;  }  [self clearLockView];}//教師端狀態(tài)改變- (void)checkTeacResult:(TeacKindType)resultType {  self.teacResultType = resultType;  switch (resultType) {    case TeacKindTypeTrue:      break;    case TeacKindTypeNoEnough:{      [self clearLockView];    }      break;    default:      break;  }}

清除方法: 這里將self.finished = NO;因?yàn)槿绻峭ㄟ^(guò)代理將值傳到外界并且外界對(duì)該值進(jìn)行了校驗(yàn),對(duì)內(nèi)容的resultType進(jìn)行改變,這時(shí)候其實(shí)還是在drawReact方法中,并且已經(jīng)走完了self.finished 方法,在這里將其設(shè)置為NO 是為了改變下一次繪制的finished狀態(tài),雖然不起眼,但是也是寫(xiě)出來(lái)了。

- (void)clearLockView {  self.finished = NO;  //遍歷所有選中的按鈕  for (UIButton *btn in self.selectBtns) {    //取消選中狀態(tài)    btn.selected = NO;  }  [self.selectBtns removeAllObjects];  //  [self setNeedsDisplay];}

利用貝塞爾曲線繪制路徑,并根據(jù)對(duì)應(yīng)的狀態(tài)修改路徑顏色,按鈕顏色,當(dāng)系統(tǒng)調(diào)用這個(gè)方法的時(shí)候會(huì)進(jìn)行重繪,重繪時(shí),從self.selectBtns數(shù)組中取出選中的button,當(dāng)button是第一個(gè)的時(shí)候?qū)⑵湓O(shè)置為bezierPath的起點(diǎn)[path moveToPoint:btn.center];其余的按鈕繪制路徑[path addLineToPoint:btn.center];。在這里判斷是否松開(kāi)手指,在這個(gè)判斷里邏輯判斷比較多,大致捋一下,當(dāng)self.finished == YES的時(shí)候,就將創(chuàng)建的密碼利用先前聲明的代理傳遞出去在外部進(jìn)行檢驗(yàn)。根據(jù)外部返回的操作狀態(tài),如果是self.isTeac根據(jù)返回的結(jié)果狀態(tài)進(jìn)行判斷

case TeacKindTypeNoEnough:{[[UIColor clearColor] set];}break;case TeacKindTypeTrue:{[[UIColor colorWithRed:94/255.0 green:195/255.0 blue:49/255.0 alpha:0.8] set];}

如果畫(huà)的點(diǎn)不足4個(gè),那么清除選中的點(diǎn)并且將繪制路徑的顏色透明(或者如果考慮到性能的話,最好用和背景色一樣的顏色),如果是繪制完成,用“綠色”填充,這里我選擇了教師繪制完畢不清楚繪制路徑,以便查看。
如果是學(xué)生端的話:繪制正確清除路徑,錯(cuò)誤用“紅色”標(biāo)識(shí)路徑并從盛放錯(cuò)誤按鈕的數(shù)組self.errorBtns中取出按鈕進(jìn)行狀態(tài)的改變。

switch (self.resultType) {case ResultKindTypeTrue:{//正確[[UIColor clearColor] set];}break;case ResultKindTypeFalse:{//錯(cuò)誤[[UIColor redColor] set];for (int i = 0; i < self.errorBtns.count; i++) {UIButton *btn = [self.errorBtns objectAtIndex:i];[btn setImage:[UIImage imageNamed:@"sign_img_circle_p"] forState:UIControlStateNormal];}break;case ResultKindTypeNoEnough:{[[UIColor clearColor] set];}break;case ResultKindTypeClear:break;default:break;}

之后便是若沒(méi)有finish 就是在繪制路徑了,對(duì)path進(jìn)行一些相關(guān)設(shè)置。

- (void)drawRect:(CGRect)rect {  if (_selectBtns.count == 0) return;  // 把所有選中按鈕中心點(diǎn)連線  UIBezierPath *path = [UIBezierPath bezierPath];  for (int i = 0; i < self.selectBtns.count; i ++) {    UIButton *btn = self.selectBtns[i];    if (i == 0) {      [path moveToPoint:btn.center]; // 設(shè)置起點(diǎn)    } else {      [path addLineToPoint:btn.center];    }  }    //判斷是否松開(kāi)手指  if (self.finished) {    //松開(kāi)手    NSMutableString *pwd = [self transferGestureResult];//傳遞創(chuàng)建的密碼    [[UIColor colorWithRed:94/255.0 green:195/255.0 blue:49/255.0 alpha:0.8] set];    if ([self.delegate respondsToSelector:@selector(gestureLockView:drawRectFinished:)]) {      [self.delegate gestureLockView:self drawRectFinished:pwd];    }        if (self.isTeac) {      //教師端      switch (self.teacResultType) {        case TeacKindTypeNoEnough:        {          [[UIColor clearColor] set];        }          break;        case TeacKindTypeTrue:        {          [[UIColor colorWithRed:94/255.0 green:195/255.0 blue:49/255.0 alpha:0.8] set];        }          break;        default:          break;      }    } else {      switch (self.resultType) {        case ResultKindTypeTrue:        {          //正確          [[UIColor clearColor] set];        }          break;        case ResultKindTypeFalse:        {          //錯(cuò)誤          [[UIColor redColor] set];          for (int i = 0; i < self.errorBtns.count; i++) {            UIButton *btn = [self.errorBtns objectAtIndex:i];            [btn setImage:[UIImage imageNamed:@"sign_img_circle_p"] forState:UIControlStateNormal];          }          break;        case ResultKindTypeNoEnough:          {            [[UIColor clearColor] set];          }          break;        case ResultKindTypeClear:          break;        default:          break;        }      }        }  } else {    [path addLineToPoint:self.currentPoint];    [[UIColor colorWithRed:94/255.0 green:195/255.0 blue:49/255.0 alpha:0.8] set];  }  path.lineWidth = 1;  path.lineJoinStyle = kCGLineCapRound;  path.lineCapStyle = kCGLineCapRound;  [path stroke];}

ViewController

這個(gè)比較容易理解:分別跳轉(zhuǎn)兩個(gè)界面:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {  if (indexPath.row == 0) {    TeacViewController *vc = [[TeacViewController alloc] init];    [self.navigationController pushViewController:vc animated:YES];  } else {    StudViewController *vc = [[StudViewController alloc] init];    [self.navigationController pushViewController:vc animated:YES];  }}

TeacViewController

主要的應(yīng)用就是調(diào)用GestureLockViewDelegate了,接受并校驗(yàn)密碼,

#pragma mark gestureLockView代理事件- (void)gestureLockView:(GestureLockView *)lockView drawRectFinished:(NSMutableString *)gesturePassword {  [self createGesturesPassword:gesturePassword];}//創(chuàng)建手勢(shì)密碼- (void)createGesturesPassword:(NSMutableString *)gesturePassword {  if (self.lastGesturePsw.length == 0) {    if (gesturePassword.length < 4) {      self.lastGesturePsw = nil;      [self.gestureLockView checkTeacResult:TeacKindTypeNoEnough];      self.statusLabel.text = @"至少連接4個(gè)點(diǎn),重新輸入";      [self shakeAnimationForView:self.statusLabel];      return;    }    self.lastGesturePsw = gesturePassword;    [self.gestureLockView checkTeacResult:TeacKindTypeTrue];    NSLog(@"---%@", self.lastGesturePsw);    self.statusLabel.text = [NSString stringWithFormat:@"密碼是%@", gesturePassword];  }}

兩個(gè)按鈕的點(diǎn)擊事件

#pragma mark 按鈕點(diǎn)擊事件//重置按鈕- (void)resetBtnClick:(UIButton *)btn {  self.lastGesturePsw = nil;  [TeacViewController addGesturePassword:@""];  [self.gestureLockView checkTeacResult:TeacKindTypeNoEnough];  self.statusLabel.text = @"請(qǐng)繪制手勢(shì)密碼";  NSLog(@"resetPwd == %@, resetUserDefaultsPwd == %@", self.lastGesturePsw, [TeacViewController gesturePassword]);}//確定按鈕- (void)sureBtnClick:(UIButton *)btn {  if (!self.lastGesturePsw) {    self.statusLabel.text = @"請(qǐng)繪制手勢(shì)密碼";    return;  }  [TeacViewController addGesturePassword:self.lastGesturePsw];  [self.gestureLockView checkTeacResult:TeacKindTypeTrue];  self.statusLabel.text = @"密碼設(shè)置成功";  NSLog(@"resetPwd == %@, resetUserDefaultsPwd == %@", self.lastGesturePsw, [TeacViewController gesturePassword]);//  [self.navigationController popViewControllerAnimated:YES];}

用本地存儲(chǔ)進(jìn)行模擬

#pragma mark 本地存儲(chǔ)模擬+ (void)deleteGestuesPassword {  [[NSUserDefaults standardUserDefaults] removeObjectForKey:GESPWD];  [[NSUserDefaults standardUserDefaults] synchronize];}+ (void)addGesturePassword:(NSString *)gesturePassword {  [[NSUserDefaults standardUserDefaults] setObject:gesturePassword forKey:GESPWD];  [[NSUserDefaults standardUserDefaults] synchronize];}+ (NSString *)gesturePassword {  return [[NSUserDefaults standardUserDefaults] objectForKey:GESPWD];}

StudViewController

GestureLockDelegate代理方法 并校驗(yàn)對(duì)當(dāng)前的手勢(shì)密碼和本地存儲(chǔ)的教師端密碼

#pragma mark 手勢(shì)密碼界面代理- (void)gestureLockView:(GestureLockView *)lockView drawRectFinished:(NSMutableString *)gesturePassword {  [self validateGesturePassword:gesturePassword];}//校驗(yàn)手勢(shì)密碼- (void)validateGesturePassword:(NSMutableString *)gesturePassword {    if (gesturePassword.length < 4) {    self.statusLabel.text = @"至少連接4個(gè)點(diǎn),重新輸入";    [self.gestureLockView checkPwdResult:ResultKindTypeNoEnough];    [self shakeAnimationForView:self.statusLabel];    return;  }  self.lastGesturePsw = gesturePassword;      /*滑完直接校驗(yàn)*/  NSLog(@"validPwd == %@, validUserDefaultsPwd == %@", self.lastGesturePsw, [StudViewController gesturePassword]);  static NSInteger errorCount = 5;    if ([self.lastGesturePsw isEqualToString:[StudViewController gesturePassword]]) {    [self.gestureLockView checkPwdResult:ResultKindTypeTrue];    self.statusLabel.text = @"密碼校驗(yàn)成功";    [self shakeAnimationForView:self.statusLabel];  } else {    [self.gestureLockView checkPwdResult:ResultKindTypeFalse];    errorCount = errorCount - 1;    if (errorCount == 0) {      //已經(jīng)輸錯(cuò)5次      self.statusLabel.text = @"請(qǐng)重新輸入密碼";      errorCount = 5;      return;    }    self.statusLabel.text = [NSString stringWithFormat:@"密碼錯(cuò)誤, 還可以再輸入%ld次", errorCount];    [self shakeAnimationForView:self.statusLabel];  }}

清除按鈕點(diǎn)擊事件 改變self.gestureLockView中的resultType 進(jìn)行界面的重繪等調(diào)整

- (void)clearBtnClick:(UIButton *)btn {  self.statusLabel.text = @"清除!!!";  [self.gestureLockView checkPwdResult:ResultKindTypeClear];  [self shakeAnimationForView:self.statusLabel];}

本地存儲(chǔ):這里也有一個(gè)本地存儲(chǔ) 和教師端對(duì)應(yīng) (其實(shí)可以單獨(dú)封裝出來(lái)的)

#pragma mark 本地存儲(chǔ)模擬+ (void)deleteGestuesPassword {  [[NSUserDefaults standardUserDefaults] removeObjectForKey:GESPWD];  [[NSUserDefaults standardUserDefaults] synchronize];}+ (void)addGesturePassword:(NSString *)gesturePassword {  [[NSUserDefaults standardUserDefaults] setObject:gesturePassword forKey:GESPWD];  [[NSUserDefaults standardUserDefaults] synchronize];}+ (NSString *)gesturePassword {  return [[NSUserDefaults standardUserDefaults] objectForKey:GESPWD];}

以上,就是這個(gè)功能實(shí)現(xiàn)的大體流程了,捋順了思路來(lái)看其實(shí)還是蠻明確的,當(dāng)時(shí)做的時(shí)候也是走路挖坑填坑的,發(fā)現(xiàn)這樣把自己的思路寫(xiě)下來(lái)還真是蠻有收獲的,希望自己更好的進(jìn)步,如果您看到這兒覺(jué)得有不合理的地方歡迎隨時(shí)和我溝通哈。

源代碼連接:https://github.com/irembeu/LGJGestureLockDemo.git

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到IOS開(kāi)發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 卢湾区| 贡嘎县| 灌南县| 招远市| 东丰县| 荆门市| 手游| 安远县| 枣强县| 广平县| 舞阳县| 五河县| 永吉县| 昌乐县| 镇原县| 博兴县| 汉阴县| 青冈县| 灵川县| 土默特左旗| 聊城市| 自治县| 太保市| 河西区| 平谷区| 平罗县| 博乐市| 湖州市| 张家口市| 隆德县| 湖北省| 金寨县| 乌拉特前旗| 巴彦县| 休宁县| 十堰市| 南通市| 肇东市| 乌什县| 肇东市| 乌兰察布市|