486

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

4

46 回答 46

1045

虽然UITextField该类没有最大长度属性,但通过设置文本字段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 指定。替换只是使用非空字符串进行范围删除。

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

正如评论中提到的,有一个错误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
    }

希望对你有帮助。

于 2009-11-20T21:10:26.527 回答
74

斯威夫特 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[..<indexEndOfText]
        text = String(substring)
        
        selectedTextRange = selection
    }
}

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

在此处输入图像描述

于 2015-04-22T16:56:04.560 回答
56

谢谢八月!(帖子

这是我最终使用的代码:

#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;}
}
于 2009-01-11T19:40:02.733 回答
22

要完成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);
}
于 2009-04-16T07:51:47.467 回答
17

您不能直接执行此操作 -UITextField没有maxLength属性,但您可以设置UITextField's委托,然后使用:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
于 2009-01-11T18:42:29.947 回答
14

通常您有多个长度不同的输入字段。

- (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
    }
}
于 2012-09-07T07:39:45.630 回答
12

最好的方法是在文本更改时设置通知。在您-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];
于 2009-01-11T19:19:37.767 回答
11

这应该足以解决问题(将 4 替换为您想要的限制)。只需确保在 IB 中添加委托即可。

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
     NSString *newString = [textField.text stringByReplacingCharactersInRange:range withString:string];
     return (newString.length<=4);
}
于 2012-08-20T10:10:17.743 回答
11

我创建了这个UITextFieldLimit 子类:

  • 支持多个文本字段
  • 设置文本长度限制
  • 粘贴预防
  • 在文本字段内显示左侧字符的标签,停止编辑时隐藏。
  • 当没有角色离开时摇动动画。

从这个 GitHub 存储库中获取UITextFieldLimit.h和:UITextFieldLimit.m

https://github.com/JonathanGurebo/UITextFieldLimit

并开始测试!

标记您的故事板创建的 UITextField 并使用身份检查器将其链接到我的子类:

身份检查员

然后您可以将其链接到 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.
}

希望课堂能帮到你。祝你好运!

于 2014-04-12T22:37:52.287 回答
11

UITextField使用以下扩展名设置 a和.的最大字符长度UITextView

斯威夫特 4.0

    private var kAssociationKeyMaxLength: Int = 0
    private var kAssociationKeyMaxLengthTextView: 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[..<indexEndOfText]
            text = String(substring)

            selectedTextRange = selection
        }
    }

UITextView

extension UITextView:UITextViewDelegate {


        @IBInspectable var maxLength: Int {
            get {
                if let length = objc_getAssociatedObject(self, &kAssociationKeyMaxLengthTextView) as? Int {
                    return length
                } else {
                    return Int.max
                }
            }
            set {
                self.delegate = self

                objc_setAssociatedObject(self, &kAssociationKeyMaxLengthTextView, newValue, .OBJC_ASSOCIATION_RETAIN)
            }
        }

        public func textViewDidChange(_ textView: UITextView) {
            checkMaxLength(textField: self)
        }
        @objc func checkMaxLength(textField: UITextView) {
            guard let prospectiveText = self.text,
                prospectiveText.count > maxLength
                else {
                    return
            }

            let selection = selectedTextRange

            let indexEndOfText = prospectiveText.index(prospectiveText.startIndex, offsetBy: maxLength)
            let substring = prospectiveText[..<indexEndOfText]
            text = String(substring)

            selectedTextRange = selection
        }
    }

您可以在下面设置限制。

在此处输入图像描述

于 2018-07-26T13:30:35.650 回答
7

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

- (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;
}
于 2011-07-28T04:58:48.637 回答
7

在 Swift 中有设置最大长度的通用解决方案。通过 IBInspectable,您可以在 Xcode 属性检查器中添加新属性。在此处输入图像描述

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
    }

}
于 2016-08-11T12:17:26.457 回答
7

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 中看到一个新字段(最大长度)

