如何更好地限制一个UITextField的输入长度

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何更好地限制一个UITextField的输入长度相关的知识,希望对你有一定的参考价值。

要限制一个UITextField的输入字数(参考链接),首先想到的应该是通过UITextFieldDelegate

的代理方法来限制:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; // return NO to not change text

比如要设置字数限制为20:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

if (textField == self.titleField)
if (textField.length > 20) return NO;


return YES;


但是这样的限制简单粗暴,可能会影响用户正常逻辑下的输入,比如输入了20个字符后,要退格回删字符。
这时候我们可能会考虑“Detect backspace in UITextField”,比如简单地判断replacementString的长度是否为0。
接着我们可能还会遇到用户已经输入20个字符了,这时候继续输入---不过是选择了部分文本进行替换-----无法进行了,这也妨碍了用户的正常操作,所以限制的代码版本可能会演进为:
#pragma mark - UITextFieldDelegate

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

if (textField == self.titleField)
if (string.length == 0) return YES;

NSInteger existedLength = textField.text.length;
NSInteger selectedLength = range.length;
NSInteger replaceLength = string.length;
if (existedLength - selectedLength + replaceLength > 20)
return NO;



return YES;


到这里可能会觉得基本大功告成了,但是当你输入19个字符后,第20个字符以中文汉字的形式继续输入,那么系统会在键盘上方提供后续的一系列联想词,你会发现通过这种方式可以连续选字输入从而突破20个字符的限制。WTF
到了这里,我们可能会希望有个类似
- (void)textFieldDidChange:(UITextField *)textField

的回调方法,但可惜没有。
当然,我们还可以通过
- (void)textFieldDidEndEditing:(UITextField *)textField;

回调方法在结束编辑的时候把文本截断,虽然在用户体验上会有点突兀。
不过当我们点进去UITextField.h头文件里寻觅上述回调方法而不得时,可能会发现最下面有这么个消息通知名称:
UIKIT_EXTERN NSString *const UITextFieldTextDidChangeNotification;

