iOS学习笔记iOS DeveloperiOS开发

实现跟微信、支付宝一样输入支付密码

2017-05-27  本文已影响343人  搬运工开发者

最近的项目中需要实现类似微信和支付宝的输入密码一样的功能,自己查看了以下资料,思路大致如下:
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

效果图

1.gif

新建需要显示密码的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;
}

demo:http://code.cocoachina.com/view/135154

上一篇下一篇

猜你喜欢

热点阅读