专栏首页ios 技术积累iOS UITextField 限制输入

iOS UITextField 限制输入

通常情况下如果要限制UITextField的输入长度或输入类型要么在回调方法判断

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{
}

要么在监听里面判断

[self.phoneTextField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

- (void)textFieldDidChange:(UITextField *)textField
{
}

但是如果很多页面的TextField控件需要验证这样写就很麻烦,为了不重复造轮子。写了一个Category。只实现了输入长度限制,输入数字,输入字母,如果不能满足需求可自行扩展。

#import <UIKit/UIKit.h>

typedef void(^TextLengthBlock)(NSInteger length);
typedef void(^IsTextFieldTypeBlock)(BOOL filedType);

typedef NS_ENUM(NSInteger,DTextFieldType) {
    DTextFieldStringTypeNone = 0,            // 不限制
    DTextFieldStringTypeNumber = 1,         // 数字
    DTextFieldStringTypeLetter = 2         // 字母
};

NS_ASSUME_NONNULL_BEGIN

@interface UITextField (Limit)

/**允许输入最大字符长度*/
@property (assign, nonatomic) NSInteger maxLength;
/**输入类型*/
@property (assign, nonatomic) NSInteger textFieldType;
/**输入长度回调(返回输入的字符长度)*/
@property (nonatomic , copy) TextLengthBlock lengthBlock;
/**输入限制类型的回调(判断是否是想要的输入类型,外部提示用)*/
@property (nonatomic , copy) IsTextFieldTypeBlock isTextFieldTypeBlock;


@end

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

#define kDNUMBERS     @"0123456789\n"
#define kDLETTER     @"abcdefghijklmnopqresuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

static NSString * const DMaxLengthKey = @"DMaxLengthKey";
static NSString * const DTextLengthBlockKey = @"DTextLengthKey";
static NSString * const DTextFieldTypeKey = @"DTextFieldTypeKey";
static NSString * const DIsTextFieldTypeKey = @"DIsTextFieldTypeKey";

@implementation UITextField (Limit)

- (void)setMaxLength:(NSInteger)maxLength{
    objc_setAssociatedObject(self, &DMaxLengthKey, @(maxLength), OBJC_ASSOCIATION_ASSIGN);
    
    [self addTarget:self
             action:@selector(textFieldTextChanged:)
   forControlEvents:UIControlEventEditingChanged];
}
- (NSInteger)maxLength{
    return   [objc_getAssociatedObject(self, &DMaxLengthKey) integerValue];
}

- (void)setLengthBlock:(TextLengthBlock)lengthBlock{
    objc_setAssociatedObject(self, &DTextLengthBlockKey, lengthBlock, OBJC_ASSOCIATION_COPY);
    
    [self addTarget:self
             action:@selector(textFieldTextChanged:)
   forControlEvents:UIControlEventEditingChanged];
}
- (TextLengthBlock)lengthBlock{
    return objc_getAssociatedObject(self, &DTextLengthBlockKey);
}

- (void)setTextFieldType:(NSInteger)textFieldType{
    objc_setAssociatedObject(self, &DTextFieldTypeKey,  @(textFieldType), OBJC_ASSOCIATION_ASSIGN);
}
- (NSInteger)textFieldType{
    return [objc_getAssociatedObject(self, &DTextFieldTypeKey) integerValue];
}

- (void)setIsTextFieldTypeBlock:(IsTextFieldTypeBlock)isTextFieldTypeBlock{
    objc_setAssociatedObject(self, &DIsTextFieldTypeKey, isTextFieldTypeBlock, OBJC_ASSOCIATION_COPY);
}
- (IsTextFieldTypeBlock)isTextFieldTypeBlock{
    return objc_getAssociatedObject(self, &DIsTextFieldTypeKey);
}

- (void)lengthLimitBlock:(UITextField *)textField
{
    if (self.lengthBlock) {
        self.lengthBlock(textField.text.length);
    }
}

- (void)textFieldTextChanged:(UITextField *)textField
{
   
    switch (self.textFieldType) {
        case DTextFieldStringTypeNone:
        {
            [self textFieldStringTypeNumber:textField];
        }
            break;
        case DTextFieldStringTypeNumber:
        {
            [self textFieldStringTypeNumber:textField];
        }
            break;
        case DTextFieldStringTypeLetter:
        {
            [self textFieldStringTypeLetter:textField];
        }
            break;
            
        default:
            break;
    }
    
   [self lengthLimitBlock:textField];
}


/**
 获取TextField输入范围
 @param textField textField
 @return 范围
 */
- (NSRange)getTextFieldRange:(UITextField *)textField
{
    NSInteger adaptedLength = textField.maxLength > 0? MIN(textField.text.length, textField.maxLength) : MIN(textField.text.length, MAXFLOAT);
    NSRange range = NSMakeRange(0, adaptedLength);
    
    return range;
}


/**
 输入类型验证

 @param aStr 输入字符串
 @param format 验证格式
 @return BOOL
 */
- (BOOL)inputTypeVerification:(NSString *)aStr format:(NSString *)format{
    NSCharacterSet* filterCS = [[NSCharacterSet characterSetWithCharactersInString:format] invertedSet];
    NSString *filterString = [[aStr componentsSeparatedByCharactersInSet:filterCS] componentsJoinedByString:@""];
    
    return [aStr isEqualToString:filterString];
}


/**
 无限制(可以输入任何类型)
 @param textField textField
 */
- (void)textFieldStringTypeNone:(UITextField *)textField
{
    textField.text = [textField.text substringWithRange:[self getTextFieldRange:textField]];
}

/**
 只能输入数字
 @param textField textField
 */
- (void)textFieldStringTypeNumber:(UITextField *)textField
{
    BOOL flag = [self inputTypeVerification:textField.text format:kDNUMBERS];
    if (flag){
        textField.text = [textField.text substringWithRange:[self getTextFieldRange:textField]];
        if (self.isTextFieldTypeBlock) {
            self.isTextFieldTypeBlock(YES);
        }
    }
    else{
        textField.text = @"";
        if (self.isTextFieldTypeBlock) {
            self.isTextFieldTypeBlock(NO);
        }
    }
}

/**
 只能输入字母
 @param textField textField
 */
- (void)textFieldStringTypeLetter:(UITextField *)textField
{
    BOOL flag = [self inputTypeVerification:textField.text format:kDLETTER];;
    if (flag){
        textField.text = [textField.text substringWithRange:[self getTextFieldRange:textField]];
        if (self.isTextFieldTypeBlock) {
            self.isTextFieldTypeBlock(YES);
        }
    }
    else{
        textField.text = @"";
        if (self.isTextFieldTypeBlock) {
            self.isTextFieldTypeBlock(NO);
        }
    }
}

@end

使用

self.textField1.textFieldType = DTextFieldStringTypeNumber;
    self.textField1.maxLength = 11;
    
    self.textField1.lengthBlock = ^(NSInteger length) {
        NSLog(@"长度--%zd",length);
    };
    self.textField1.isTextFieldTypeBlock = ^(BOOL filedType) {
        if (!filedType) {
            NSLog(@"请输入正确的类型");
        }
    };

Demo

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ios 圆形进度条

    有很多开源的进度条不用,非要弄这种效果,就不吐槽了,还是想想怎么实现 废话就不多说了 直接上代码

    赵哥窟
  • iOS AFNetworking 源码阅读一

    大名鼎鼎的AFNetWorking,做iOS开发的人都知道吧。 AFNetWorking一款轻量级网络请求开源框架,基于iOS和mac os 网络进行扩展的高...

    赵哥窟
  • ios 扩大UIButton点击范围

    先了解Hit-Test请看上一篇文章 https://www.jianshu.com/writer#/notebooks/4989829/notes/3314...

    赵哥窟
  • 糗事百科_多线程demo(2)

    版权声明:Copyright © ...

    zhengzongwei
  • 使用Pytorch实现Kmeans聚类

    Kmeans是一种简单易用的聚类算法,是少有的会出现在深度学习项目中的传统算法,比如人脸搜索项目、物体检测项目(yolov3中用到了Kmeans进行anchor...

    带萝卜
  • 获取 zabbix 挂件数据(widget)

    Zabbix 有非常丰富的 API ,但没有 widget 的 API。 所以获取 widget 的数据需要通过模拟登录爬取网页的形式来做。虽然我们可以用一定的...

    用户1416054
  • 转-Golang自玩项目中一个重连机制实现.

    package tcp_listentype Connection interface { Read() ( value interface...

    李海彬
  • 转-Golang自玩项目中一个重连机制实现.

    package tcp_listentype Connection interface { Read() ( value interfac...

    李海彬
  • python第三十九课——面向对象(二)之初始化属性

    hankleo
  • 实战篇 | 用Python来找你喜欢的妹子(二)

    我之前写了一个抓取妹子资料的文章,主要是使用selenium来模拟网页操作,然后使用动态加载,再用xpath来提取网页的资料,但这种方式效率不高。用Python...

    龙哥

扫码关注云+社区

领取腾讯云代金券