不过,监听消息还要记得解除监听,通常我还习惯把监听消息的代码统一放在一个方法中,看起来有点“大动干戈”。
所幸的是UITextField本身提供了相应的事件监听:
[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

这样就可以更好地限制输入长度:
- (void)textFieldDidChange:(UITextField *)textField

if (textField == self.titleField)
if (textField.text.length > 20)
textField.text = [textField.text substringToIndex:20];


参考技术A 要限制一个UITextField的输入字数(参考链接),首先想到的应该是通过
UITextFieldDelegate

的代理方法来限制:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; // return NO to not change text

比如要设置字数限制为20:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

if (textField == self.titleField)
if (textField.length > 20) return NO;


return YES;


但是这样的限制简单粗暴,可能会影响用户正常逻辑下的输入,比如输入了20个字符后,要退格回删字符。
这时候我们可能会考虑“Detect backspace in UITextField”,比如简单地判断replacementString的长度是否为0。
接着我们可能还会遇到用户已经输入20个字符了,这时候继续输入---不过是选择了部分文本进行替换-----无法进行了,这也妨碍了用户的正常操作,所以限制的代码版本可能会演进为:
#pragma mark - UITextFieldDelegate

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

if (textField == self.titleField)
if (string.length == 0) return YES;

NSInteger existedLength = textField.text.length;
NSInteger selectedLength = range.length;
NSInteger replaceLength = string.length;
if (existedLength - selectedLength + replaceLength > 20)
return NO;



return YES;


到这里可能会觉得基本大功告成了,但是当你输入19个字符后,第20个字符以中文汉字的形式继续输入,那么系统会在键盘上方提供后续的一系列联想词,你会发现通过这种方式可以连续选字输入从而突破20个字符的限制。WTF
到了这里,我们可能会希望有个类似
- (void)textFieldDidChange:(UITextField *)textField

的回调方法,但可惜没有。
当然,我们还可以通过
- (void)textFieldDidEndEditing:(UITextField *)textField;

回调方法在结束编辑的时候把文本截断,虽然在用户体验上会有点突兀。
不过当我们点进去UITextField.h头文件里寻觅上述回调方法而不得时,可能会发现最下面有这么个消息通知名称:
UIKIT_EXTERN NSString *const UITextFieldTextDidChangeNotification;

不过,监听消息还要记得解除监听,通常我还习惯把监听消息的代码统一放在一个方法中,看起来有点“大动干戈”。
所幸的是UITextField本身提供了相应的事件监听:
[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];

这样就可以更好地限制输入长度:
- (void)textFieldDidChange:(UITextField *)textField

if (textField == self.titleField)
if (textField.text.length > 20)
textField.text = [textField.text substringToIndex:20];


本回答被提问者和网友采纳
参考技术B 要限制一个UITextField的输入字数(参考链接),首先想到的应该是通过

UITextFieldDelegate
的代理方法来限制:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; // return NO to not change text
比如要设置字数限制为20:

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

if (textField == self.titleField)
if (textField.length > 20) return NO;


return YES;

但是这样的限制简单粗暴,可能会影响用户正常逻辑下的输入,比如输入了20个字符后,要退格回删字符。
这时候我们可能会考虑“Detect backspace in UITextField”,比如简单地判断replacementString的长度是否为0。
接着我们可能还会遇到用户已经输入20个字符了,这时候继续输入---不过是选择了部分文本进行替换-----无法进行了,这也妨碍了用户的正常操作,所以限制的代码版本可能会演进为:
参考技术C 如果要限制UITextField输入长度最长不超过kMaxLength,那么需要实现做以下操作:

1、实现UITextFieldDelegate协议;

2、实现textField:shouldChangeCharactersInRange:replacementString:方法;

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



NSInteger strLength = textField.text.length - range.length + string.length;

return (strLength <= kMaxLength);



方法- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

功能:

  把textField中位置为range的字符串替换为string字符串;

  此函数在textField内容被修改时调用;

返回值:

  YES,表示修改生效;NO,表示不做修改,textField的内容不变。

参数说明:

  textField:响应UITextFieldDelegate协议的UITextField控件。

  range: UITextField控件中光标选中的字符串,即被替换的字符串;

       range.length为0时,表示在位置range.location插入string。

  string: 替换字符串;

       string.length为0时,表示删除。
参考技术D   如何更好地限制一个UITextField的输入长度 :
  通常写法是:
  #pragma mark - UITextFieldDelegate
  - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
  
  if (textField == self.titleField)
  if (string.length == 0) return YES;
  NSInteger existedLength = textField.text.length;
  NSInteger selectedLength = range.length;
  NSInteger replaceLength = string.length;
  if (existedLength - selectedLength + replaceLength > 20)
  return NO;
  
  
  return YES;
  
  但是当用户输入19个字符后,第20个字符以中文汉字的形式继续输入,所以要添加相应的事件监听:
  [textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
  这样就可以更好地限制输入长度:
  - (void)textFieldDidChange:(UITextField *)textField
  
  if (textField == self.titleField)
  if (textField.text.length > 20)
  textField.text = [textField.text substringToIndex:20];
  
  
  

如何将 uitextfield 字符范围限制为 10 位

【中文标题】如何将 uitextfield 字符范围限制为 10 位【英文标题】:how to limit uitextfield character range upto 10 digit 【发布时间】:2015-04-21 05:03:48 【问题描述】:

我只想知道如何限制 uitextfield 范围,即我有一个文本框,我在其中输入 10 位数的值。如果我尝试输入超过 10 位数字,我的文本字段不应接受这些值。非常简单,我只想在文本字段中输入 10 位数字。

我编写了这段代码,但它对我不起作用:

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

NSUInteger oldLength = [textField.text length];
NSUInteger replacementLength = [string length];
NSUInteger rangeLength = range.length;

NSUInteger newLength = oldLength - rangeLength + replacementLength;

BOOL returnKey = [string rangeOfString: @"\n"].location != NSNotFound;

return newLength <= MAXLENGTH || returnKey;
  

【问题讨论】:

Set the maximum character length of a UITextField 的可能重复项 [This][1] 是我找到的最佳解决方案。 ***.com/questions/433337/…[1]:***.com/questions/433337/… 【参考方案1】:

要限制文本输入的长度,请实现 UITextFieldDelegate 这个方法并在更改后检查文本的长度:

- (BOOL)            textField:(UITextField *)textField
shouldChangeCharactersInRange:(NSRange)range
            replacementString:(NSString *)string 
    NSString *resultText = [textField.text stringByReplacingCharactersInRange:range
                                                                   withString:string];
    return resultText.length <= 10;

【讨论】:

【参考方案2】:

在 Swift 3.0 中

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool 

    let charsLimit = 10

    let startingLength = textField.text?.characters.count ?? 0
    let lengthToAdd = string.characters.count
    let lengthToReplace =  range.length
    let newLength = startingLength + lengthToAdd - lengthToReplace

    return newLength <= charsLimit

【讨论】:

【参考方案3】:

试试下面限制为 10 个数字文本的代码。

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

        NSInteger length = [textField.text length];
        if (length>9 && ![string isEqualToString:@""]) 
            return NO;
        

        // This code will provide protection if user copy and paste more then 10 digit text

       dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
           if ([textField.text length]>10) 
                textField.text = [textField.text substringToIndex:10];

            
       );


        return YES;
    

希望对您有所帮助。

【讨论】:

检查这个的原因是什么:![string isEqualToString:@""] ? 退格点击后将允许编辑。表示添加 10 位数字后,允许编辑该数字 允许用户粘贴一个大字符串然后裁剪它是很聪明的。可能有用。感谢您的方法。【参考方案4】:

Swift 3 版本

func textField(_ textField: UITextField, shouldChangeCharactersIn range:NSRange, replacementString string: String) -> Bool
    
        let currentCharacterCount = textField.text?.characters.count ?? 0
        if (range.length + range.location > currentCharacterCount)
            return false
        
        let newLength = currentCharacterCount + string.characters.count - range.length
        return newLength <= 10
    

【讨论】:

【参考方案5】:

试试这个。

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
if(range.length + range.location > textField.text.length)

    return NO;


NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > 10) ? NO : YES;

