iOS TextField輸入限制(限制長度、只能輸入數字,只能輸入數字字母……)


項目中各個地方都會用到textField,textField的輸入也會有各種需求,各種限制,每次用到的時候要重寫一遍這些限制,導致各種垃圾代碼,各種重復,有一天,我終於看不下去了,於是把textField的輸入限制封裝成在了一起,方便后續開發使用,代碼量也減少了很多,這里把封裝的View提供出來,有需要的可以參考一下(關於textView輸入限制設置placeholder請參考我的文章iOS textView限制輸入)。demo下載地址:https://github.com/qqcc1388/TYLimitInputDemo

TYLimitedTextField能夠快速實現以下功能(支持xib):
1. 限制輸入的字符(數字,字母,數字+字母,email等)
2. 提供一個可以監聽textField實時改變的方法,不需要自己去寫觀察者
3. 限制輸入文字的最大長度
4. 限制textField距離leftPading rightPading
5. 更方便快捷的設置leftView rightView
6. 設置placeholderColor

話不多說了 上代碼
#import <UIKit/UIKit.h>

typedef NS_ENUM(NSUInteger, TYLimitedTextFieldType) {
    
    TYLimitedTextFieldTypeNomal = 0,                //系統默認鍵盤
    TYLimitedTextFieldTypeNumber,                   //數字
    TYLimitedTextFieldTypeNumberOrLetter,       //數字和字母
    TYLimitedTextFieldTypeEmail,                      //數字 字母 和 特定字符( '.'  '@')
};


@class TYLimitedTextField;

@protocol TYLimitedTextFieldDelegate <NSObject>

//為了防止 self.delegate = self 然后外部有重寫了這個delegate方法導致代理失效的問題,這里重寫一遍系統的代理方法
//在使用TYLimitedTextField的使用請不要使用UITextField本身代理方法
@optional     //   ----這里只是拓展了textField的部分代理,如果有需要還可以自己實現在這里添加

/**
 鍵盤return鍵點擊調用
 
 @param textField TYLimitedTextField
 */
-(BOOL)limitedTextFieldShouldReturn:(UITextField *)textField;

/**
 輸入結束調用
 
 @param textField TYLimitedTextField
 */
-(void)limitedTextFieldDidEndEditing:(UITextField *)textField;

/**
 輸入內容改變調用(實時變化)

 @param textField TYLimitedTextField
 */
-(void)limitedTextFieldDidChange:(UITextField *)textField;

@end


@interface TYLimitedTextField : UITextField

/**
 代理方法 盡量使用這個代理而不是用textfield的代理
 */
@property (nonatomic,weak) id<TYLimitedTextFieldDelegate> realDelegate;

/**
 TYLimitedTextFieldType 根據type值不同 給出不同limited 默認TYLimitedTextFieldTypeNomal
 */
@property (nonatomic,assign) TYLimitedTextFieldType limitedType;

/**
 textField允許輸入的最大長度 默認 0不限制
 */
@property (nonatomic,assign) NSInteger maxLength;

/**
 距離左邊的間距  默認0
 */
@property (nonatomic,assign) CGFloat leftPadding;

/**
 距離右邊的間距 默認 0
 */
@property (nonatomic,assign) CGFloat rightPadding;

/**
 給placeHolder設置顏色
 */
@property (nonatomic,strong) UIColor *placeholderColor;

/**
 textField -> leftView
 */
@property (nonatomic,strong) UIView *customLeftView;

/**
 textField -> rightView
 */
@property (nonatomic,strong) UIView *customRightView;

@end


#import "TYLimitedTextField.h"

//字母+數字
#define kLetterNum  @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
#define kEmail      @"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.@"

@interface TYLimitedTextField () <UITextFieldDelegate>

//篩選條件
@property (nonatomic,copy) NSString *filter;

@end

@implementation TYLimitedTextField


-(instancetype)initWithFrame:(CGRect)frame{
    
    if (self = [super initWithFrame:frame]) {
        
        [self initialize];
    }
    return self;
}

-(instancetype)initWithCoder:(NSCoder *)aDecoder{
    
    if (self = [super initWithCoder:aDecoder]) {
        
        [self initialize];
    }
    return self;
}

