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


当前回答

如果您限制文本计数的目的是确保文本可以适合其他地方的UILabel,那么我会避免使用字符计数。它会因为一些表情符号而崩溃(试图截断一个两倍大小的表情符号可能会导致应用程序崩溃)。这也是一些语言(如日语和汉语)的问题,它们有两步输入过程,简单的计数是行不通的。

我构建了一个UITextField下拉子类(MPC_CharacterLimitedTextField在github)。你输入预期的输出标签宽度,它将处理所有语言、表情符号和粘贴问题。不管字符数是多少,它只会收获符合标签的完整字符数。项目中有一个演示,所以你可以测试它,看看它是否是你需要的。希望它能帮助到和我一样有输出长度问题的人。

其他回答

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

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

你不能直接这样做- UITextField没有maxLength属性,但你可以设置UITextField的委托,然后使用:

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

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

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以禁止更改。

当在文本字段的末尾输入单个字符时,范围。Location是当前字段的长度和范围。Length将为0,因为我们没有替换或删除任何东西。插入到文本字段的中间只是意味着一个不同的范围。位置,粘贴多个字符意味着字符串中有多个字符。

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

关于崩溃的“撤消”错误的说明

正如评论中提到的,UITextField有一个bug,可能导致崩溃。

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

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

Swift 3.0与复制和粘贴工作良好。

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
    }

希望对你有帮助。

使用接口构建器,您可以在任何函数中链接并获得“编辑更改”的事件。 现在你可以检查长度

- (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;
    }

}
(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];

    if ([txt_name.text length]>100)
    {
        return NO;
    }

    return YES;
}