如果您还有更多问题,请查看此链接:http ://www.globalnerdy.com/2016/05/18/ios-programming-trick-how-to-use-xcode-to-set-a-text-fields -最大长度视觉工作室风格/

于 2016-09-29T15:28:47.293 回答
6

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

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

}
于 2010-09-16T08:35:52.853 回答
6

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

- (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;
    }
}
于 2014-08-12T08:02:52.443 回答
5

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

#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;
        }
    }
于 2009-10-13T07:34:32.770 回答
4

斯威夫特 4

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let text = textField.text else { return true }
    let newLength = text.count + string.count - range.length
    return newLength <= 10
}
于 2018-02-09T17:07:15.257 回答
3

斯威夫特 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) == nil
}


func doesNotContainCharactersIn(matchCharacters: String) -> Bool {
let characterSet = NSCharacterSet(charactersInString: matchCharacters)
return self.rangeOfCharacterFromSet(characterSet) == nil
}

func isNumeric() -> Bool
{
let scanner = NSScanner(string: self)
scanner.locale = NSLocale.currentLocale()

return scanner.scanDecimal(nil) && scanner.atEnd
}

}

现在保存课程......

用法..

现在转到您的 viewController.swift 类并将您的文本字段的网点设置为..

@IBOutlet weak var contactEntryTxtFld: UITextField! //First textfield
@IBOutlet weak var contactEntryTxtFld2: UITextField!   //Second textfield

现在转到文本字段的 shouldChangeCharactersInRange 方法并使用如下。

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if string.characters.count == 0 {
        return true
    }
    let latestText = textField.text ?? ""
    let checkAbleText = (latestText as NSString).stringByReplacingCharactersInRange(range, withString: string)


    switch textField {

    case contactEntryTxtFld:
        return checkAbleText.containsOnlyCharactersIn("0123456789") && prospectiveText.characters.count <= 5

    case contactEntryTxtFld2:
        return checkAbleText.containsOnlyCharactersIn("0123456789") && prospectiveText.characters.count <= 5

    default:
        return true
    }

}

不要忘记设置文本字段的委托协议/方法。

让我解释一下……我正在使用我在另一个类中编写的字符串的简单扩展过程。现在我只是通过添加检查和最大值从另一个需要它们的类中调用这些扩展方法。

特征...

  1. 它将设置特定文本字段的最大限制。
  2. 它将为特定文本字段设置接受键的类型。

类型...

containsOnlyCharactersIn //仅接受字符。

containsCharactersIn //接受字符组合

doesNotContainsCharactersIn //不会接受字符

希望这有帮助....谢谢..

于 2015-11-27T18:51:52.150 回答
3

迅捷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
    }

感谢您的投票。:)

于 2016-12-29T13:35:44.490 回答
3

我根据@Frouo 给出一个补充答案。我认为他的回答是最美丽的方式。因为它是我们可以重用的通用控件。

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)
            self.addTarget(self, action: #selector(checkMaxLength), for: .editingChanged)
        }
    }

    func checkMaxLength(textField: UITextField) {

        guard !self.isInputMethod(), let prospectiveText = self.text,
            prospectiveText.count > maxLength
            else {
                return
        }

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

    //The method is used to cancel the check when use Chinese Pinyin input method.
    //Becuase the alphabet also appears in the textfield when inputting, we should cancel the check.
    func isInputMethod() -> Bool {
        if let positionRange = self.markedTextRange {
            if let _ = self.position(from: positionRange.start, offset: 0) {
                return true
            }
        }
        return false
    }

}
于 2018-02-06T12:51:21.787 回答
2

这是在 UITextField 上处理最大长度的正确方法,它允许返回键退出作为第一响应者的文本字段,并让用户在达到限制时退格

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
int MAX_LENGHT = 5;
    if([string isEqualToString:@"\n"])
    {
        [textField resignFirstResponder];
        return FALSE;
    }
    else if(textField.text.length > MAX_LENGHT-1)
    {
        if([string isEqualToString:@""] && range.length == 1)
        {
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }
    else
    {
        return TRUE;
    }
}
于 2013-09-23T15:30:17.993 回答
2