【讨论】:

【参考方案6】:

你可以用这个……希望对你有帮助/

   -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    
       int lenght1 = code.text.length - range.length + string.length;
    if (textField.text.length >= 4 && range.length == 0)
          return NO;

【讨论】:

【参考方案7】:

我构建了一个非常好的UITextField 子类来限制输入到字段中的字符数。给你!:

public class NumberFormattedTextField : UITextField 
    @IBInspectable public var maximumCharacters = 10 
         didSet 
             format()
        
    

    public override func awakeFromNib() 
         format()
         addTarget(self, action: "format", forControlEvents: .EditingChanged)
    

    func format() 
         let len = text.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
         // truncate for max characters if needed
         if len > maximumCharacters 
             text = text[1...maximumCharacters] // pulls in the last entered character and drops the first one off to preserve length
         
    

这取决于String 的下标。这也是:

public extension String 
    public subscript (r: Range<Int>) -> String? 
        let l = self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)
        if r.startIndex <= l && r.endIndex <= l 
            return substringWithRange(Range(start: advance(startIndex, r.startIndex), end: advance(startIndex, r.endIndex)))
         else 
            return nil
        
    

【讨论】:

【参考方案8】:

我已经根据Oxcug 给出的答案构建了一个子类,无需在字符串文件中创建扩展名,并且可以从情节提要和 swift 文件中设置最大字符长度。:

@IBDesignable class CustomTextField: UITextField 
    @IBInspectable var maximumCharacters: Int = 80 
        didSet 
            limitCharacters()
        
    
    override func awakeFromNib() 
        super.awakeFromNib()
        limitCharacters()
        addTarget(self, action: #selector(CustomTextField.limitCharacters), for: .editingChanged)
    

    func limitCharacters() 
        guard text != nil else 
            return
        
        if (text?.characters.count)! > maximumCharacters 
            if let range = text?.index(before: (text?.endIndex)!) 
                text = text?.substring(to: range)
            
        
    

【讨论】:

【参考方案9】:

最佳解决方案:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool 
        
        return range.location < 10 //Here 10 is your character limit
    

【讨论】:

以上是关于如何更好地限制一个UITextField的输入长度的主要内容,如果未能解决你的问题,请参考以下文章

怎么限制 UITextField 输入长度

UITextField中文输入法输入时对字符长度的限制

UITextField限制输入长度

如何更好地识别 UITextField

Objective-C 限制文本输入长度

iOS输入框UITextField输入限制