.h
@interface PasswordTextView : UIView
/**
the password is user inputed
*/
@property (nonatomic, copy) void(^passwordDidChangeBlock)(NSString *password);
/**
set element count, default is 4, remove all elements and creat new elemets when it was set
*/
@property (nonatomic, assign) NSInteger elementCount;
/**
set element color, default is balck color
*/
@property (nonatomic, strong) UIColor *elementBorderColor;
/**
set element margein, default is 4 point
*/
@property (nonatomic, assign) CGFloat elementMargin;
/**
auto hide the keyboard when input password was completed, default is YES
*/
@property (nonatomic, assign) BOOL autoHideKeyboard;
/**
set element border width, default's 1 point
*/
@property (nonatomic, assign) CGFloat elementBorderWidth;
/**
clear all password
*/
- (void)clearPassword;
- (void)showKeyboard;
- (void)hideKeyboard;
.m
@interface TPPasswordTextView ()
@property(nonatomic, weak) UITextField *textField;
@property (nonatomic, strong) NSMutableArray *dataSource;
@end
@implementation PasswordTextView
#pragma mark - lazy
- (NSMutableArray *)dataSource {
if (_dataSource == nil) {
_dataSource = [NSMutableArray array];
}
return _dataSource;
}
#pragma mark - initialization
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UITextField *textField = [[UITextField alloc] initWithFrame:self.bounds];
textField.hidden = YES;
textField.keyboardType = UIKeyboardTypeNumberPad;
[textField addTarget:self action:@selector(textChange:) forControlEvents:UIControlEventEditingChanged];
//使文本框在界面打开时就获取焦点,并弹出输入键盘
[textField becomeFirstResponder];
//使文本框失去焦点,并收回键盘
//[textField resignFirstResponder];
[self addSubview:textField];
self.textField = textField;
self.autoHideKeyboard = YES;
self.elementBorderColor = [UIColor blackColor];
self.backgroundColor = [UIColor whiteColor];
self.elementBorderWidth = 1;
}
return self;
}
- (void)setElementCount:(NSInteger)elementCount {
_elementCount = elementCount;
if (elementCount <= 0) {
return;
}
if (self.dataSource.count > 0) {
[self.dataSource enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[NSObject cancelPreviousPerformRequestsWithTarget:obj selector:@selector(removeFromSuperview) object:nil];
}];
[self.dataSource makeObjectsPerformSelector:@selector(removeFromSuperview)];
[self.dataSource removeAllObjects];
}
for (int i = 0; i < self.elementCount; i++)
{
UITextField *pwdTextField = [[UITextField alloc] init];
pwdTextField.enabled = NO;
pwdTextField.textAlignment = NSTextAlignmentCenter;//居中
pwdTextField.secureTextEntry = YES;//设置密码模式
pwdTextField.userInteractionEnabled = NO;
[self insertSubview:pwdTextField belowSubview:self.textField];
[self.dataSource addObject:pwdTextField];
}
}
- (void)setElementMargin:(CGFloat)elementMargin {
_elementMargin = elementMargin;
[self setNeedsLayout];
[self setNeedsDisplay];
}
#pragma mark - publick method
- (void)clearPassword {
self.textField.text = nil;
[self textChange:self.textField];
}
- (void)showKeyboard {
[self.textField becomeFirstResponder];
}
- (void)hideKeyboard {
[self.textField resignFirstResponder];
}
#pragma mark - 文本框内容改变
- (void)textChange:(UITextField *)textField {
NSString *password = textField.text;
if (password.length > self.elementCount) {
return;
}
for (int i = 0; i < self.dataSource.count; i++)
{
UITextField *pwdTextField= [self.dataSource objectAtIndex:i];
if (i < password.length) {
NSString *pwd = [password substringWithRange:NSMakeRange(i, 1)];
pwdTextField.text = pwd;
} else {
pwdTextField.text = nil;
}
}
if (password.length == self.dataSource.count)
{
if (self.autoHideKeyboard) {
[self hideKeyboard];//隐藏键盘
}
}
!self.passwordDidChangeBlock ? : self.passwordDidChangeBlock(textField.text);
}
- (void)layoutSubviews {
[super layoutSubviews];
CGFloat x = 0;
CGFloat y = 0;
CGFloat w = (self.bounds.size.width - (self.elementCount - 1) * self.elementMargin) / self.elementCount;
CGFloat h = self.bounds.size.height;
for (NSUInteger i = 0; i < self.dataSource.count; i++) {
UITextField *pwdTextField = [self.dataSource objectAtIndex:i];
x = i * (w + self.elementMargin);
pwdTextField.frame = CGRectMake(x, y, w, h);
}}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self showKeyboard];
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
[self.backgroundColor set];
CGContextFillRect(context, rect);
CGContextSetLineCap(context, kCGLineCapSquare);
CGContextSetLineWidth(context, self.elementBorderWidth);
CGContextSetStrokeColorWithColor(context, self.elementBorderColor.CGColor);
CGContextSetFillColorWithColor(context, [UIColor clearColor].CGColor);
CGContextBeginPath(context);
if (self.elementMargin != 0) {
for (UITextField *textField in self.dataSource) {
CGRect rect = CGRectInset(textField.frame, self.elementBorderWidth, self.elementBorderWidth);
CGFloat left = rect.origin.x;
CGFloat right = rect.origin.x + rect.size.width;
CGFloat top = rect.origin.y;
CGFloat bottom = rect.origin.y + rect.size.height;
CGContextMoveToPoint(context, left, top);
CGContextAddLineToPoint(context, right, top);
CGContextAddLineToPoint(context, right, bottom);
CGContextAddLineToPoint(context, left, bottom);
CGContextClosePath(context);
}
}else {
CGPoint leftTopPoint, rightTopPoint, leftBottomPoint, rightBottomPoint;
for (NSUInteger i = 0; i < self.dataSource.count; i++) {
UITextField *textField = [self.dataSource objectAtIndex:i];
CGRect rect = CGRectInset(textField.frame, self.elementBorderWidth, self.elementBorderWidth);
CGFloat left = rect.origin.x;
CGFloat right = rect.origin.x + rect.size.width;
CGFloat top = rect.origin.y;
CGFloat bottom = rect.origin.y + rect.size.height;
CGContextMoveToPoint(context, left, top);
CGContextAddLineToPoint(context, left, bottom);
CGContextClosePath(context);
if (self.dataSource.count - 1 == i) {
CGContextMoveToPoint(context, right, top);
CGContextAddLineToPoint(context, right, bottom);
CGContextClosePath(context);
rightTopPoint = CGPointMake(right, top);
rightBottomPoint = CGPointMake(right, bottom);
}else if (0 == i) {
leftTopPoint = CGPointMake(left, top);
leftBottomPoint = CGPointMake(left, bottom);
}
}
CGContextMoveToPoint(context, leftTopPoint.x, leftTopPoint.y);
CGContextAddLineToPoint(context, rightTopPoint.x, rightTopPoint.y);
CGContextClosePath(context);
CGContextMoveToPoint(context, leftBottomPoint.x, leftBottomPoint.y);
CGContextAddLineToPoint(context, rightBottomPoint.x, rightBottomPoint.y);
CGContextClosePath(context);
}
CGContextStrokePath(context);
}
-------------------
使用
CGPoint center = self.view.center;
TPPasswordTextView *view1 = [[TPPasswordTextView alloc] initWithFrame:CGRectMake(0, 0, 200, 44)];
view1.elementCount = 5;
view1.center = CGPointMake(center.x, 50);
[self.view addSubview:view1];
view1.passwordDidChangeBlock = ^(NSString *password) {
NSLog(@"%@",password);
};
TPPasswordTextView *view2 = [[TPPasswordTextView alloc] initWithFrame:CGRectMake(0, 0, 200, 44)];
view2.elementCount = 5;
view2.center = CGPointMake(center.x, 100);
view2.elementBorderColor = [UIColor redColor];
[self.view addSubview:view2];
view2.passwordDidChangeBlock = ^(NSString *password) {
NSLog(@"%@",password);
};
TPPasswordTextView *view3 = [[TPPasswordTextView alloc] initWithFrame:CGRectMake(0, 0, 200, 44)];
view3.elementCount = 8;
view3.center = CGPointMake(center.x, 150);
view3.elementBorderColor = [UIColor cyanColor];
view3.elementMargin = 5;
[self.view addSubview:view3];
view3.passwordDidChangeBlock = ^(NSString *password) {
NSLog(@"%@",password);
};
TPPasswordTextView *view4 = [[TPPasswordTextView alloc] initWithFrame:CGRectMake(0, 0, 288, 44)];
view4.elementCount = 6;
view4.center = CGPointMake(center.x, 200);
view4.elementBorderColor = [UIColor grayColor];
view4.elementMargin = 5;
[self.view addSubview:view4];
view3.passwordDidChangeBlock = ^(NSString *password) {
NSLog(@"%@",password);
};