-(void)initialize{
    
    //設置默認值
    self.rightPadding = 5;
    self.leftPadding = 5;
    self.limitedType = TYLimitedTextFieldTypeNomal;
    
    //設置邊框和顏色
    self.layer.cornerRadius = 5;
    self.backgroundColor = [UIColor whiteColor];
    self.textColor = [UIColor colorWithRed:51/255.0 green:51/255.0 blue:51/255.0 alpha:1.0];
    self.font = [UIFont systemFontOfSize:14];
    
    //設置代理 這里delegate = self 外面就不可以在使用textField的delegate 否則這個代理將會失效
    self.delegate = self;
    [self addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
    
}

#pragma mark - textFieldDelegate

-(BOOL)textFieldShouldReturn:(UITextField *)textField{
    if (_realDelegate && [_realDelegate respondsToSelector:@selector(limitedTextFieldShouldReturn:)]) {
        return [_realDelegate limitedTextFieldShouldReturn:textField];
    }
    return YES;
}

-(void)textFieldDidEndEditing:(UITextField *)textField{
    if (_realDelegate && [_realDelegate respondsToSelector:@selector(limitedTextFieldDidEndEditing:)]) {
        [_realDelegate limitedTextFieldDidEndEditing:textField];
    }
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
    
    //超過最大長度 並且不是取消鍵被點擊了
    if ((textField.text.length >= self.maxLength) && self.maxLength && ![string isEqualToString:@""]) {  return NO;}
    
    if (!self.filter) {  return YES;}

    //限制條件
    NSCharacterSet *cs = [[NSCharacterSet characterSetWithCharactersInString:self.filter] invertedSet];
    NSString *filtered = [[string componentsSeparatedByCharactersInSet:cs] componentsJoinedByString:@""]; //按cs分離出數組,數組按@""分離出字符串
    
    return  [string isEqualToString:filtered];
}

//textField內容有變化會調用這個方法
-(void)textFieldDidChange:(UITextField *)textField{
    if (_realDelegate && [_realDelegate respondsToSelector:@selector(limitedTextFieldDidChange:)]) {
        [_realDelegate limitedTextFieldDidChange:textField];
    }
}


#pragma mark - setter getter

-(void)setLimitedType:(TYLimitedTextFieldType)limitedType{
    _limitedType = limitedType;
    
    //根據Type選擇鍵盤
    if (limitedType == TYLimitedTextFieldTypeNomal) {
        self.keyboardType = UIKeyboardTypeDefault;
        self.filter = nil;
    }else{  //限制輸入這里使用自定義鍵盤
        self.keyboardType = UIKeyboardTypeASCIICapable;
        if (limitedType == TYLimitedTextFieldTypeNumber) {  //數字
            self.keyboardType = UIKeyboardTypeNumberPad;
            self.filter = nil;
        }else if(limitedType == TYLimitedTextFieldTypeNumberOrLetter){  //數字和字母
            self.filter = kLetterNum;
        }else if(limitedType == TYLimitedTextFieldTypeEmail){  //email
            self.filter = kEmail;
        }
    }
}

-(void)setLeftPadding:(CGFloat)leftPadding{
    _leftPadding = leftPadding;
    [self setValue:@(leftPadding) forKey:@"paddingLeft"];
}

-(void)setRightPadding:(CGFloat)rightPadding{
    _rightPadding = rightPadding;
    [self setValue:@(rightPadding) forKey:@"paddingRight"];
}

-(void)setPlaceholderColor:(UIColor *)placeholderColor{
    _placeholderColor = placeholderColor;
    [self setValue:_placeholderColor forKeyPath:@"_placeholderLabel.textColor"];
}

-(void)setCustomLeftView:(UIView *)customLeftView{
    _customLeftView = customLeftView;
    self.leftView = customLeftView;
    self.leftViewMode = UITextFieldViewModeAlways;
}

-(void)setCustomRightView:(UIView *)customRightView{
    _customRightView = customRightView;
    self.rightView = customRightView;
    self.rightViewMode = UITextFieldViewModeAlways;
}

@end

使用起來也非常簡單 需要僅僅只是需要設置限制

    //設置限制鍵盤類型
    self.textField.limitedType = TYLimitedTextFieldTypeEmail;
    
    //設置最大長度
    self.textField.maxLength = 11;
    
    //設置leftPading rightPading
    self.textField.leftPadding = 10;
    self.textField.rightPadding = 10;

    //設置placehoder  注意順序性 先設置文字再設置顏色
    self.textField.placeholder = @"請開始你的表演";
    self.textField.placeholderColor = [UIColor redColor];
    
    //設置leftView rightView
    UIButton *item = [UIButton buttonWithType:UIButtonTypeContactAdd];
    self.textField.customLeftView = item;

如果需要監聽簡單事件則需要實現代理realDelegate

    self.textField.realDelegate = self;

    -(BOOL)limitedTextFieldShouldReturn:(UITextField *)textField{
    NSLog(@"點擊了return");
    return YES;
    }

    -(void)limitedTextFieldDidEndEditing:(UITextField *)textField{
        NSLog(@"結束編輯 - text:%@",textField.text);
    }

    -(void)limitedTextFieldDidChange:(UITextField *)textField{
        NSLog(@"實時監聽文字改變%@",textField.text);
    }

使用TYLimitedTextField一定要注意:TYLimitedTextField已經將系統的TextField部分代理方法拓展出來了,所有如果你需要使用TYLimitedTextField回調功能,請不要使用delegate而使用realDelegate,否則會出現沖突也就是self.delegate = self 的尷尬。如果拓展出來的方法不足以你使用,自己自行拓展

轉載請標注來源http://www.cnblogs.com/qqcc1388/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM