下班回家,随便写写,写了个手势解锁,很多app都有。自己封装了一个,手势解锁视图。代码如下:
头文件
#import <UIKit/UIKit.h>
typedef void(^JGestureLockViewRightResultBlock)();
@interface JGestureLockView : UIView
@property(nonatomic,copy)NSString *rightSecret;
@property(nonatomic,copy)JGestureLockViewRightResultBlock resultBlock;
@end
源文件:
//
// JGestureLockView.m
// GestureLockDemo
//
// Created by jiangtd on 16/6/12.
// Copyright © 2016年 jiangtd. All rights reserved.
//
#import "JGestureLockView.h"
#define SelectedImgName @"1.jpg"
#define NormalImgName @"2.jpg"
#define WrongSelectedImgName @"33.jpg"
#define WrongLineImgName @"5"
#define RightLineImgName @"6.jpg"
#define LockBtnSize 70
#define GestureCirle 20
#define LineWith 20
typedef NS_ENUM(NSInteger,JGestureLockViewState){
JGestureLockViewStateRight,
JGestureLockViewStateWrong,
JGestureLockViewStateWaitingJudge,
JGestureLockViewStateNone,
};
@interface JGestureLockView ()
@property(nonatomic,strong)NSMutableArray *viewArr;
@property(nonatomic,strong)NSMutableArray *locationArr;
@property(nonatomic,strong)NSMutableArray *selectedArr;
@property(nonatomic,assign)JGestureLockViewState state;
@property(nonatomic,assign)CGPoint gestureLocation;
@property(nonatomic,strong)NSTimer *timer;
@end
@implementation JGestureLockView
-(id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self setUpUI];
}
return self;
}
-(void)setUpUI{
_state = JGestureLockViewStateNone;
for (int i = 0; i < 9; i++) {
UIImageView *imgView = [[UIImageView alloc] init];
[self.viewArr addObject:imgView];
imgView.image = [UIImage imageNamed:NormalImgName];
imgView.frame = CGRectMake(0, 0, LockBtnSize, LockBtnSize);
imgView.layer.masksToBounds = YES;
imgView.layer.cornerRadius = LockBtnSize / 2;
[self addSubview:imgView];
}
}
-(void)layoutSubviews
{
[self calculateViewLocation];
for (int i = 0; i < 9; i++) {
if (self.viewArr.count - 1 >= i && self.locationArr.count - 1 >= i) {
UIImageView *imgView = self.viewArr[i];
CGPoint center = [self.locationArr[i] CGPointValue];
imgView.center = center;
}
}
}
-(void)calculateViewLocation{
CGFloat marignWidth = 25;
CGFloat lineWidth = (self.frame.size.width - marignWidth * 2 - 3 * LockBtnSize) / 2;
CGFloat beginX = marignWidth + LockBtnSize / 2;
CGFloat beginY = marignWidth + LockBtnSize / 2;
for (int i = 0; i< 9; i++) {
CGFloat x = beginX + (i % 3) * LockBtnSize + (i % 3) * lineWidth;
CGFloat y = beginY + (i / 3) * LockBtnSize + (i / 3) *lineWidth;
CGPoint viewCenterPoint = CGPointMake(x, y);
[self.locationArr addObject:[NSValue valueWithCGPoint:viewCenterPoint]];
}
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
_state = JGestureLockViewStateNone;
//清除之前选择的结果
[self.selectedArr removeAllObjects];
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self];
_gestureLocation = point;
//遍历各点,检测是否落在点的周边
for (int i = 0;i< 9; i++) {
NSValue *pointValue = self.locationArr[i];
CGPoint center = [pointValue CGPointValue];
if ([self isInCirleWithCenter:center point:point] && ![self hasSelectedWithIndex:i]) {
[self.selectedArr addObject:@(i)];
if (_state == JGestureLockViewStateNone) {
_state = JGestureLockViewStateWaitingJudge;
}
}
}
[self setNeedsDisplay];
}
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//拼凑选择的答案
NSMutableString *selectResult = [NSMutableString string];
for (NSNumber *selectNum in self.selectedArr) {
[selectResult appendFormat:@"%ld",[selectNum integerValue]];
}
if ([selectResult isEqualToString:_rightSecret]) {
_state = JGestureLockViewStateRight;
}
else{
_state = JGestureLockViewStateWrong;
}
NSLog(@"selectResult:%@",selectResult);
//如果手势正确 block通知解锁成功
if (_state == JGestureLockViewStateRight && _resultBlock) {
_resultBlock();
}
if (_state == JGestureLockViewStateWrong) {
_timer = [NSTimer scheduledTimerWithTimeInterval:.5 target:self selector:@selector(timerAction:) userInfo:nil repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
}
[self setNeedsDisplay];
}
//从俯视图移除时,再次确认清除定时器
-(void)willMoveToSuperview:(UIView *)newSuperview
{
if (!newSuperview) {
[self stopTimer];
}
}
-(void)stopTimer{
if (_timer) {
[_timer invalidate];
_timer = nil;
}
}
-(void)dealloc
{
NSLog(@"dealloc");
}
-(void)timerAction:(id)sender{
[self stopTimer];
[self.selectedArr removeAllObjects];
[self setNeedsDisplay];
}
-(void)drawRect:(CGRect)rect{
for (int i = 0; i< 9; i++) {
UIImageView *imgView = self.viewArr[i];
NSString *imgName = @"";
if ([self hasSelectedWithIndex:i]) {
imgName = SelectedImgName;
}
else{
imgName = NormalImgName;
}
imgView.image = [UIImage imageNamed:imgName];
}
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineCap(context, kCGLineCapRound);
CGContextSetLineJoin(context, kCGLineJoinRound);
CGContextSetLineWidth(context, LineWith);
UIColor *lineColor = nil;
if (_state == JGestureLockViewStateWrong) {
lineColor = [UIColor colorWithPatternImage:[UIImage imageNamed:WrongLineImgName]];
}
else
{
lineColor = [UIColor colorWithPatternImage:[UIImage imageNamed:RightLineImgName]];
}
CGContextSetStrokeColorWithColor(context, lineColor.CGColor);
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
if ([self.selectedArr count] > 0) {
NSInteger beginIndex = [self.selectedArr[0] integerValue];
CGPoint point = [self.locationArr[beginIndex] CGPointValue];
[bezierPath moveToPoint:point];
for (int i = 1; i< self.selectedArr.count; i++) {
NSInteger beginIndex = [self.selectedArr[i] integerValue];
CGPoint point = [self.locationArr[beginIndex] CGPointValue];
[bezierPath addLineToPoint:point];
}
if (_state != JGestureLockViewStateRight || _state != JGestureLockViewStateWrong) {
[bezierPath addLineToPoint:_gestureLocation];
}
CGContextAddPath(context, bezierPath.CGPath);
}
CGContextStrokePath(context);
}
-(BOOL)hasSelectedWithIndex:(NSInteger)index{
for (NSNumber *num in self.selectedArr) {
if ([num integerValue] == index) {
return YES;
}
}
return NO;
}
-(BOOL)isInCirleWithCenter:(CGPoint)center point:(CGPoint)point{
CGRect rect = CGRectMake(center.x - GestureCirle, center.y - GestureCirle, GestureCirle * 2, GestureCirle * 2);
return CGRectContainsPoint(rect, point);
}
#pragma mark =================GetMethod=================
-(NSMutableArray*)viewArr
{
if (!_viewArr) {
_viewArr = [NSMutableArray array];
}
return _viewArr;
}
-(NSMutableArray*)locationArr
{
if (!_locationArr) {
_locationArr = [NSMutableArray array];
}
return _locationArr;
}
-(NSMutableArray*)selectedArr{
if (!_selectedArr) {
_selectedArr = [NSMutableArray array];
}
return _selectedArr;
}
@end
使用:
-(void)setUpUI{
__weak typeof(self) weakSelf = self;
JGestureLockView *gestureView = [[JGestureLockView alloc] init];
gestureView.backgroundColor = [UIColor blackColor];
gestureView.alpha = 0.6;
gestureView.rightSecret = @"01235";
gestureView.tag = 1;
gestureView.resultBlock = ^(){
[weakSelf gestureSecceed];
};
[self.view addSubview:gestureView];
gestureView.frame = CGRectMake(0, 64, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.width);
}
代码如上,效果如下: