设置UITextField的最大字符长度

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设置UITextField的最大字符长度相关的知识,希望对你有一定的参考价值。

当我加载UITextField时,如何在iPhone SDK上设置UIView中的最大字符数?

答案

虽然UITextField类没有max length属性,但通过设置文本字段的delegate并实现以下委托方法来获得此功能相对简单:

Objective-C的

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
    // Prevent crashing undo bug – see note below.
    if(range.length + range.location > textField.text.length)
    
        return NO;
    

    NSUInteger newLength = [textField.text length] + [string length] - range.length;
    return newLength <= 25;

迅速

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

    let currentCharacterCount = textField.text?.count ?? 0
    if range.length + range.location > currentCharacterCount 
        return false
    
    let newLength = currentCharacterCount + string.count - range.length
    return newLength <= 25

在文本字段更改之前,UITextField会询问委托是否应更改指定的文本。此时文本字段没有改变,所以我们抓住它的当前长度和我们插入的字符串长度(通过粘贴复制的文本或使用键盘键入单个字符),减去范围长度。如果此值太长(在此示例中超过25个字符),请返回NO以禁止更改。

当在文本字段的末尾键入单个字符时,range.location将是当前字段的长度,range.length将为0,因为我们不替换/删除任何内容。插入文本字段的中间只是意味着不同的range.location,粘贴多个字符只意味着string中有多个字符。

删除单个字符或剪切多个字符由具有非零长度的range和空字符串指定。替换只是一个非空字符串的范围删除。

A note on the crashing "undo" bug

正如评论中提到的,UITextField存在一个可能导致崩溃的错误。

如果粘贴到字段中,但验证实现阻止了粘贴,则粘贴操作仍会记录在应用程序的撤消缓冲区中。如果然后触发撤消(通过摇动设备并确认撤消),UITextField将尝试用空字符串替换它认为粘贴的字符串。这会崩溃,因为它从未真正将字符串粘贴到自身。它将尝试替换不存在的字符串的一部分。

幸运的是,你可以保护UITextField不会像这样自杀。您只需要确保它建议替换的范围确实存在于其当前字符串中。这是上面的初步健全检查。

swift 3.0 with copy and paste working fine.

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool 
        let str = (textView.text + text)
        if str.characters.count <= 10 
            return true
        
        textView.text = str.substring(to: str.index(str.startIndex, offsetBy: 10))
        return false
    

希望它对你有所帮助。

另一答案

我模拟了即将发生的实际字符串替换,以计算未来字符串的长度:

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

    NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];

    if([newString length] > maxLength)
       return NO;

    return YES;

另一答案

Swift 3版本// *****这不适用于Swift 2.x! // *****

首先创建一个新的Swift文件:TextFieldMaxLength.swift,然后添加以下代码:

import UIKit

private var maxLengths = [UITextField: Int]()

extension UITextField 

   @IBInspectable var maxLength: Int 

      get 

          guard let length = maxLengths[self] 
             else 
                return Int.max
      
      return length
   
   set 
      maxLengths[self] = newValue
      addTarget(
         self,
         action: #selector(limitLength),
         for: UIControlEvents.editingChanged
      )
   

func limitLength(textField: UITextField) 
    guard let prospectiveText = textField.text,
        prospectiveText.characters.count > maxLength
    else 
        return
    

   let selection = selectedTextRange
   let maxCharIndex = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
   text = prospectiveText.substring(to: maxCharIndex)
   selectedTextRange = selection
   

然后,当您选择任何TextField时,您将在Storyboard中看到一个新字段(Max Length)

如果您还有更多问题,请查看此链接:http://www.globalnerdy.com/2016/05/18/ios-programming-trick-how-to-use-xcode-to-set-a-text-fields-maximum-length-visual-studio-style/

另一答案

使用“界面”构建器,您可以在任何功能中链接并获取“编辑已更改”的事件。现在你可以检查长度

- (IBAction)onValueChange:(id)sender 

    NSString *text = nil;
    int MAX_LENGTH = 20;
    switch ([sender tag] ) 
    
        case 1: 
        
            text = myEditField.text;
            if (MAX_LENGTH < [text length]) 
                myEditField.text = [text substringToIndex:MAX_LENGTH];
            
        
            break;
        default:
            break;
    


另一答案

以下代码类似于sickp的答案,但处理正确的复制粘贴操作。如果您尝试粘贴长度超过限制的文本,以下代码将截断文本以适应限制,而不是完全拒绝粘贴操作。

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
    static const NSUInteger limit = 70; // we limit to 70 characters
    NSUInteger allowedLength = limit - [textField.text length] + range.length;
    if (string.length > allowedLength) 
        if (string.length > 1) 
            // get at least the part of the new string that fits
            NSString *limitedString = [string substringToIndex:allowedLength];
            NSMutableString *newString = [textField.text mutableCopy];
            [newString replaceCharactersInRange:range withString:limitedString];
            textField.text = newString;
        
        return NO;
     else 
        return YES;
    

另一答案

为了使它能够剪切和粘贴任何长度的字符串,我建议将函数更改为:

#define MAX_LENGTH 20

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    
        NSInteger insertDelta = string.length - range.length;

        if (textField.text.length + insertDelta > MAX_LENGTH)
        
           return NO; // the new string would be longer than MAX_LENGTH
        
        else 
            return YES;
        
    
另一答案

在Swift中设置最大长度的通用解决方案。通过IBInspectable,您可以在Xcode属性Inspector.enter image description here中添加新属性

import UIKit
private var maxLengths = [UITextField: Int]()
extension UITextField 

    @IBInspectable var maxLength: Int 
        get 
            guard let length = maxLengths[self]
            else 
                return Int.max
            
            return length
        
        set 
            maxLengths[self] = newValue
            addTarget(
                self,
                action: Selector("limitLength:"),
                forControlEvents: UIControlEvents.EditingChanged
            )
        
    

    func limitLength(textField: UITextField) 
        guard let prospectiveText = textField.text
            where prospectiveText.characters.count > maxLength else 
                return
        
        let selection = selectedTextRange
        text = prospectiveText.substringWithRange(
            Range<String.Index>(prospectiveText.startIndex ..< prospectiveText.startIndex.advancedBy(maxLength))
        )
        selectedTextRange = selection
    


另一答案

Swift 2.0 +

首先为此过程创建一个类。让我们称之为StringValidator.swift。

然后只需在其中粘贴以下代码即可。

import Foundation

extension String 

func containsCharactersIn(matchCharacters: String) -> Bool 
let characterSet = NSCharacterSet(charactersInString: matchCharacters)
return self.rangeOfCharacterFromSet(characterSet) != nil


func containsOnlyCharactersIn(matchCharacters: String) -> Bool 
let disallowedCharacterSet = NSCharacterSet(charactersInString: matchCharacters).invertedSet
return self.rangeOfCharacterFromSet(disallowedCharacterSet) =

以上是关于设置UITextField的最大字符长度的主要内容,如果未能解决你的问题,请参考以下文章

UITextField 在 Swift 中设置最大字符长度

最大长度 UITextField

简单几步实现 IOS UITextField输入长度的控制

设置 UITextField 约束以在换行符中继续

iOS 设置textfield的最大文本长度

输入四个字符后如何编写UItextfield长度和更改键盘数字格式的条件