iOS开发进阶 - 实现类似微信和支付宝的密码输入框(UIKeyInput协议)

目前在项目中需要实现发红包的功能,自己就写了一个密码输入框的控件,主要用到了UIKeyInput协议和CoreGraphics框架,效果类似微信支付,感觉还行就把我的思路和制作过程写下来给大家分享一下。(demo地址觉得有用的可以star一下)

wcl.gif

让你的自定义View具备输入的功能(UIKeyInput协议)

通过UIKeyInput协议可以为响应者提供简单的键盘输入的功能,让需要键盘的responder成为第一响应者就行了。UIKeyInput协议必须实现的有三个方法,分别是以下方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#pragma mark - UIKeyInput
/**
* 用于显示的文本对象是否有任何文本
*/
- (BOOL)hasText {
return self.textStore.length > 0;
}

/**
* 插入文本
*/
- (void)insertText:(NSString *)text {
if (self.textStore.length < self.passWordNum) {
//判断是否是数字
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:MONEYNUMBERS] invertedSet];
NSString*filtered = [[text componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
BOOL basicTest = [text isEqualToString:filtered];
if(basicTest) {
if ([self.delegate respondsToSelector:@selector(passWordDidChange:)]) {
[self.delegate passWordDidChange:self];
}
if (self.textStore.length == self.passWordNum) {
if ([self.delegate respondsToSelector:@selector(passWordCompleteInput:)]) {
[self.delegate passWordCompleteInput:self];
}
}
[self.textStore appendString:text];
[self setNeedsDisplay];
}
}
}

/**
* 删除文本
*/
- (void)deleteBackward {
if (self.textStore.length > 0) {
[self.textStore deleteCharactersInRange:NSMakeRange(self.textStore.length - 1, 1)];
if ([self.delegate respondsToSelector:@selector(passWordDidChange:)]) {
[self.delegate passWordDidChange:self];
}
}
[self setNeedsDisplay];
}

/**
* 是否能成为第一响应者
*/
- (BOOL)canBecomeFirstResponder {
return YES;
}

/**
* 点击成为第一相应者
*/
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
if (![self isFirstResponder]) {
[self becomeFirstResponder];
}
}

实现类似微信和支付宝的密码输入框

实现的思路是通过CoreGraphics框架绘制出密码输入框的外框和里面的小黑点,然后通过从键盘上获取到的字符串判断输入的位数,具体实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/**
* 设置正方形的边长
*/
- (void)setSquareWidth:(CGFloat)squareWidth {
_squareWidth = squareWidth;
[self setNeedsDisplay];
}

/**
* 设置键盘的类型
*/
- (UIKeyboardType)keyboardType {
return UIKeyboardTypeNumberPad;
}

/**
* 设置密码的位数
*/
- (void)setPassWordNum:(NSUInteger)passWordNum {
_passWordNum = passWordNum;
[self setNeedsDisplay];
}

/**
* 绘制
*/
- (void)drawRect:(CGRect)rect {
CGFloat height = rect.size.height;
CGFloat width = rect.size.width;
CGFloat x = (width - self.squareWidth*self.passWordNum)/2.0;
CGFloat y = (height - self.squareWidth)/2.0;
CGContextRef context = UIGraphicsGetCurrentContext();
//画外框
CGContextAddRect(context, CGRectMake( x, y, self.squareWidth*self.passWordNum, self.squareWidth));
CGContextSetLineWidth(context, 1);
CGContextSetStrokeColorWithColor(context, self.rectColor.CGColor);
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
//画竖条
for (int i = 1; i <= self.passWordNum; i++) {
CGContextMoveToPoint(context, x+i*self.squareWidth, y);
CGContextAddLineToPoint(context, x+i*self.squareWidth, y+self.squareWidth);
CGContextClosePath(context);
}
CGContextDrawPath(context, kCGPathFillStroke);
CGContextSetFillColorWithColor(context, self.pointColor.CGColor);
//画黑点
for (int i = 1; i <= self.textStore.length; i++) {
CGContextAddArc(context, x+i*self.squareWidth - self.squareWidth/2.0, y+self.squareWidth/2, self.pointRadius, 0, M_PI*2, YES);
CGContextDrawPath(context, kCGPathFill);
}
}

以上就是实现的主要代码和分析,大家需要看demo可以点击超链接进去下载观看,谢谢大家的阅读~


作者 @W_C__L
2016 年 06月 02日

简单不先于复杂,而是在复杂之后~~