ios手势解锁

手势的解锁效果如下:

技术分享技术分享


编写环境:Xcode 6


代码文件视图:

技术分享


以九个按钮排列成九宫格形成手势解锁视图,自定义一个继承自UIButton得类来描述按钮(对按钮进行封装)

#import "CXCircleView.h"

@implementation CXCircleView


- (instancetype)initWithFrame:(CGRect)frame

{

    if (self = [super initWithFrame:frame]) {

        [self initialiseButton];

    }

    return self;

}


- (id)initWithCoder:(NSCoder *)aDecoder

{

    if (self = [super initWithCoder:aDecoder]) {

        [self initialiseButton];

    }

    return self;

}

/**

 *  初始化按钮

 */

- (void)initialiseButton

{

    // 取消用户交互

    self.userInteractionEnabled = NO;

    [self setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];

    // 被选中状态下显示该图片,目的是手指滑动时按钮全部高亮

    [self setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];

}

在storyboard里,为控制器的view上添加一个占满屏幕的UIImageView,设置背景图,再为九个按钮添加一个父控件View来排列按钮,父控件View的宽高大小设置为375(暂时不做屏幕适配,直接在肾6屏幕上显示),为该view自定义一个类,在该类里面实现手势解锁功能

#import "CXLocView.h"

#import "CXCircleView.h"

// 按钮总数

static const int CXButtonCount = 9;

// 九宫格列数

static const int CXColumns = 3;



@interface CXLocView ()


/**

 *  被选中的按钮

 */

@property (nonatomic,strong) NSMutableArray *totalSelectedBtnArr;

/**

 *  不在按钮范围上的当前点

 */

@property (nonatomic,assign) CGPoint currPoint;

@end



@implementation CXLocView


- (NSMutableArray *)totalSelectedBtnArr

{

    if (_totalSelectedBtnArr == nil) {

        _totalSelectedBtnArr = [NSMutableArray array];

    }

    return _totalSelectedBtnArr;

}



/**

 *  初始化view

 */

- (instancetype)initWithFrame:(CGRect)frame

{

    if (self = [super initWithFrame:frame]) {

        [self initialiseView];

    }

    return self;

}



- (id)initWithCoder:(NSCoder *)aDecoder

{

    if (self = [super initWithCoder:aDecoder]) {

        [self initialiseView];

    }

    return self;

}

/**

 *  初始化view,为view添加九宫格按钮

 */

- (void)initialiseView

{

    for (int i = 0; i < CXButtonCount; i++) {

        CXCircleView *btn = [CXCircleView buttonWithType:UIButtonTypeCustom];

        btn.tag = i;

        [self addSubview:btn];

    }

}


/**

 *  设置按钮的frame

 */

- (void)layoutSubviews

{

    // 调用父类的方法

    [super layoutSubviews];

    for (int i = 0; i < CXButtonCount; i++) {

        CGFloat btnW = 95.0;

        CGFloat btnH = btnW;

        // 按钮所在行号

        int row = i / CXColumns;

        // 按钮所在列号

        int col = i % CXColumns;

        // 按钮间距

        CGFloat btnMarginX = (self.frame.size.width - (CXColumns * btnW)) / (CXColumns + 1);

        CGFloat btnMarginY = btnMarginX;

        CGFloat btnX = btnMarginX + (btnW + btnMarginX) * col;

        CGFloat btnY = btnMarginY + (btnH + btnMarginY) * row;

        [self.subviews[i] setFrame:CGRectMake(btnX, btnY, btnW, btnH)];

    }

}


/**

 *  获取当前触摸点

 */

- (CGPoint)pointWithTouches:(NSSet *)touches

{

    UITouch *touch = [touches anyObject];

    return [touch locationInView:touch.view];

}


/**

 *  获取被触摸的按钮

 */

- (CXCircleView *)touchBtnWithPoint:(CGPoint)point

{

    for (CXCircleView *btn in self.subviews) {

        // 缩小按钮的有效范围

        CGFloat wh = 60;

        CGFloat btnX = btn.center.x - wh * 0.5;

        CGFloat btnY = btn.center.y - wh * 0.5;

        if(CGRectContainsPoint(CGRectMake(btnX, btnY, wh, wh), point))

        {

            return btn;

        }

        

    }

    return nil;

}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    // 将当前点清零

    self.currPoint = CGPointZero;

    // 获得当前的点

    CGPoint point = [self pointWithTouches:touches];

    // 获得该点所在的范围的按钮

    CXCircleView *btn = [self touchBtnWithPoint:point];

    // 存在该按钮且未被选中

    if (btn && btn.selected == NO) {

        btn.selected = YES;

        [self.totalSelectedBtnArr addObject:btn];

    }

    [self setNeedsDisplay];

}


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

{

    CGPoint point =  [self pointWithTouches:touches];

    CXCircleView *btn = [self touchBtnWithPoint:point];

    if (btn && btn.selected == NO) {

        btn.selected = YES;

        [self.totalSelectedBtnArr addObject:btn];

    }

    else

    {

        self.currPoint = point;

    }

    [self setNeedsDisplay];

}


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

{

    NSMutableString *pwd = [NSMutableString string];

    for (CXCircleView *btn in self.totalSelectedBtnArr) {

        [pwd appendFormat:@"%d",(int)btn.tag];

    }

    // 添加代理,将密码传递给控制器

    if ([self.delegate respondsToSelector:@selector(CXLocView:DidFinishPassWord:)]) {

        [self.delegate CXLocView:self DidFinishPassWord:pwd];

    }

    

    [self.subviews makeObjectsPerformSelector:@selector(setSelected:) withObject:@(NO)];

    [self.totalSelectedBtnArr removeAllObjects];

    // 重绘

    [self setNeedsDisplay];

}



- (void)drawRect:(CGRect)rect

{

    // 如果没有被选按钮则返回

    if(self.totalSelectedBtnArr.count == 0) return;

    UIBezierPath *path = [UIBezierPath bezierPath];

    for (int index = 0; index < self.totalSelectedBtnArr.count; index++) {

#warning CXCircleView *btn = self.subviews[index]; 错写成subviews

        CXCircleView *btn = self.totalSelectedBtnArr[index];

        if (0 == index) {

            [path moveToPoint:btn.center];


        }

        else

        {

            [path addLineToPoint:btn.center];


        }


    }

    

    // 画非按钮上的线

    if (CGPointEqualToPoint(_currPoint, CGPointZero) == NO) {

        [path addLineToPoint:_currPoint];

    }

    

    path.lineWidth = 8;

    path.lineJoinStyle = kCGLineJoinRound;

    path.lineCapStyle = kCGLineCapRound;

    [[UIColor colorWithRed:32/255.0 green:210/255.0 blue:254/255.0 alpha:0.7] set];

    [path stroke];

}


@end


为该类添加代理

#import <UIKit/UIKit.h>

@class CXLocView;

@protocol CXLocViewDelegate <NSObject>

@optional

- (void)CXLocView:(CXLocView *)view DidFinishPassWord:(NSString *)pwd;


@end



@interface CXLocView : UIView

#import <UIKit/UIKit.h>

@class CXLocView;

@protocol CXLocViewDelegate <NSObject>

@optional

- (void)CXLocView:(CXLocView *)view DidFinishPassWord:(NSString *)pwd;


@end



@interface CXLocView : UIView


@property (weak,nonatomic) IBOutlet id<CXLocViewDelegate> delegate;


@end


直接在storyboard里设置代理,如图

技术分享


手势解锁完成!

需要源码的留下邮箱。

ps:有谁知道怎么在博客上上传gif,我上传了gif格式的但是是静态的动不了


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。