这个简单的方法怎么样。它对我来说工作正常。

extension UITextField {

    func  charactersLimit(to:Int) {

        if (self.text!.count > to) {
            self.deleteBackward()
        }
    }
}

然后:

someTextField.charactersLimit(to:16)
于 2018-09-04T21:44:22.487 回答
1

其他答案不处理用户可以从剪贴板粘贴长字符串的情况。如果我粘贴一个长字符串,它应该被截断但显示出来。在您的委托中使用它:

static const NSUInteger maxNoOfCharacters = 5;

-(IBAction)textdidChange:(UITextField * )textField
{
NSString * text = textField.text;

if(text.length > maxNoOfCharacters)
{
    text = [text substringWithRange:NSMakeRange(0, maxNoOfCharacters)];
    textField.text = text;
}

// use 'text'

}
于 2013-04-04T05:39:20.733 回答
1

现在你想要多少个字符只是给出值

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range   replacementString:(NSString *)string {
     NSUInteger newLength = [textField.text length] + [string length] - range.length;
     return (newLength > 25) ? NO : YES;
  }
于 2013-11-26T11:30:48.327 回答
1

将其简化为 1 行代码:)

将文本视图的委托设置为“self”,然后<UITextViewDelegate>在 .h 中添加,在 .m 中添加以下代码 .... 您可以将数字“7”调整为您想要的最大字符数。

-(BOOL)textView:(UITextView *)a shouldChangeTextInRange:(NSRange)b replacementText:(NSString *)c {
    return ((a.text.length+c.length<=7)+(c.length<1)+(b.length>=c.length)>0);
}

该代码包括输入新字符、删除字符、选择字符然后输入或删除、选择字符和剪切、一般粘贴以及选择字符和粘贴。

完毕!






或者,使用位操作编写此代码的另一种很酷的方法是

-(BOOL)textView:(UITextView *)a shouldChangeTextInRange:(NSRange)b replacementText:(NSString *)c {
    return 0^((a.text.length+c.length<=7)+(c.length<1)+(b.length>=c.length));
}
于 2013-12-13T06:16:10.513 回答
1

我已经实现了一个 UITextField 扩展来向它添加一个 maxLength 属性。

它基于 Xcode 6 IBInspectables,因此您可以在 Interface builder 上设置 maxLength 限制。

这是实现:

UITextField+MaxLength.h

#import <UIKit/UIKit.h>

@interface UITextField_MaxLength : UITextField<UITextFieldDelegate>

@property (nonatomic)IBInspectable int textMaxLength;
@end

UITextField+MaxLength.m

#import "UITextField+MaxLength.h"

@interface UITextField_MaxLength()

@property (nonatomic, assign) id <UITextFieldDelegate> superDelegate;

@end

@implementation UITextField_MaxLength

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

    //validate the length, only if it's set to a non zero value
    if (self.textMaxLength>0) {
        if(range.length + range.location > textField.text.length)
            return NO;

        if (textField.text.length+string.length - range.length>self.textMaxLength) {
            return NO;
        }
    }

    //if length validation was passed, query the super class to see if the delegate method is implemented there
    if (self.superDelegate && [self.superDelegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) {
        return [self.superDelegate textField:textField shouldChangeCharactersInRange:range replacementString:string];
    }
    else{
        //if the super class does not implement the delegate method, simply return YES as the length validation was passed
        return YES;
    }
}

- (void)setDelegate:(id<UITextFieldDelegate>)delegate {
    if (delegate == self)
        return;
    self.superDelegate = delegate;
    [super setDelegate:self];
}

//forward all non overriden delegate methods
- (id)forwardingTargetForSelector:(SEL)aSelector {
    if ([self.superDelegate  respondsToSelector:aSelector])
        return self.superDelegate;

    return [super forwardingTargetForSelector:aSelector];
}

