当前位置:  开发笔记 > IOS > 正文

设置UITextField的最大字符长度

如何解决《设置UITextField的最大字符长度》经验,为你挑选了15个好方法。

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



1> sickp..:

虽然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包含多个字符.

删除单个字符或剪切多个字符由a指定,range长度为非零,空字符串.替换只是一个非空字符串的范围删除.

关于崩溃"撤消"错误的说明

正如评论中提到的那样,有一个错误UITextField可能会导致崩溃.

如果粘贴到字段中,但验证实现阻止了粘贴,则粘贴操作仍会记录在应用程序的撤消缓冲区中.如果你随后触发撤消(通过摇动设备并确认撤消),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
    }

希望它对你有所帮助.


很好的答案,但三元运算符是多余的; 你可以把`return newLength <= 25;`
找到一个解决方案,用if(textField == _ssn){}包围这两行并添加return YES; 在方法的最后,它将允许所有其他UITextFields接受文本而没有任何限制.漂亮!
@bherry在Swift中,对undo case的检查似乎打破了表情符号的输入.count(textField.text)实际上不应该是count(textField.text.utf16)来匹配范围内的objc/uikit报告(vs Swift的字符串计数变量)?
如果您只是希望文本不会溢出文本框架的框架,该怎么办?不是所有的字符都是相同的宽度,对吧?
确实存在@bcherry提到的撤消错误 - 在iPad iOS 8.1上使用`UITextField`进行测试.(+1评论).作者是否会添加一些关于此的内容,因为它是最受好评的答案?我很高兴做一个编辑,但我经常被拒绝!:-)

2> frouo..:
斯威夫特4
import UIKit

private var kAssociationKeyMaxLength: Int = 0

extension UITextField {

    @IBInspectable var maxLength: Int {
        get {
            if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLength) as? Int {
                return length
            } else {
                return Int.max
            }
        }
        set {
            objc_setAssociatedObject(self, &kAssociationKeyMaxLength, newValue, .OBJC_ASSOCIATION_RETAIN)
            addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
        }
    }

    @objc func checkMaxLength(textField: UITextField) {
        guard let prospectiveText = self.text,
            prospectiveText.count > maxLength
            else {
                return
        }

        let selection = selectedTextRange

        let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
        let substring = prospectiveText[..

编辑:内存泄漏问题已修复.

在此输入图像描述


我已编辑@Ixx,以解决您指出的问题和Swift 3带来的内存泄漏问题。

3> Domness..:

谢谢八月!(发布)

这是我最终使用的代码:

#define MAX_LENGTH 20

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (textField.text.length >= MAX_LENGTH && range.length == 0)
    {
        return NO; // return NO to not change text
    }
    else
    {return YES;}
}


遗憾的是,此解决方案无法阻止用户复制并粘贴到文本字段中,因此允许用户绕过限制.Sickpea的答案正确地应对了这种情况.
如果人们有if语句返回NO或YES?试试这个:return!(textField.text.length> = MAX_LENGTH && range.length == 0);

4> Jmini..:

要完成8月份答案,可以实现所提议的函数(请参阅UITextField的委托).

我没有测试domness代码,但是如果用户达到了限制,我不会卡住它,并且它与一个新的字符串兼容,它取代了一个更小或相等的字符串.

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    //limit the size :
    int limit = 20;
    return !([textField.text length]>limit && [string length] > range.length);
}



5> August..:

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

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


我同意,这是最好的前进方式,但它仍然是一个黑客.向Apple提交一个错误报告,您希望查看文本长度的属性.我对这一点也很感兴趣.
@avocade,这不是一个黑客:这是一个例子,你必须做你应该为你完成的基本框架代码.iOS SDK中有很多这样的例子.

6> Vincent..:

通常,您有多个具有不同长度的输入字段.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    int allowedLength;
    switch(textField.tag) {
        case 1: 
            allowedLength = MAXLENGTHNAME;      // triggered for input fields with tag = 1
            break;
        case 2:
            allowedLength = MAXLENGTHADDRESS;   // triggered for input fields with tag = 2
            break;
        default:
            allowedLength = MAXLENGTHDEFAULT;   // length default when no tag (=0) value =255
            break;
    }

    if (textField.text.length >= allowedLength && range.length == 0) {
        return NO; // Change not allowed
    } else {
        return YES; // Change allowed
    }
}



7> Martin Pilki..:

最好的方法是设置文本更改通知.在您-awakeFromNib的视图控制器方法中,您需要:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(limitTextField:) name:@"UITextFieldTextDidChangeNotification" object:myTextField];

然后在同一个类中添加:

- (void)limitTextField:(NSNotification *)note {
    int limit = 20;
    if ([[myTextField stringValue] length] > limit) {
        [myTextField setStringValue:[[myTextField stringValue] substringToIndex:limit]];
    }
}

然后将插座连接myTextField到您,UITextField并且在达到限制后不会再添加任何字符.请务必将此添加到您的dealloc方法:

[[NSNotificationCenter defaultCenter] removeObserver:self name:@"UITextFieldTextDidChangeNotification" object:myTextField];



8> Nishant..:

这应该足以解决问题(用你想要的限制替换4).只需确保在IB中添加委托.

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



9> Jonathan Gur..:

我创建了这个 UITextFieldLimit子类:

支持多个文本字段

设置文本长度限制

粘贴预防

在文本字段内显示左侧字符的标签,在停止编辑时隐藏.

没有人物离开时动摇动画.

抓住UITextFieldLimit.hUITextFieldLimit.m从该GitHub的仓库:

https://github.com/JonathanGurebo/UITextFieldLimit

并开始测试!

标记您的故事板创建的UITextField并使用Identity Inspector将其链接到我的子类:

身份检查员

然后,您可以将其链接到IBOutlet并设置限制(默认值为10).


您的ViewController.h文件应包含:(如果您不想修改设置,如限制)

#import "UITextFieldLimit.h"

/.../

@property (weak, nonatomic) IBOutlet UITextFieldLimit *textFieldLimit; // <--Your IBOutlet

你的ViewController.m文件应该@synthesize textFieldLimit.


在ViewController.m文件中设置文本长度限制:

- (void)viewDidLoad
{
    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

    [textFieldLimit setLimit:25];// <-- and you won't be able to put more than 25 characters in the TextField.
}

希望全班同学帮助你.祝好运!



10> samvermette..:

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

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



11> Gilad Brunfm..:

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 -最大长度视觉工作室风格/



12> 小智..:

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

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

}



13> 小智..:

以下代码类似于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;
    }
}



14> Hiren..:

没有通用的解决方案在斯威夫特设置最大长度.通过IBInspectable,您可以在Xcode Attribute Inspector中添加新属性.在此输入图像描述

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(prospectiveText.startIndex ..< prospectiveText.startIndex.advancedBy(maxLength))
        )
        selectedTextRange = selection
    }

}



15> Påhl Melin..:

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

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

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有