iOS开发之手势解锁详解

A.需求
1.九宫格手势解锁
2.使用了绘图和手势事件
code source: https://github.com/hellovoidworld/GestureUnlockDemo
B.实现
  • 使用按钮来处理每个圆点
  • 使用代码生成按钮
  • 取消按钮点击事件
  • 设置普通状态和选中状态的背景图片
  • CGRectContainsPoint,移动到按钮范围内改变按钮为选中状态
  • 按钮的连接:使用数组存储被选中的所有按钮,画上连线
  • 已经连线的按钮不需要再连线
  • 触摸结束清空连线和按钮选中状态
  • 移动中也要画出线,最后的点用来辅助画移动中的线
  • 解决bug:每次触摸开始重置当前画笔位置
  • 设置触摸触发选中的按钮内部范围
  • 使用tag记录按钮的选中顺序轨迹,触摸结束取得轨迹
  • 封装整个手势解锁view成为一个自定义控件
  • 封装按钮称为自定类

    1.准备基础界面,使用一个UIView作为解锁画面
    2.在控制器ViewController设置一下背景图片和状态栏
    //
     //  ViewController.m
     //  HVWLockView
     //
     //  Created by hellovoidworld on 15/1/12.
     //  Copyright (c) 2015年 hellovoidworld. All rights reserved.
     //
     
     #import "ViewController.h"
     
     @interface ViewController ()
     
     @end
     
     @implementation ViewController
     
     - (void)viewDidLoad {
         [super viewDidLoad];
         // Do any additional setup after loading the view, typically from a nib.
        
         // 设置背景
         self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"Home_refresh_bg"]];
     }
     
     /** 设置状态栏样式 */
     - (UIStatusBarStyle)preferredStatusBarStyle {
         return UIStatusBarStyleLightContent;
     }
     
     - (void)didReceiveMemoryWarning {
         [super didReceiveMemoryWarning];
         // Dispose of any resources that can be recreated.
     }
     
     
     @end

    3.自定义解锁画面的类HVWLockView
    4.使用代码初始化HVWLockView的子控件—按钮,设置按钮的样式、位置尺寸
    //
     //  HVWLockView.m
     //  HVWLockView
     //
     //  Created by hellovoidworld on 15/1/12.
     //  Copyright (c) 2015年 hellovoidworld. All rights reserved.
     //
     
     #import "HVWLockView.h"
     #import "HVWLockButton.h"
     
     #define BUTTON_COUNT 9
     #define BUTTON_COL_COUNT 3
     
     @implementation HVWLockView
     
     #pragma mark - 初始化方法
     /** 使用文件初始化 */
     - (id)initWithCoder:(NSCoder *)aDecoder {
         if (self = [super initWithCoder:aDecoder]) {
             [self initView];
         }
         return self;
     }
     
     /** 使用代码初始化 */
     - (instancetype)initWithFrame:(CGRect)frame {
         if (self = [super initWithFrame:frame]) {
             [self initView];
         }
         return self;
     }
     
     /** 初始化view内的控件(按钮) */
     - (void) initView {
         for (int i=0; i
    out:
    5.实现触摸事件方法
    (1)点击开始,使被点击的按钮改变为选中状态(改变图片)
    (2)点击拖曳中,同样使被触碰到的按钮改变为选中状态
    (3)点击结束,清空选中状态
    (4)小修改:把HVWLockView背景改为透明
    HVWLockView:
    UITouch * touch = [ touches anyObject ]; CGPoint touchLocation = [ touch locationInView : touch . view ]; // 检测哪个按钮被点中了 for ( HVWLockButton * button in self . subviews ) { if ( CGRectContainsPoint ( button . frame , touchLocation )) { button . selected = YES ; } } } - ( void ) touchesMoved :( NSSet *) touches withEvent :( UIEvent *) event { UITouch * touch = [ touches anyObject ]; CGPoint touchLocation = [ touch locationInView : touch . view ]; // 检测哪个按钮被点中了 for ( HVWLockButton * button in self . subviews ) { if ( CGRectContainsPoint ( button . frame , touchLocation )) { button . selected = YES ; } } } - ( void ) touchesEnded :( NSSet *) touches withEvent :( UIEvent *) event { // 消除所有按钮选中状态 for ( HVWLockButton * button in self . subviews ) { button . selected = NO ; } }
    out:
    6.画出连接线
    (1)优化:将按钮封装为一个类HVWLockButton
    //
     //  HVWLockButton.m
     //  HVWLockView
     //
     //  Created by hellovoidworld on 15/1/12.
     //  Copyright (c) 2015年 hellovoidworld. All rights reserved.
     //
     
     #import "HVWLockButton.h"
     
     @implementation HVWLockButton
     
     /** 使用文件创建会调用 */
     - (id)initWithCoder:(NSCoder *)aDecoder {
         if (self = [super initWithCoder:aDecoder]) {
             [self initLockButton];
         }
         return self;
     }
     
     /** 使用代码创建会调用 */
     - (instancetype)initWithFrame:(CGRect)frame {
         if (self = [super initWithFrame:frame]) {
             [self initLockButton];
         }
         return self;
     }
     
     /** 初始化 */
     - (void) initLockButton {
         // 取消交互事件(点击)
         self.userInteractionEnabled = NO;
        
         // 设置普通状态图片
         [self setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
        
         // 设置选中状态图片
         [self setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];
     }
     
     @end

    (2)使用一个数组来存储已经被选择的按钮
    (3)把触碰到的按钮到加入到上述数组中
    (4)在绘图方法中把数组内的按钮用线连起来
    (5)使用一个成员变量来存储当前触摸位置,画出最后触摸的按钮到现触摸点的线
    (6)重复触碰同一个按钮的时候,不用重绘和计算
    (7)创建一个代理方法,在触摸结束的时候输出轨迹序列
    (8)精简一下代码
     #define BUTTON_COUNT 9
     #define BUTTON_COL_COUNT 3
     
     @interface HVWLockView()
     
     /** 已选择按钮数组 */
     @property(nonatomic, strong) NSMutableArray *selectedButtons;
     
     /** 触摸位置 */
     @property(nonatomic, assign) CGPoint currentTouchLocation;
     
     @end
     
     @implementation HVWLockView
     
     /** 初始化数组 */
     - (NSMutableArray *)selectedButtons {
         if (nil == _selectedButtons) {
             _selectedButtons = [NSMutableArray array];
         }
         return _selectedButtons;
     }
     
     #pragma mark - 初始化方法
     /** 使用文件初始化 */
     - (id)initWithCoder:(NSCoder *)aDecoder {
         if (self = [super initWithCoder:aDecoder]) {
             [self initView];
         }
         return self;
     }
     
     /** 使用代码初始化 */
     - (instancetype)initWithFrame:(CGRect)frame {
         if (self = [super initWithFrame:frame]) {
             [self initView];
         }
         return self;
     }
     
     /** 初始化view内的控件(按钮) */
     - (void) initView {
         // 设置透明背景
         self.backgroundColor = [[UIColor alloc] initWithRed:1 green:1 blue:1 alpha:0];
        
         for (int i=0; i

    out:
    2015-01-12 16:39:23.794 HVWLockView[10274:184387] 手势解锁的输出序列:01246

你可能感兴趣的:(iOS)