- (BOOL)respondsToSelector:(SEL)aSelector {
    if ([self.superDelegate respondsToSelector:aSelector])
        return YES;

    return [super respondsToSelector:aSelector];
}
@end
于 2014-11-28T17:48:09.787 回答
1

我已经开源了一个 UITextField 子类STATextField,它通过它的属性提供了这个功能(以及更多)maxCharacterLength

于 2015-06-17T01:02:34.157 回答
1

在此处使用此代码 RESTRICTED_LENGTH 是您要限制文本字段的长度。

   - (BOOL)textField:(UITextField *)textField     shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    if (textField == nameTF) {
    int limit = RESTRICTED_LENGTH - 1;
    return !([textField.text length]>limit && [string length] > range.length);
    }
   else
   {
    return YES;
   }

return NO;

}
于 2015-09-30T10:36:55.457 回答
1

我在 Swift 中使用数字键盘时限制了 8 个字符。

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    return !(textField.text?.characters.count == MAX_LENGTH && string != "")
}

我必须测试 string != "" 以允许删除按钮在数字键盘上工作,否则在达到最大值后将不允许删除文本字段中的字符。

于 2016-01-20T20:06:40.843 回答
1

对于 Xamarin:

YourTextField.ShouldChangeCharacters = 
delegate(UITextField textField, NSRange range, string replacementString)
        {
            return (range.Location + replacementString.Length) <= 4; // MaxLength == 4
        };
于 2016-03-01T13:41:09.670 回答
1

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

我构建了一个 UITextField 插入子类(github 上的 MPC_CharacterLimitedTextField)。你给它提供预期的输出标签宽度,它会处理所有语言、表情符号和粘贴问题。无论字符数如何,它都只会收集适合标签的完整字符。该项目中有一个演示,因此您可以对其进行测试以查看它是否是您所需要的。希望它会帮助任何在输出长度方面遇到与我相同问题的人。

于 2016-11-30T06:05:53.997 回答
1

你也可以在Swift 4中使用 NotificationCenter

NotificationCenter.default.addObserver(self, selector: #selector(self.handleTextChange(recognizer:)), name: NSNotification.Name.UITextFieldTextDidChange, object: yourTextField)

    @objc func handleTextChange(recognizer: NSNotification) {
            //max length is 50 charater max
            let textField = recognizer.object as! UITextField

            if((textField.text?.count)! > 50) {
                let newString: String? = (textField.text as NSString?)?.substring(to: 50)
                textField.text = newString

            }         
        }
于 2018-06-06T12:57:13.187 回答
1

Swift 4.2 和 UITextFieldDelegate 方法

这对我有用,并将文本字段限制为最大输入 8 个字符。希望 NSRange 最终将更改为 Range,但现在我很高兴使用 NSString,因为从 NSRange 创建 Range 涉及处理另一个可选项。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let text = textField.text ?? ""
    let nsString = text as NSString
    let newText = nsString.replacingCharacters(in: range, with: string)
    return newText.count <= 8
}
于 2019-03-19T21:40:46.207 回答
0

上面给出的一些答案的问题是,例如我有一个文本字段,我必须设置输入 15 个字符的限制,然后在输入第 15 个字符后停止。但他们不允许删除。那就是删除按钮也不起作用。因为我面临同样的问题。提出了解决方案,如下所示。非常适合我

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
 if(textField.tag==6)
 {
    if ([textField.text length]<=30)
    {
        return YES;   
    }
    else if([@"" isEqualToString:string])
    {
        textField.text=[textField.text substringToIndex:30 ];
    }

    return NO;
 }
 else
 {
    return YES;
 }
}

我有一个文本字段,我已将其标签设置为“6”,并且我限制了 max char limit = 30 ;在任何情况下都可以正常工作

于 2014-03-21T14:36:40.140 回答
0
(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;
}
于 2014-05-19T14:48:47.320 回答
0

我们可以像这样设置文本字段的范围..

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range  replacementString:(NSString *)string
{
     int setrange = 20;
     return !([textField.text length]>setrange && [string length] > range.length);
}
于 2014-05-20T10:51:06.763 回答
0

这限制了字符数,但也确保您可以在字段中粘贴直到最大限制。

- (void)textViewDidChange:(UITextView *)textView
{
    NSString* str = [textView text];
    str = [str substringToIndex:MIN(1000,[str length])];
    [textView setText:str];

    if([str length]==1000) {
        // show some label that you've reached the limit of 1000 characters
    }
}
于 2014-05-27T20:10:43.553 回答
0

除了回答原始问题并扩展 Frouo 的答案之外,这里有一些扩展来修剪空格字符串和最大长度,并利用这些字符串扩展来修剪 UITextField 到最大长度:

// In String_Extensions.swift

extension String {

  func trimmedString() -> String {
    var trimmedString = self.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    let components = trimmedString.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).filter { count($0) > 0 }
    return " ".join(components)
  }

  func trimmedStringToMaxLength(maxLength: Int) -> String {
    return trimmedString().substringToIndex(advance(startIndex, min(count(self), maxLength))).trimmedString()
  }

}

// In UITextField_Extensions.swift

private var maxLengthDictionary = [UITextField : Int]()
private var textFieldMaxLength = 20

extension UITextField {

  @IBInspectable var maxLength: Int {
    get {
      if let maxLength = maxLengthDictionary[self] {
        return maxLength
      } else {
        return textFieldMaxLength
      }
    }
    set {
      maxLengthDictionary[self] = newValue < textFieldMaxLength + 1 ? newValue : textFieldMaxLength
    }
  }

  func trimAndLimitToMaxLength() {
    text = text.trimmedStringToMaxLength(maxLength)
  }

}

let someTextField = UITextField()
let someString = "   This   is   a   string   that   is longer than allowable for a text field.   "
someTextField.text = someString
someTextField.trimAndLimitToMaxLength()
println(someTextField.text) // Prints "This is a string tha"
let anotherTextField = UITextField()
anotherTextField.maxLength = 5
anotherTextField.text = someString
anotherTextField.trimAndLimitToMaxLength()
println(anotherTextField.text) // Prints "This"

trimAndLimitToMaxLength()可以在 UITextFieldDelegate 中使用,textFieldDidEndEditing(_:)以便用户可以输入或粘贴比可接受的更长的字符串,然后将其缩短而不是仅以最大长度切断输入。在这样做时,我还将设置属性文本样式以指示超出可接受长度的文本的任何部分(例如,[NSBackgroundColorAttributeName : UIColor.redColor(), NSForegroundColorAttributeName : UIColor.whiteColor(), NSStrikethroughStyleAttributeName : NSNumber(int: 1)]

于 2015-05-01T11:25:10.180 回答
0

对于 Swift 2.1+

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    if (range.length + range.location > textField.text!.characters.count )
    {
        return false;
    }

    let newLength = textField.text!.characters.count + string.characters.count - range.length
    return newLength <= 25
}

希望能帮助到你

于 2015-11-03T23:54:43.250 回答
0

我想补充@sickp 给出的答案。

Swift任何多字节文本(例如表情符号)都会在他的代码中出现问题。NSRangeStringinSwift不兼容,因此委托类将它们结合起来令人沮丧。诀窍只是将String对象转换为NSString正确的解决方案,基于@sickp 写的,实际上是这样的:

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

    let currentText = (textField.text as NSString?) ?? NSString()
    let currentCharacterCount = currentText.length
    if range.length + range.location > currentCharacterCount {
        return false
    }
    let newLength = currentText.replacingCharacters(in: range, with: string).characters.count
    return newLength <= 25
}
于 2017-04-07T17:18:41.920 回答
0

适用于 Swift 3.1 或更高版本

首先添加协议UITextFieldDelegate

像:-

class PinCodeViewController: UIViewController, UITextFieldDelegate { 
.....
.....
.....

}

