iOS手势解锁

练习的时候做过的一个demo,附上github地址:https://github.com/H0ng/GestureLock

技术分享

#HHView.h

#import <UIKit/UIKit.h>
@class HHView;
@protocol HHViewDelegate <NSObject>

@optional
-(void)showView:(HHView*)showView didFinishedPath:(NSString *)path;
@end

@interface HHView : UIView
@property (nonatomic, weak) id<HHViewDelegate> delegate;
@end

 #HHView.m

#import "HHView.h"
#import "HHCircleButton.h"

@interface HHView()
@property (nonatomic, strong) NSMutableArray *totalpointPaths;
@property (nonatomic, assign) CGPoint currentPoint;
@end
@implementation HHView

-(NSMutableArray *)totalpointPaths
{
    if (_totalpointPaths == nil) {
        NSMutableArray *array = [NSMutableArray array];
        _totalpointPaths = array;
    }
    return _totalpointPaths;
}

/**
 *  通过代码创建会调用此方法
 */
-(instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self setup];
    }
    return self;
}
/**
 *  通过xib,sb创建会调用此方法
 */
-(id)initWithCoder:(NSCoder *)decoder
{
    if (self = [super initWithCoder:decoder]) {
        [self setup];
    }
    return self;
}


/**
 *  创建9个按钮
 */
-(void)setup
{
    for (int i = 0; i < 9; i++)
    {
        HHCircleButton *button = [HHCircleButton buttonWithType:UIButtonTypeCustom];
        button.tag = i;
        [self addSubview:button];
    }
}

/**
 *  9个按钮的frame
 */
-(void)layoutSubviews
{
    [super layoutSubviews];
    
    for (int i = 0; i < self.subviews.count; i++) {
        HHCircleButton *button = self.subviews[i];
        int col = i / 3;
        int row = i % 3;
        CGFloat buttonW = 74;
        CGFloat buttonH = 74;
        CGFloat leftParading = (self.frame.size.width - buttonW * 3) / 4.0;
        CGFloat buttonX = leftParading + (leftParading + buttonW) * row;
        CGFloat buttonY = leftParading + (leftParading + buttonH) * col;
        button.frame = CGRectMake(buttonX, buttonY, buttonW, buttonH);
        }
}

#pragma mark - 返回touches点的point
-(CGPoint)pointWithTouches:(NSSet *)touches
{
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];
    return point;
}

#pragma mark - 判断触点是否在按钮的frame内
-(HHCircleButton *)buttonWithPoint:(CGPoint)point
{
    for (HHCircleButton *btn in self.subviews)
    {
        CGFloat wh = 24;
        CGFloat frameX = btn.center.x - wh * 0.5;
        CGFloat frameY = btn.center.y - wh * 0.5;
        if (CGRectContainsPoint(CGRectMake(frameX, frameY, wh, wh), point))
        {
            return btn;
        }
    }
    return nil;
}

#pragma mark - touchesBegan
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.currentPoint = CGPointZero;
    //获取当前触摸点
    CGPoint point = [self pointWithTouches:touches];
    
    //判断如果触摸点在某个btn上,返回这个btn,否则返回nil
    HHCircleButton *btn = [self buttonWithPoint:point];
    
    //判断是否在btn上,以及这个btn是否被选中,如果没有就选中
    if (btn && btn.selected == NO) {
        btn.selected = YES;
        [self.totalpointPaths addObject:btn];
    }
    //重绘
    [self setNeedsDisplay];
}

#pragma mark - touchesMoved
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint point = [self pointWithTouches:touches];
    
    HHCircleButton *btn = [self buttonWithPoint:point];
    
    //判断按钮是否已经被选中了
    if (btn && btn.selected == NO) {
        btn.selected = YES;
        [self.totalpointPaths addObject:btn];
    }else{
        self.currentPoint = point;
    }
    [self setNeedsDisplay];
}

#pragma mark - touchesEnded
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//    CGPoint point = [self pointWithTouches:touches];
//    
//    HHCircleButton *btn = [self buttonWithPoint:point];
//    
//    if (btn && btn.selected == NO) {
//        btn.selected = YES;
//        [self.totalpointPaths addObject:btn];
//    }else{
//        self.currentPoint = point;
//    }
    
    if ([self.delegate respondsToSelector:@selector(showView:didFinishedPath:)]) {
        NSMutableString *path = [NSMutableString string];
        for (HHCircleButton *btn in self.totalpointPaths) {
            [path appendFormat:@"%ld",(long)btn.tag];
        }
        [self.delegate showView:self didFinishedPath:path];
    }

    //将current点清0
    self.currentPoint = CGPointZero;
    
//    //然后将所有按钮设置为非选中状态
//    [self.totalpointPaths makeObjectsPerformSelector:@selector(setSelected:) withObject:@(NO)];
//    [self.totalpointPaths removeAllObjects];
    [self setNeedsDisplay];
    
}

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self touchesEnded:touches withEvent:event];
}

#pragma mark - 绘制按钮间连线
-(void)drawRect:(CGRect)rect
{
    if (self.totalpointPaths.count == 0) return;
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    for(int index = 0; index < self.totalpointPaths.count; index++) {
        HHCircleButton *btn = self.totalpointPaths[index];
        if (index == 0) {
            [path moveToPoint:btn.center];
        }else{
            [path addLineToPoint:btn.center];
        }
    }
    
    if (CGPointEqualToPoint(self.currentPoint, CGPointZero) == NO) {
        [path addLineToPoint:self.currentPoint];
    }
    path.lineWidth = 10;
    path.lineJoinStyle = kCGLineJoinRound;
    [[UIColor colorWithRed:32/255.0 green:210/255.0 blue:254/255.0 alpha:0.5] set];
    [path stroke];
}

 

#HHCircleButton.h

#import <UIKit/UIKit.h>

@interface HHCircleButton : UIButton

@end

 

#HHCircleButton.m

#import "HHCircleButton.h"

@implementation HHCircleButton

-(id)initWithCoder:(NSCoder *)decoder
{
    if (self = [super initWithCoder:decoder]) {
        [self setup];
    }
    return self;
}

-(instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self setup];
    }
    return self;
}

#pragma mark - 设置按钮状态图片
-(void)setup
{
    self.userInteractionEnabled = NO;
    
    [self setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
    [self setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];
}

@end

 

#ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController


@end

 

#ViewController.m

#import "ViewController.h"
#import "HHView.h"

@interface ViewController ()<HHViewDelegate>
//storyboard连线
@property (weak, nonatomic) IBOutlet HHView *showView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.showView.delegate = self;
}
-(void)showView:(HHView *)showView didFinishedPath:(NSString *)path
{
    NSLog(@"%@",path);
}

@end

 

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