手势密码。
界面:
画面主要代码:
buttonArray = [[NSMutableArray alloc]init];
for (int i = 0; i< 9; i++) {
int row = (i/3);
int col = (i%3);
int distance = (view.frame.size.width/3);
int size = ((distance)/1.5);
int margin = (size/4);
GesturePasswordButton * gesturePasswordButton = [[GesturePasswordButton alloc] initWithFrame:CGRectMake(col*distance+margin, row*distance, size, size) ];
gesturePasswordButton.tag = i;
[view addSubview:gesturePasswordButton];
[buttonArray addObject:gesturePasswordButton];
}
tentacleView = [[TentacleView alloc] initWithFrame:view.frame];
tentacleView.buttonArray = buttonArray;
tentacleView.tentacleDelegate = self;
[self.view addSubview:tentacleView];
就是画面上九个button和手势界面tentacleview。
tentacleview.m的代码:
#import "TentacleView.h"
#import "GesturePasswordButton.h"
@implementation TentacleView
@synthesize buttonArray;
@synthesize touchedArray;
@synthesize touchesArray;
@synthesize success;
@synthesize drawed;
@synthesize style;
@synthesize tentacleDelegate;
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self setBackgroundColor:[UIColor clearColor]];
touchesArray=[[NSMutableArray alloc] init];
touchedArray=[[NSMutableArray alloc] init];
success = false;
drawed = false;
style = 2;
}
return self;
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
CGPoint touchPoint;
UITouch *touch = touches.allObjects[0];
[touchesArray removeAllObjects];
[touchedArray removeAllObjects];
success = true;
drawed = false;
if(touch != nil){
touchPoint = [touch locationInView:self];
for (int i=0; i<buttonArray.count;i++) {
GesturePasswordButton * buttonTemp = buttonArray[i];
buttonTemp.success = true;
buttonTemp.selected = false;
if ([buttonTemp contains:touchPoint]) {
CGRect frameTemp = buttonTemp.frame;
CGPoint point = CGPointMake(frameTemp.origin.x+frameTemp.size.width/2,frameTemp.origin.y+frameTemp.size.height/2);
NSDictionary *model = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithFloat: point.x ],@"x",[ NSNumber numberWithFloat:point.y],@"y",nil];
[touchesArray addObject:model];
}
[buttonTemp setNeedsDisplay];
}
[self setNeedsDisplay];
}
}
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
CGPoint touchPoint;
UITouch *touch = touches.allObjects[0];
if(touch != nil){
touchPoint = [touch locationInView:self];
for (int i=0; i<buttonArray.count;i++) {
GesturePasswordButton *buttonTemp = buttonArray[i];
if ([buttonTemp contains:touchPoint]){
buttonTemp.selected = true;
id wid = nil;
for(id obj in touchedArray){
if ([[NSString stringWithFormat:@"num%d",i] isEqual:obj]) {
wid = obj;
}
}
if(wid){
lineEndPoint = touchPoint;
[self setNeedsDisplay];
return;
}
[touchedArray addObject:[NSString stringWithFormat:@"num%d",i]];
[buttonTemp setNeedsDisplay];
CGRect frameTemp = buttonTemp.frame;
CGPoint point = CGPointMake(frameTemp.origin.x+frameTemp.size.width/2, frameTemp.origin.y+frameTemp.size.height/2);
NSDictionary *model = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithFloat: point.x ],@"x",[ NSNumber numberWithFloat:point.y],@"y",[ NSNumber numberWithFloat:i],@"num",nil];
[touchesArray addObject:model];
break;
}
}
lineEndPoint = touchPoint;
[self setNeedsDisplay];
}
}
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSString * resultString = @"";
for(NSDictionary *p in touchesArray ){
if([p objectForKey:@"num"] == nil){
continue;
}
int num=[[p objectForKey:@"num"] intValue];
resultString = [resultString stringByAppendingString:[NSString stringWithFormat:@"%d",num]];
}
drawed = true;
if(style==1){
success = [self.tentacleDelegate verification:resultString];
}else{
success = [self.tentacleDelegate resetPassword:resultString];
}
for (int i=0; i<touchesArray.count;i++ ){
if([touchesArray[i] objectForKey:@"num"] == nil){
continue;
}
int selection = [[touchesArray[i] objectForKey:@"num"] intValue];
GesturePasswordButton * buttonTemp = buttonArray[selection];
buttonTemp.success = success;
[buttonTemp setNeedsDisplay];
}
[self setNeedsDisplay];
}
-(void)drawRect:(CGRect)rect{
if(touchesArray.count<=0){
return;
}
NSLog(@"drawRect==%@",touchesArray);
for (int i =0; i<touchesArray.count; i++) {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 3.0);
CGContextSetLineCap(context, kCGLineCapSquare);
if([touchesArray[i] objectForKey:@"num"] == nil){
[touchesArray removeObjectAtIndex:i];
//i = i-1;
continue;
}
if (success) {
NSLog(@"drawRect==success1");
CGContextSetRGBStrokeColor(context, 0.0, 0.0, 1.0, 0.3);
//CGContextSetStrokeColorWithColor(context, color);
}
else {
NSLog(@"drawRect==success0");
CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 0.3);
}
CGContextAddRect(context, rect);
//CGContextBeginPath(context);
//连接线裁剪,注释掉,连接线连结圆心。
for (GesturePasswordButton *btn in buttonArray) {
CGContextAddEllipseInRect(context, btn.frame);
}
CGContextEOClip(context);
CGContextMoveToPoint(context,[[touchesArray[i] objectForKey:@"x"] floatValue],[[touchesArray[i] objectForKey:@"y"] floatValue]);
if(i<touchesArray.count-1){
NSLog(@"drawRect==i<touchesArray.count-1");
CGContextAddLineToPoint(context, [[touchesArray[i+1] objectForKey:@"x"] floatValue], [[touchesArray[i+1] objectForKey:@"y"] floatValue]);
}
else{
if(success && drawed != true){
NSLog(@"drawRect==success && drawed != true");
CGContextAddLineToPoint(context,lineEndPoint.x,lineEndPoint.y);
}
}
CGContextStrokePath(context);
}
}
-(void)enterArgin{
[touchesArray removeAllObjects];
[touchedArray removeAllObjects];
for( int i=0; i<buttonArray.count;i++ ){
GesturePasswordButton * buttonTemp = buttonArray[i];
buttonTemp.success = true;
buttonTemp.selected = false;
[buttonTemp setNeedsDisplay];
}
[self setNeedsDisplay];
}
@end
九个button不是xcode中标准控件,看代码:
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import "GesturePasswordButton.h"
#define PI 3.14159265358979323846
@implementation GesturePasswordButton
@synthesize selected;
@synthesize success;
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
selected = false;
success = true;
[self setBackgroundColor:[UIColor clearColor]];
}
return self;
}
- (void)drawRect:(CGRect)rect{
CGContextRef context= UIGraphicsGetCurrentContext();
if(selected){
if(success){
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = {0.0,0.0,1.0,0.5};//颜色元素
CGColorRef color = CGColorCreate(colorspace, components);//这两行创建颜色
CGContextSetStrokeColorWithColor(context, color);
CGContextSetFillColorWithColor(context, color);
}else{
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = {1.0,0.0,0.0,0.5};//颜色元素
CGColorRef color = CGColorCreate(colorspace, components);//这两行创建颜色
CGContextSetStrokeColorWithColor(context, color);
CGContextSetFillColorWithColor(context, color);
}
CGRect rectangle = CGRectMake(self.bounds.size.width/2-self.bounds.size.width/8+1, self.bounds.size.height/2-self.bounds.size.height/8, self.bounds.size.width/4, self.bounds.size.height/4);
//CGContextAddEllipse(in: frame);
CGContextAddEllipseInRect(context, rectangle);
CGContextFillPath(context);
}else{
//线条颜色
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = {1.0,1.0,1.0,1.0};//颜色元素
CGColorRef color = CGColorCreate(colorspace, components);//这两行创建颜色
CGContextSetStrokeColorWithColor(context, color);
}
CGContextSetLineWidth(context, 2.0);
CGRect frame = CGRectMake(2,2,self.bounds.size.width-3,self.bounds.size.height-3);
CGContextAddEllipseInRect(context, frame);
CGContextStrokePath(context);
/*>>>>>>>>
if(success){
//context.setFillColor(red: 30/225, green: 175/255, blue: 235/255, alpha: 0.3)
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
//CGFloat components[] = {30/225,175/255,235/255,1.0};//颜色元素
CGFloat components[] = {0.0,0.0,1.0,0.5};//颜色元素
CGColorRef color = CGColorCreate(colorspace, components);//这两行创建颜色
CGContextSetFillColorWithColor(context, color);
}else{
CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
//CGFloat components[] = {208/225,36/255,36/255,1.0};//颜色元素
CGFloat components[] = {1.0,0.0,0.0,0.5};//颜色元素
CGColorRef color = CGColorCreate(colorspace, components);//这两行创建颜色
CGContextSetFillColorWithColor(context, color);
//context.setFillColor(red: 208/225, green: 36/255, blue: 36/255, alpha: 0.3)
}
//context.addEllipse(in: frame)
CGContextAddEllipseInRect(context, frame);
if(selected){
CGContextFillPath(context);
}
*///<<<<<<
}
-(BOOL)contains:(CGPoint)touchPoint{
return CGRectContainsPoint(self.frame,touchPoint);
}
@end
核心的原理就在tentacleview.m和GesturePasswordButton.m里。仔细看下就会明白。
我也是参考网友写的。大家的原理都大同小异。