您的位置:首页 > 移动开发 > IOS开发

ios手势解锁

2015-03-01 11:57 239 查看
手势的解锁效果如下:





编写环境: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格式的但是是静态的动不了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: