| 1、有图有真相 
 
   
 2、设计思路
 2.1、以屏幕宽度为边长创建一个正方形View;
 2.2、一个for循环创建9个按钮并自动布局;
 2.3、监听该view的触摸事件,触摸区域落在某按钮区域则按钮发光
 2.4、记录发光的按钮,输出按钮顺序(可以在for循环创建按钮时给按钮做tag标记,这样就有对应关系了,从而把按钮转换成字符串密码)
 
 3、代码示例
 SAScreenLockView.h
 
 SAScreenLockView.m[Objective-C] 纯文本查看 复制代码 //
//  SAScreenLockView.h
//  SAScreenLock
//
//  Created by 余西安 on 14/12/27.
//  Copyright (c) 2014年 Sian. All rights reserved.
//
#import <UIKit/UIKit.h>
/***************代理协议***************/
@class SAScreenLockView;
@protocol SAScreenLockViewDelegate <NSObject>
- (void)screenLock:(SAScreenLockView *)screenLockView didFinishPaht:(NSNumber *)path;
@end
/***************圆圈控件***************/
@interface SACircle : UIButton
@end
/***************解锁视图***************/
@interface SAScreenLockView : UIView
@property (nonatomic, weak) id<SAScreenLockViewDelegate> delegate;
- (id)initWithDelegate:(id<SAScreenLockViewDelegate>)delegate;
@end
 [Objective-C] 纯文本查看 复制代码 //
//  SAScreenLockView.m
//  SAScreenLock
//
//  Created by 余西安 on 14/12/27.
//  Copyright (c) 2014年 Sian. All rights reserved.
//
#import "SAScreenLockView.h"
/*********************圆圈控件*********************/
@implementation SACircle
- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder]) {
        [self setup];
    }
    return self;
}
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
    }
    return self;
}
- (void)setup
{
    self.userInteractionEnabled = NO;
    UIImage *normal = [UIImage imageNamed:@"gesture_node_normal.png"];
    UIImage *selected = [UIImage imageNamed:@"gesture_node_highlighted"];
    [self setImage:normal forState:UIControlStateNormal];
    [self setImage:selected forState:UIControlStateSelected];
}
@end
/*********************解锁视图*********************/
@interface SAScreenLockView ()
@property (nonatomic, strong) NSMutableArray *circles;
@property (nonatomic, assign) CGPoint        position;
@end
@implementation SAScreenLockView
#pragma mark - 初始化方法
- (id)initWithDelegate:(id<SAScreenLockViewDelegate>)delegate
{
    if (self = [super init]) {
        self.delegate = delegate;
    }
    return self;
}
// xib创建时调用
- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder]) {
        [self setup];
    }
    return self;
}
// 代码创建时调用
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
    }
    return self;
}
// 初始化9个子控件
- (void)setup
{
    self.backgroundColor = [UIColor clearColor];
    CGFloat width = [[UIScreen mainScreen] bounds].size.width;
    self.frame = (CGRect){CGPointZero, width, width};
    for (int i = 0; i < 9; i++) {
        SACircle *circle = [SACircle buttonWithType:UIButtonTypeCustom];
        circle.tag = i + 1;
        [self addSubview:circle];
    }
}
// 被选中的子控件
- (NSMutableArray *)circles
{
    if (_circles == nil){
        _circles = [NSMutableArray array];
    }
    return _circles;
}
// 子控件位置调整
- (void)layoutSubviews
{
    NSInteger columns = 3;
    CGFloat width = self.frame.size.width;
    CGFloat dimeter = 64.0f;
    CGFloat margic = (width - dimeter * columns) / (columns + 1);
    for (SACircle *circle in self.subviews) {
        CGFloat x = (circle.tag - 1) % columns * (dimeter + margic) + margic;
        CGFloat y = (circle.tag - 1) / columns * (dimeter + margic);
        CGFloat w = dimeter;
        CGFloat h = dimeter;
        circle.frame = (CGRect){x, y, w, h};
    }
    CGRect rect = self.frame;
    rect.size.height = dimeter * 3 + margic * 2;
    self.frame = rect;
}
#pragma mark - 触摸交互事件处理
- (CGPoint)pointWithTouch:(NSSet *)touches
{
    UITouch *touch = [touches anyObject];
    return [touch locationInView:self];
}
- (SACircle *)circleWithTouches:(NSSet *)touches
{
    CGPoint pos = [self pointWithTouch:touches];
    // 判断当前触摸位置是否进入9个圆圈内
    for (SACircle *circle in self.subviews) {
        CGRect touchArea = circle.frame;
        CGFloat w = touchArea.size.width;
        touchArea.origin.x += w / 4;
        touchArea.origin.y += w / 4;
        touchArea.size.width -= w / 2;
        touchArea.size.height -= w / 2;
        if (CGRectContainsPoint(touchArea, pos)){
            return circle;
        }
    }
    return nil;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.position = CGPointZero;
    SACircle *circle = [self circleWithTouches:touches];
    // 如果进入圆圈内并且当前圆圈未被选中则加入到选中数组
    if (circle && !circle.selected){
        circle.selected = YES;
        [self.circles addObject:circle];
    }
    [self setNeedsDisplay];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    self.position = [self pointWithTouch:touches];
    SACircle *circle = [self circleWithTouches:touches];
    // 如果进入圆圈内并且当前圆圈未被选中则加入到选中数组
    if (circle && !circle.selected){
        circle.selected = YES;
        [self.circles addObject:circle];
    }
    [self setNeedsDisplay];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSMutableString *path = [NSMutableString string];
    for (SACircle *circle in self.circles) {
        circle.selected = NO;
        [path appendFormat:@"%d", (int)circle.tag];
    }
    // 当选中的圆圈不为空,并且代理有实现代理方法时通知代理
    if ([self.delegate respondsToSelector:@selector(screenLock:didFinishPaht:)] && self.circles.count)
        [self.delegate screenLock:self didFinishPaht:@([path longLongValue])];
    
    [self.circles removeAllObjects];
    [self setNeedsDisplay];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self touchesEnded:touches withEvent:event];
}
#pragma mark - 视图绘制方法
- (void)drawRect:(CGRect)rect
{
    if (self.circles.count == 0) return;
    UIBezierPath *path = [UIBezierPath bezierPath];
    path.lineWidth = 8;
    path.lineCapStyle = kCGLineCapRound;
    path.lineJoinStyle = kCGLineJoinRound;
    for (int i = 0; i < self.circles.count; i++) {
        SACircle *circle = self.circles[i];
        if (i == 0) {
            [path moveToPoint:circle.center];
        } else {
            [path addLineToPoint:circle.center];
        }
    }
    if (!CGPointEqualToPoint(self.position, CGPointZero))
        [path addLineToPoint:self.position];
    [[UIColor colorWithRed:122/255.0 green:214/255.0 blue:250/255.0 alpha:0.7] set];
    [path stroke];
}
@end
4、Demo下载:
 
 |