你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS實現手勢解鎖操作

iOS實現手勢解鎖操作

編輯:IOS開發綜合

本文主要介紹通過手勢識別實現手勢解鎖功能,這個方法被廣泛用於手機解鎖,密碼驗證,快捷支付等功能實現。事例效果如下所示。

 首先,我們先分析功能的實現過程,首先我們需要先看大致的實現過程:

1.加載九宮格頁面

2.實現按鈕被點擊及滑動過程中按鈕狀態的改變

3.實現滑動過程中的連線

4.繪制完畢後判定密碼是否正確,

5.密碼判定後實現跳轉。

下面我們就來用代碼實現上述五個過程。

1.加載九宮格界面

1.1九宮格內控件的分布 3*3 ,我們可以自定義view(包含3*3個按鈕),添加到viewController上。

//添加view中子控件
-(void)awakeFromNib
{
//  創建按鈕
  for (int i=0; i<9; i++) {
    self.LineColor=[UIColor blueColor];
  UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
    btn.userInteractionEnabled=NO;
  //    設置按鈕屬性
  [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
    [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateHighlighted ];
    [btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_error"] forState:UIControlStateDisabled];
    [self addSubview:btn];
  }
}
//布局view子控件
-(void)layoutSubviews
{
  [super layoutSubviews];
  CGFloat width=74;
  CGFloat height=74;
  CGFloat Margin=(self.bounds.size.width-3*width)/2;
//  遍歷設置9個button的frame
  [self.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//    通過tag設置按鈕的索引標識
    obj.tag=idx;
      int row=(int)idx/3;
      int col=idx%3;
    obj.frame=CGRectMake(col*(Margin + width), row*(Margin +height), width, height);
  }];
}


1.2將定義好的view通過xib添加到viewController上

首先,定義一個blockview(九宮格view)的類方法,

// 加載xib文件
+(instancetype)lockView
{
  return [[[NSBundle mainBundle]loadNibNamed:@"MYblockView" owner:nil options:nil]lastObject];
}

然後加載到控制器上。

//  設置控制器view的背景圖片
  self.view.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageNamed:@"bg"]];
  MYblockView *blockView=[MYblockView lockView];
  blockView.center=self.view.center;
//  將blockview添加到viewController上
  [self.view addSubview:blockView];

2.實現按鈕被點擊及滑動過程中按鈕狀態的改變

2.1定義數組類型的成員屬性,用來裝被點擊的按鈕

@property(nonatomic,strong)NSMutableArray *btnArr;
//懶加載
-(NSMutableArray *)btnArr
{
  if (_btnArr==nil) {
    _btnArr=[NSMutableArray array];
  }
  return _btnArr;
}

2.2創建路徑,繪制圖形

#pragma mark----繪制圖形
-(void)drawRect:(CGRect)rect
{
  if (self.btnArr.count==0 ) {
    return;
  }
//  創建路徑
  UIBezierPath *path=[UIBezierPath bezierPath];
//  遍歷所有按鈕進行繪制
  [self.btnArr enumerateObjectsUsingBlock:^(__kindof UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//    第一個按鈕,中心點就是起點
    if (idx==0) {
      [path moveToPoint:obj.center];
    }else
    {
      [path addLineToPoint:obj.center];
    }
  }];
  [path addLineToPoint:self.currentPoint];
//  設置路徑屬性
  path.lineWidth=10;
  path.lineCapStyle=kCGLineCapRound;
  path.lineJoinStyle=kCGLineJoinRound;
  [self.LineColor setStroke];
//  渲染
  [path stroke];
}
 

2.3開始觸摸

#pragma mark-----開始觸摸
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 獲取觸摸對象
  UITouch *touch=touches.anyObject;
//  獲取觸摸點
  CGPoint loc=[touch locationInView:self];
//  遍歷按鈕,判定觸摸點是否在按鈕上
  [self.subviews enumerateObjectsUsingBlock:^(__kindof UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    BOOL isContains=CGRectContainsPoint(obj.frame, loc);
//    如果在按鈕上,將當前按鈕保存在數組中,並改變按鈕狀態
    if (isContains&&obj.highlighted==NO) {
      [self.btnArr addObject:obj];
      obj.highlighted=YES;
    }else
    {
      obj.highlighted=NO;
    }
  }];
}

2.4滑動過程中,重繪

#pragma mark----開始滑動
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//  獲取觸摸對象
  UITouch *touch=touches.anyObject;
//  獲取觸摸點
  CGPoint loc=[touch locationInView:self];
  self.currentPoint=loc;
//  遍歷按鈕,如果按鈕在滑動路徑上,就改變按鈕狀態
  [self.subviews enumerateObjectsUsingBlock:^(__kindof UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    BOOL isContains=CGRectContainsPoint(obj.frame, loc);
    if (isContains&&obj.highlighted==NO) {
      [self.btnArr addObject:obj];
      obj.highlighted=YES;
    }
  }];
//  重繪
  [self setNeedsDisplay];
   }

3.實現滑動過程中的連線和4.繪制完畢後判定密碼是否正確

#pragma mark----停止滑動結束
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//  定義最後一個按鈕
  UIButton *lastBtn=[self.btnArr lastObject];
//  將最後一個按鈕中心點定義為相對滑動的當前點
  self.currentPoint=lastBtn.center;
//  重繪
  [self setNeedsDisplay];
//  判定密碼
  self.password=[NSMutableString string];
   [self.btnArr enumerateObjectsUsingBlock:^( UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
     [self.password appendFormat:@"%@",@(obj.tag)];
   }];
  NSLog(@"%@",self.password);
  BOOL isOk;
  if ([self.delegate respondsToSelector:@selector(blockView:finishedWithPassword:)]) {
    isOk= [self.delegate blockView:self finishedWithPassword:self.password];
  }
  if (isOk) {
    [self.btnArr enumerateObjectsUsingBlock:^(UIButton* _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
      obj.highlighted=NO;
      
    }];
    [self.btnArr removeAllObjects];
    [self setNeedsDisplay];
    
    NSLog(@"密碼正確");
  }else
  {
    NSLog(@"密碼錯誤");
  }

}
 

注意:我們在密碼判定過程中是通過根據先前布局按鈕的時候定義的按鈕tag值進行字符串拼接,密碼傳值是通過代理實現。

#import <UIKit/UIKit.h>
@class MYblockView;
//聲明代理
@protocol MYblockViewDelegate <NSObject>
@optional
//代理方法
-(BOOL) blockView:(MYblockView *)blockView finishedWithPassword:(NSString *)password;
@end
@interface MYblockView : UIView
+(instancetype)lockView;
//設置代理成員屬性
@property(nonatomic,weak)id<MYblockViewDelegate>delegate;
@end

5.密碼判定後實現跳轉。

else
  {
    
//    關閉用戶交互
    self.userInteractionEnabled=NO;
    [self.btnArr enumerateObjectsUsingBlock:^(UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
      self.LineColor=[UIColor redColor];
      obj.highlighted=NO;
      obj.enabled=NO;
      [self setNeedsDisplay];
      
      dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//        回復按鈕狀態
       [self.btnArr enumerateObjectsUsingBlock:^(UIButton * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
         obj.enabled=YES;        
       }];
//        恢復線條的顏色
        self.LineColor=[UIColor blueColor];
        
        [self.btnArr removeAllObjects];
        
        [self setNeedsDisplay];      
      });
      }];  
    NSLog(@"密碼錯誤");
  }
  self.userInteractionEnabled=YES;

}

代理判定密碼並實現跳轉

-(BOOL)blockView:(MYblockView *)blockView finishedWithPassword:(NSString *)password
{
  if ([password isEqualToString:@"012"]) {
    
    UIViewController *two=[UIViewController new];
    two.view.backgroundColor=[UIColor greenColor];
    [self.navigationController pushViewController:two animated:YES];
    return YES;
  }
  else{
      return NO;
  }
}

最後設置控制器navigationbar屬性

 [self.navigationController.navigationBar setBackgroundColor:[UIColor redColor]];
  [ self.navigationController.navigationBar setTitleTextAttributes:@{
                              NSForegroundColorAttributeName :[UIColor whiteColor]  
                                   }];

以上就是本文的全部內容,希望對大家的學習有所幫助。

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved