美文网首页
iOS UITextField多个号码填充删除

iOS UITextField多个号码填充删除

作者: 你的小福蝶 | 来源:发表于2019-01-26 11:32 被阅读9次
image.png

产品的需求总会让人心碎一地,十一个输入空格,除第一个固定其它每个都可以独立输入,点击其中一个聚焦,继续键盘输入自动后移,点击删除自动向前移动,点击搜索按钮执行搜索,空格处使用"_"代替😭


暂时只用了最笨的方法:多个UITextField


@property (nonatomic , strong) NSMutableArray *numMutaArr;  //自定义选号
-  (NSMutableArray *)numMutaArr{
    if (!_numMutaArr) {
        _numMutaArr = [[NSMutableArray alloc]initWithObjects:@"1",@"_",@"_",@"_",@"_",@"_",@"_",@"_",@"_",@"_",@"_", nil];
    }
    return _numMutaArr;
}
//布局代码
- (UIView *)defaultView{
    if (!_defaultView) {
        _defaultView = [UIView new]; 
        _defaultView.frame = CGRectMake(0, 40*layoutBy6(), SCREEN_WIDTH, 100*layoutBy6());
        //文字提示
        UILabel *titleLbl = [UILabel creatLabelWithString:@"请输入您心仪的号码" TextColor:hexStringToColor(@"999999") andFont:[UIFont systemFontOfSize:13*layoutBy6()]];
        titleLbl.frame = CGRectMake(20*layoutBy6(), 20*layoutBy6(), SCREEN_WIDTH-40*layoutBy6(), 20*layoutBy6());
        [_defaultView addSubview:titleLbl];
        //icon展示
        UIImageView *imgIcon = [UIImageView createImageViewWithName:@"zxxh_ss" color:nil];
        imgIcon.frame = CGRectMake(SCREEN_WIDTH - 37*layoutBy6(), 20*layoutBy6(), 17*layoutBy6(), 17*layoutBy6());
        [_defaultView addSubview:imgIcon];
        //增大触发范围
        UIButton *searchBtn = [UIButton createButtonWithbackImageName:nil selectImg:nil title:nil andTitleColor:nil andFont:nil andTarget:self andAction:@selector(defaultSearchClick)];
        searchBtn.frame = CGRectMake(SCREEN_WIDTH - 80*layoutBy6(), 20*layoutBy6(), 60*layoutBy6(), 17*layoutBy6());
        [_defaultView addSubview:searchBtn];
        
        float txtFY   = CGRectGetMaxY(titleLbl.frame)+12.5*layoutBy6();
        float firstX  = 20*layoutBy6();
        float secondX = (firstX+15+25*3+3.5*2)*layoutBy6();
        float thirdX  = secondX + (25*4+3.5*3+15)*layoutBy6();
        
        for (int i=0; i<11; i++) {
            YJTextField *textF = [YJTextField createTextFielWithFont:[UIFont systemFontOfSize:14*layoutBy6()] placeholder:@""];
            textF.backgroundColor = hexStringToColor(@"F5F5F5");
            textF.textAlignment = NSTextAlignmentCenter;
            textF.keyboardType = UIKeyboardTypeNumberPad;
            textF.textColor = hexStringToColor(@"000000");
            textF.layer.masksToBounds = true;
            textF.layer.cornerRadius =  2.5*layoutBy6();
            textF.tag =  300+i;
            textF.delegate = self;
            if (i<3) {
                if (i == 0) {  //第一位不可编辑更改
                    textF.text = @"1";
                    textF.userInteractionEnabled = false;
                }
                textF.frame = CGRectMake(firstX+i*(3.5+25)*layoutBy6(), txtFY, 25*layoutBy6(), 30*layoutBy6());
            } else if (2<i&&i<7){
                textF.frame = CGRectMake(secondX+(i-3)*(3.5+25)*layoutBy6(), txtFY, 25*layoutBy6(), 30*layoutBy6());
            } else {
                textF.frame = CGRectMake(thirdX+(i-7)*(3.5+25)*layoutBy6(), txtFY, 25*layoutBy6(), 30*layoutBy6());
            }
            [_defaultView addSubview:textF];
        }

    }
    return _defaultView;
}
#pragma mark -Delegate

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    
    //前删
    textField.text.length ? textField.returnKeyType = UIReturnKeySend :(textField.returnKeyType = UIReturnKeyDone);
    
    if ([string isEqualToString:@""""]) {
        NSLog(@"你点击了删除按钮");
        
        NSMutableArray *mutArr = [NSMutableArray arrayWithArray:self.numMutaArr];
        [mutArr replaceObjectAtIndex:textField.tag-300 withObject:@"_"];
        self.numMutaArr = mutArr;
        textField.text = @"";
        
        if (textField.tag != 301) {
            [textField resignFirstResponder];
        }
        if (textField.tag - 300>1) {
            UITextField *newTexF = (UITextField *)[self viewWithTag:textField.tag-1];
            [newTexF becomeFirstResponder];
        }
        return NO;
    }
    if ([string isEqualToString:@"\n"]) {
        NSLog(@"你点击了回车或者发送按钮");
    }
    
    // 后加 - 当文本框内容出现变化时 及时获取文本最新内容
    NSString *oldText = textField.text;
    NSString *newText = string;
    NSMutableArray *mutArr = [NSMutableArray arrayWithArray:self.numMutaArr];
    if (oldText.length>0&&newText.length>0) {
        
        textField.text = oldText;
        [mutArr replaceObjectAtIndex:textField.tag-300 withObject:oldText];
        if (textField.tag != 310) {
            [textField resignFirstResponder];
        }

        if (textField.tag-300<10&&oldText.length>0) {
            
            UITextField *newTexF = (UITextField *)[self viewWithTag:textField.tag+1];
            newTexF.text = newText;
            [mutArr replaceObjectAtIndex:textField.tag-300+1 withObject:newText];
            [newTexF becomeFirstResponder];
        }
        self.numMutaArr = mutArr;
        return NO;
    } else if (newText.length>0){
        [mutArr replaceObjectAtIndex:textField.tag-300 withObject:newText];
        self.numMutaArr = mutArr;
        textField.text = newText;
        return NO;
    } else{
        [mutArr replaceObjectAtIndex:textField.tag-300 withObject:@"_"];
        self.numMutaArr = mutArr;
    }
    return YES;
}

执行搜索

//自定义返回
- (void)defaultSearchClick{
    [self endEditing:true];
    //Array --> String
    NSString *defaultStr = [self.numMutaArr componentsJoinedByString:@""];
    if (self.defltSearBlock) {
        self.defltSearBlock(defaultStr);
    }
    NSLog(@"SearchDefault----%@",defaultStr);
}

参考

问题总结:

在空白框中点击删除无法触发代理,目前想到的办法是用RunTime直接注册监听按钮,后续更新代码。



二、更新:

通过runtime监听键盘上的删除按键,使用代理传递点击事件

.h

#import <UIKit/UIKit.h>

@protocol YJTextFieldDelegate <NSObject>

- (void)textFieldDidDeleteBackward:(UITextField *)textField;

@end

@interface UITextField (YJTextFieldBackSpace)

@property (weak, nonatomic) id<YJTextFieldDelegate> delegate;

@end

.m

#import "UITextField+YJTextFieldBackSpace.h"
#import <objc/runtime.h>

@implementation UITextField (YJTextFieldBackSpace)

+ (void)load{
    //交换2个方法中的IMP
    Method method1 = class_getInstanceMethod([self class], NSSelectorFromString(@"deleteBackward"));
    
    Method method2 = class_getInstanceMethod([self class], @selector(Wp_deleteBackward));
    
    method_exchangeImplementations(method1, method2);
    
    //! 下面这个交换主要解决大于等于8.0小于8.3系统不调用deleteBackward的问题
    
    Method method3 = class_getInstanceMethod([self class], NSSelectorFromString(@"keyboardInputShouldDelete:"));
    
    Method method4 = class_getInstanceMethod([self class], @selector(Wp_keyboardInputShouldDelete:));
    
    method_exchangeImplementations(method3, method4);
}

- (void)Wp_deleteBackward

{
    
    [self Wp_deleteBackward];
    
    if ([self.delegate respondsToSelector:@selector(textFieldDidDeleteBackward:)]){
        
        id <YJTextFieldDelegate> delegate = (id<YJTextFieldDelegate>)self.delegate;
        
        [delegate textFieldDidDeleteBackward:self];
        
    }
}


- (BOOL)Wp_keyboardInputShouldDelete:(UITextField *)textField {
    
    BOOL shouldDelete = [self Wp_keyboardInputShouldDelete:textField];
    
    BOOL isMoreThanIos8_0 = ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0f);
    
    BOOL isLessThanIos8_3 = ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.3f);
    
    if (![textField.text length] && isMoreThanIos8_0 && isLessThanIos8_3) {
        
        [self deleteBackward];
    }

    return shouldDelete;
}
@end

实现:

#import "UITextField+YJTextFieldBackSpace.h"
<YJTextFieldDelegate>

//实现代理 (shouldChangeCharactersInRange中的前删代码注意去除)
- (void)textFieldDidDeleteBackward:(UITextField *)textField{

    //前删
    NSMutableArray *mutArr = [NSMutableArray arrayWithArray:self.numMutaArr];
    [mutArr replaceObjectAtIndex:textField.tag-300 withObject:@"_"];
    self.numMutaArr = mutArr;
    textField.text = @"";
    
    if (textField.tag != 301) {
        [textField resignFirstResponder];
    }
    if (textField.tag - 300>1) {
        UITextField *newTexF = (UITextField *)[self viewWithTag:textField.tag-1];
        [newTexF becomeFirstResponder];
    }

}

参考

后续会把"后加"部分代码也使用runtime进行处理

总结:代理不够,Runtime来凑

相关文章

网友评论

      本文标题:iOS UITextField多个号码填充删除

      本文链接:https://www.haomeiwen.com/subject/gixijqtx.html