ios shouldChangeCharactersInRange text清空无效的问题

本文探讨了在验证码输入过程中遇到的一个特殊Bug,即在清空输入后,第一次输入的字符实际上是上一次输入的最后一个字符。文章详细分析了问题的原因,并提供了解决方案,即在执行清空操作的block后返回NO。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天遇到一个问题,在shouldChangeCharactersInRange执行的时候,string是拼接到textfield后的,我按照网上写了一个验证码分割效果的textfield,我写了一个block,当验证码输入错误的时候,输入的内容清空。但是当我清空clearAllInput以后,textfield.text还有上一次输入的最后一个字符。比如上次我输入123456,清空以后,我再次输入1的时候,第一个字符其实是6.
问题就在shouldChangeCharactersInRange里面,我再这里执行block,当block执行完成后,又回到shouldChangeCharactersInRange里面继续执行,这是最后一次输入的string就拼接到textfield,
解决办法就是在block后面return NO

@interface TEInputTextCode : UIView
/**背景图片*/
@property (nonatomic,copy)NSString *backgroudImageName;
/**用于获取键盘输入的内容,实际不显示*/
@property (nonatomic,strong)UITextField *textField;
/**验证码/密码的位数*/
@property (nonatomic,assign)NSInteger numberOfVertificationCode;
/**控制验证码/密码是否密文显示*/
@property (nonatomic,assign)bool secureTextEntry;
/**验证码/密码内容,可以通过该属性拿到验证码/密码输入框中验证码/密码的内容*/
@property (nonatomic,copy)NSString *vertificationCode;
/**验证码/密码输入框的背景图片*/
@property (nonatomic,strong)UIImageView *backgroundImageView;
/**实际用于显示验证码/密码的label*/
@property (nonatomic,strong)TECodeLabel *label;

@property (nonatomic,copy) void (^InputDoneHandler)(NSString *code);

-(void)becomeFirstResponder;
- (void)clearAllInput;
@end

#import "TEInputTextCode.h"

@interface TEInputTextCode () <UITextFieldDelegate>




@end

@implementation TEInputTextCode

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        // 设置透明背景色,保证vertificationCodeInputView显示的frame为backgroundImageView的frame
        self.backgroundColor = [UIColor clearColor];
        // 设置验证码/密码的位数默认为四位
        self.numberOfVertificationCode =4;
        /* 调出键盘的textField */
        self.textField = [[UITextField alloc]initWithFrame:self.bounds];
        // 隐藏textField,通过点击IDVertificationCodeInputView使其成为第一响应者,来弹出键盘
        self.textField.hidden =YES;
        self.textField.keyboardType =UIKeyboardTypeNumberPad;
        self.textField.delegate =self;
        // 将textField放到最后边
        [self insertSubview:self.textField atIndex:0];
        /* 添加用于显示验证码/密码的label */
        self.label = [[TECodeLabel alloc]initWithFrame:self.bounds];
        self.label.numberOfVertificationCode =self.numberOfVertificationCode;
        self.label.secureTextEntry =self.secureTextEntry;
        self.label.font =self.textField.font;
        [self addSubview:self.label];
    }
    return self;
}
- (void)setBackgroudImageName:(NSString *)backgroudImageName {
    _backgroudImageName = backgroudImageName;
    // 若用户设置了背景图片,则添加背景图片
    self.backgroundImageView = [[UIImageView alloc]initWithFrame:self.bounds];
    self.backgroundImageView.image = [UIImage imageNamed:self.backgroudImageName];
    // 将背景图片插入到label的后边,避免遮挡验证码/密码的显示
    [self insertSubview:self.backgroundImageView belowSubview:self.label];
}
- (void)setNumberOfVertificationCode:(NSInteger)numberOfVertificationCode {
    _numberOfVertificationCode = numberOfVertificationCode;
    // 保持label的验证码/密码位数与IDVertificationCodeInputView一致,此时label一定已经被创建
    self.label.numberOfVertificationCode =_numberOfVertificationCode;
}
- (void)setSecureTextEntry:(bool)secureTextEntry {
    _secureTextEntry = secureTextEntry;
    self.label.secureTextEntry =_secureTextEntry;
}
-(void)becomeFirstResponder{
    [self.textField becomeFirstResponder];
}
-(void)clearAllInput{
    self.textField.text = @"";
    self.label.text = @"";
    self.vertificationCode = @"";
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self.textField becomeFirstResponder];
}
//-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
//    self.textField.text = @"";
//    return YES;
//}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    
    // 判断是不是“删除”字符
    if (string.length !=0) {//不是“删除”字符
        // 判断验证码/密码的位数是否达到预定的位数
        if (textField.text.length <self.numberOfVertificationCode) {
            self.label.text = [textField.text stringByAppendingString:string];
            self.vertificationCode =self.label.text;
            if (self.label.text.length == self.numberOfVertificationCode) {
                NSLog(@"tag 已经输入完成验证码了vertificationCode= %@",_vertificationCode);
                //修改 block执行以后的 string不为空的bug
                if (self.InputDoneHandler) {
                    self.InputDoneHandler(self.label.text);
                }
                return NO;
            }
            return YES;
        } else {
            return NO;
        }
    } else {//是“删除”字符
        self.label.text = [textField.text substringToIndex:textField.text.length -1];
        self.vertificationCode =self.label.text;
        return YES;
    }
}

@end






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值