之后创建你的 UITextField 并设置委托

完成经验:-

import UIKit

class PinCodeViewController: UIViewController, UITextFieldDelegate {

let pinCodetextField: UITextField = {
    let tf = UITextField()
    tf.placeholder = "please enter your pincode"
    tf.font = UIFont.systemFont(ofSize: 15)
    tf.borderStyle = UITextBorderStyle.roundedRect
    tf.autocorrectionType = UITextAutocorrectionType.no
    tf.keyboardType = UIKeyboardType.numberPad
    tf.clearButtonMode = UITextFieldViewMode.whileEditing;
    tf.contentVerticalAlignment = UIControlContentVerticalAlignment.center
 return tf
  }()


 override func viewDidLoad() {
   super.viewDidLoad()
   view.addSubview(pinCodetextField)
    //----- setup your textfield anchor or position where you want to show it----- 


    // after that 
pinCodetextField.delegate = self // setting the delegate

 }
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    return !(textField.text?.characters.count == 6 && string != "")
     } // this is return the maximum characters in textfield 
    }
于 2017-06-28T12:26:59.643 回答
0

在 Swift 5.2 中工作

 class AngListVC: UIViewController, UITextFieldDelegate {

    @IBOutlet weak var angTextField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        angTextField.delegate = self
        angTextField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
      
    }

   func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
           let userText =  angTextField.text ?? ""
           var newText = ""
           if range.length > 0 {
               let txt = NSString(string: userText)
               if txt.length > 0 {
                   newText = txt.replacingCharacters(in: range, with: "")
               }
           } else {
               newText = userText + ""
           }
           return newText.count <= 3
       }

@objc func textFieldDidChange(_ textField: UITextField) {
        print("textFieldDidChange")
   }
于 2021-03-20T01:27:10.547 回答
0

对于斯威夫特 5

添加 UITextfield 的这个扩展,然后选择一个文本字段并检查属性检查器

private var __maxLengths = [UITextField: Int]()

extension UITextField {
    @IBInspectable var maxLength: Int {
        get {
            guard let l = __maxLengths[self] else {
               return 150 // (default int limit)
            }
            return l
        }
        set {
            __maxLengths[self] = newValue
            addTarget(self, action: #selector(setMaxLength), for: .editingChanged)
        }
    }

    @objc func setMaxLength(textField: UITextField) {
        let t = textField.text
        textField.text = t?.prefix(maxLength).description
    }
}

在此处输入图像描述

于 2021-08-26T08:37:47.553 回答
-1
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    if (textField.text.length >= 50) {
        return NO;
    }
    return YES;
}
于 2015-04-29T07:02:03.593 回答
-1

斯威夫特 4.2+

通过实现 UITextFieldDelegate方法

  1. 视图控制器:

    class MyViewController: UIViewController {
    
        let MAX_LENGTH = 256
    
        @IBOutlet weak var myTextField: UITextField!
    
        override viewDidLoad() {
            self.myTextField.delegate = self
        }
    }
    
  2. 代表:

    extension MyViewController: UITextFieldDelegate {
    
        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            let userText =  textView.text ?? ""
            var newText = ""
            if range.length > 0 {
                let txt = NSString(string: userText)
                if txt.length > 0 {
                    newText = txt.replacingCharacters(in: range, with: text)
                }
            } else {
                newText = userText + text
            }
            return newText.count <= MAX_LENGTH
        }
    
    }
    
于 2019-06-17T08:46:07.160 回答
-6

我发现这又快又简单

- (IBAction)backgroundClick:(id)sender {
    if (mytext.length <= 7) {
        [mytext resignFirstResponder];
    } else {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Too Big" 
                                                        message:@"Please Shorten Name"
                                                       delegate:nil 
                                              cancelButtonTitle:@"Cancel"
                                              otherButtonTitles:nil];
        [alert show];
        [alert release];
    }
}
于 2010-03-19T20:54:28.447 回答