最近的项目中需要实现类似微信和支付宝的输入密码一样的功能,自己查看了以下资料,思路大致如下:
1、让需要键盘的responder成为第一响应者
2、使用UIKeyInput协议使自定义的view具备输入的功能
3、通过CoreGraphics框架绘制出密码输入框的外框和里面的小黑点
UIKeyInput协议需要实现的3个方法
#if UIKIT_DEFINE_AS_PROPERTIES
@property(nonatomic, readonly) BOOL hasText;
#else
- (BOOL)hasText;
#endif
- (void)insertText:(NSString *)text;
- (void)deleteBackward
效果图
新建需要显示密码的view KKPassWordView
KKPassWordView.h
@class KKPassWordView;
@protocol KKPassWordViewDelegate <NSObject>
/** 监听改变 */
- (void)passWordView:(KKPassWordView *)passWordView didChange:(NSString *)password;
/** 监听输入完成 */
- (void)passWordView:(KKPassWordView *)passWordView endEditing:(NSString *)password;
/** 监听开始输入 */
- (void)passWordBeginEditing:(KKPassWordView *)passWordView;
@end
@interface KKPassWordView : UIView
- (void)setNum:(CGFloat)num pointColor:(UIColor *)pointColor pointSize:(CGFloat)pointSize delegate:(id<KKPassWordViewDelegate>)delgate;
@property (nonatomic, weak) id<KKPassWordViewDelegate> delegate;
@end
需要创建的属性
@interface KKPassWordView()<UIKeyInput>
/** 用于存储文本 */
@property (copy, nonatomic) NSMutableString *text;
/** 文本长度 */
@property (assign, nonatomic) NSInteger num;
/** 方框大小 */
@property (assign, nonatomic) CGFloat squareWidth;
/** 远点颜色 */
@property (strong, nonatomic) UIColor *pointColor;
@property (assign, nonatomic) CGFloat pointSize;
@end
让KKPassWordView成为第一响应者,并设置键盘类型
/** 成为第一响应者 */
- (BOOL)canBecomeFirstResponder {
return YES;
}
/** 键盘类型 */
- (UIKeyboardType)keyboardType {
return UIKeyboardTypeNumberPad;
}
UIKeyInput 需要实现的协议,每次调用[self setNeedsDisplay]会自动调用drawRect()方法,通过drawRect方法绘制小黑点,边框等。
/** 用于显示的文本对象是否有任何文本 */
- (BOOL)hasText {
return self.text.length > 0;
}
/** 插入文本 */
- (void)insertText:(NSString *)text {
if (self.text.length <= _num) {
//判断是不是数字
NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:MONEYNUMBERS] invertedSet];
NSString *filtered = [[text componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""];
BOOL basicTest = [text isEqualToString:filtered];
if (basicTest) {
[self.text appendString:text];
if (_delegate && [_delegate respondsToSelector:@selector(passWordView:didChange:)]) {
[_delegate passWordView:self didChange:self.text];
}
if (self.text.length == self.num) {
if ([self.delegate respondsToSelector:@selector(passWordView:endEditing:)]) {
[_delegate passWordView:self endEditing:self.text];
}
}
[self setNeedsDisplay];
}
}
}
/** 删除字符串 */
- (void)deleteBackward{
if (self.text.length > 0) {
[self.text deleteCharactersInRange:NSMakeRange(self.text.length - 1, 1)];
if (_delegate && [_delegate respondsToSelector:@selector(passWordView:didChange:)]) {
[_delegate passWordView:self didChange:self.text];
}
}
[self setNeedsDisplay];
}
drawRect
/** 绘制 */
- (void)drawRect:(CGRect)rect {
CGFloat height = rect.size.height;
CGFloat width = rect.size.width;
CGFloat x = (width - self.squareWidth*self.num)/2.0;
CGFloat y = (height - self.squareWidth)/2.0;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextAddRect(context, CGRectMake( x, y, self.squareWidth*self.num, self.squareWidth));
CGContextSetLineWidth(context, 1);
CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor);
CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
//画竖条
for (int i = 1; i <= self.num; 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.text.length; i++) {
CGContextAddArc(context, x+i*self.squareWidth - self.squareWidth/2.0, y+self.squareWidth/2, self.pointSize, 0, M_PI*2, YES);
CGContextDrawPath(context, kCGPathFill);
}
}
初始化
- (void)setNum:(CGFloat)num pointColor:(UIColor *)pointColor pointSize:(CGFloat)pointSize delegate:(id<KKPassWordViewDelegate>)delgate {
self.num = num;
self.pointColor = [UIColor blackColor];
self.pointSize = pointSize;
self.delegate = delgate;
self.squareWidth = CGRectGetWidth(self.frame)*1.0 / num;
[self setNeedsDisplay];
}
- (NSMutableString *)text {
if (_text == nil) {
_text = [NSMutableString string];
}
return _text;
}