Defina o comprimento máximo de caracteres de um UITextField


Respostas:


1029

Embora a UITextFieldclasse não tenha propriedade de tamanho máximo, é relativamente simples obter essa funcionalidade, definindo os campos de texto delegatee implementando o seguinte método delegado:

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

Rápido

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
}

Antes de o campo de texto mudar, o UITextField pergunta ao delegado se o texto especificado deve ser alterado. O campo de texto não mudou neste momento; portanto, pegamos o comprimento atual e o comprimento da string que estamos inserindo (colando o texto copiado ou digitando um único caractere usando o teclado), menos o comprimento do intervalo. Se esse valor for muito longo (mais de 25 caracteres neste exemplo), retorne NOpara proibir a alteração.

Ao digitar um único caractere no final de um campo de texto, range.locationserá o comprimento do campo atual e range.lengthserá 0 porque não estamos substituindo / excluindo nada. Inserir no meio de um campo de texto significa apenas um diferente range.location, e colar vários caracteres significa que stringpossui mais de um caractere.

A exclusão de caracteres únicos ou o corte de vários caracteres é especificada por a rangecom um comprimento diferente de zero e uma sequência vazia. A substituição é apenas uma exclusão de intervalo com uma sequência não vazia.

Uma observação sobre o erro "desfazer"

Como é mencionado nos comentários, há um erro UITextFieldque pode levar a uma falha.

Se você colar no campo, mas a pasta for impedida pela implementação da validação, a operação de colar ainda será registrada no buffer de desfazer do aplicativo. Se você desfazer uma ação (agitando o dispositivo e confirmando um Desfazer), a UITextFieldtentativa tentará substituir a cadeia que ela acha que colou nela mesma com uma cadeia vazia. Isso irá travar porque nunca realmente colou a string nela mesma. Ele tentará substituir uma parte da string que não existe.

Felizmente, você pode proteger-se UITextFieldde se matar assim. Você só precisa garantir que a gama que propõe a substituição faz existir dentro de sua seqüência atual. É isso que a verificação de sanidade inicial acima faz.

Swift 3.0 com copiar e colar funcionando bem.

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
    }

Espero que seja útil para você.


7
Encontre uma solução envolvendo essas 2 linhas com if (textField == _ssn) {} e adicionando return YES; no final do método, o que permitirá que todos os outros UITextFields aceitem texto sem nenhuma restrição. Bacana!
Kyle Clegg

55
Boa resposta, mas o operador ternário é supérfluo; você poderia colocarreturn newLength <= 25;
jowie

2
E se você apenas quiser que o texto não se espalhe sobre o quadro do campo de texto; nem todos os caracteres têm a mesma largura, certo?
Morkrom

2
Realmente há um erro de desfazer como o @bcherry menciona - testado UITextFieldno iPad iOS 8.1. (+1 para comentar). O autor adicionaria algo sobre isso, pois é a resposta mais votada? Fico feliz em fazer uma edição, mas as minhas parecem ser rejeitadas regularmente! :-)
Benjohn 24/11

8
@bherry No Swift, a verificação do caso de desfazer parece interromper a entrada de emoji. A contagem (textField.text) não deveria realmente ser count (textField.text.utf16) para corresponder aos relatórios objc / uikit no intervalo (versus a variante de Swift da contagem de strings)?
Rcw3

62

Swift 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
    }
}

Edição: problema de vazamento de memória corrigido.

insira a descrição da imagem aqui


Ótima idéia Frouo! Eu a expandi na minha resposta para mover o corte maxLength para uma extensão String, para que ele também possa ser usado para coisas como instâncias UITextView e para adicionar uma função de conveniência para tirar proveito dessas extensões String em uma extensão UITextField.
Scott Gardner

1
Não esta variável global criar vazamentos de memória, mantendo referências a todos os TextViews (que referenciam os superviews até raiz-)
Ixx

3
@Ixx Eu editei para corrigir o problema de fuga de memória que você apontou + rápida 3. Graças
frouo

1
a maneira mais bonita de conseguir isso! Obrigado
Victor Choy

Alguém pode me fornecer sua versão objetivo
MRizwan33

56

Obrigado agosto! ( Post )

Este é o código que eu acabei com o qual funciona:

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

19
Infelizmente, esta solução falha ao impedir que os usuários copiem e colem em um campo de texto, permitindo que eles ultrapassem o limite. A resposta do grão-de-bico lida com essa situação corretamente.
Ant

5
O que há com pessoas que possuem uma declaração if para retornar NO ou YES? Tente isso: return! (TextField.text.length> = MAX_LENGTH && range.length == 0);
Matt Parkins

ou issoreturn textField.text.length < MAX_LENGTH || range.length != 0;
igrek 21/11

22

Para concluir a resposta de agosto , uma possível implementação da função proposta (consulte o representante do UITextField ).

Eu não testei o código de domínio, mas o meu não fica preso se o usuário atingir o limite e é compatível com uma nova string que substitui uma menor ou igual.

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

17

Você não pode fazer isso diretamente - UITextFieldnão tem atributo maxLength , mas pode definir o UITextField'sdelegado e usar:

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

5
Concordo, este é o melhor caminho a seguir, mas permanece um pouco complicado. Envie à Apple um relatório de bug que você gostaria de ver uma propriedade para o tamanho do texto. Eu definitivamente estou interessado nisso também.
avocade 12/01/09

5
@avocade, não é um truque: é um exemplo em que você precisa criar um código de estrutura básico que a Apple deveria ter feito por você. Existem muitos exemplos disso no SDK do iOS.
Dan Rosenstark

13

Muitas vezes você tem vários campos de entrada com um comprimento diferente.

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

12

A melhor maneira seria configurar uma notificação sobre a alteração do texto. No seu -awakeFromNibmétodo de controle de exibição, você deseja:

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

Em seguida, na mesma classe, adicione:

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

Em seguida, conecte a tomada myTextFieldà sua UITextFielde ela não permitirá que você adicione mais caracteres depois de atingir o limite. Certifique-se de adicionar isso ao seu método de desalocação:

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

Embora eu tenha feito isso para remover erros> myTextField.text = [myTextField.text substringToIndex: limit];
Lucas

11

Eu criei esta subclasse UITextFieldLimit:

  • Vários campos de texto suportados
  • Defina o limite de comprimento do texto
  • Prevenção de pasta
  • Exibe um rótulo de caracteres esquerdos dentro do campo de texto, fica oculto quando você para de editar.
  • Agite a animação quando não houver caracteres.

Pegue o UITextFieldLimit.he UITextFieldLimit.mdeste repositório do GitHub:

https://github.com/JonathanGurebo/UITextFieldLimit

e comece a testar!

Marque o UITextField criado pelo storyboard e vincule-o à minha subclasse usando o Identity Inspector:

Inspetor de identidade

Em seguida, você pode vinculá-lo a um IBOutlet e definir o limite (o padrão é 10).


Seu arquivo ViewController.h deve conter: (se você não quiser modificar a configuração, como o limite)

#import "UITextFieldLimit.h"

/.../

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

Seu arquivo ViewController.m deve @synthesize textFieldLimit.


Defina o limite de comprimento do texto no seu arquivo 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.
}

Espero que a classe ajude você. Boa sorte!


Para a pequena necessidade do limite de caracteres, acho que adicionar sua classe seria apenas um exagero.
187 Domness

Ainda esforço apreciado.
Reaper

11

Isso deve ser suficiente para resolver o problema (substitua 4 pelo limite que você deseja). Apenas certifique-se de adicionar delegado no IB.

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

9

Use a extensão abaixo para definir o comprimento máximo de caracteres de a UITextFielde UITextView.

Swift 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
        }
    }

Você pode definir o limite abaixo.

insira a descrição da imagem aqui


melhor resposta de longe ,,, graças uma solução muito grande quando há muitos campos de texto que precisam de diferentes comprimentos
Carlos Norena

Solução realmente excelente para o campo de texto e o limite de entrada de caracteres de controle de visualização de texto. Sua economia de linhas de código e tempo também para desenvolvedor ... :)
Sandip Patel - SM

Isso funciona melhor do que as outras soluções que encontrei. Por exemplo, se você tiver emojis no seu campo de texto, outras extensões que encontrei pulariam para o final da linha durante a edição. Mas seu código não faz isso. Obrigado!
Phontaine Judd 31/12/19

7

Eu simulo a substituição real da string que está prestes a calcular o tamanho da string futura:

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

7

Versão Swift 3 // ***** Isso NÃO funcionará com o Swift 2.x! ***** //

Primeiro, crie um novo arquivo Swift: TextFieldMaxLength.swift e adicione o código abaixo:

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

e, no Storyboard, você verá um novo campo (Comprimento máximo) ao selecionar qualquer Campo de texto

se você ainda tiver mais perguntas, consulte este link: http://www.globalnerdy.com/2016/05/18/ios-programming-trick-how-to-use-xcode-to-set-a-text-fields -maximum-length-visual-studio-style /


Atenção, essa variável global cria vazamentos de memória, mantendo referências a todas as visualizações de texto.
frouo

6

Usando o construtor Interface, você pode vincular e obter o evento para "Edição alterada" em qualquer uma das suas funções. Agora você pode colocar o cheque pelo comprimento

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

}

6

O código a seguir é semelhante à resposta do sickp, mas lida com operações de copiar e colar corretamente. Se você tentar colar um texto maior que o limite, o código a seguir truncará o texto para que ele se ajuste ao limite, em vez de recusar completamente a operação de colar.

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

6

Existe uma solução genérica para definir o comprimento máximo no Swift. Por IBInspectable, você pode adicionar um novo atributo no Xcode Attribute Inspector.insira a descrição da imagem aqui

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
    }

}

Solução limpa e perfeita
Eduardo

Manter um UITextField em um campo global os manterá na memória mesmo depois que o UIViewController for descartado. Este é um vazamento de memória. Não use esse método.
Gunhan 27/02/19

5

Para fazê-lo funcionar com recortar e colar cordas de qualquer comprimento, sugiro alterar a função para algo como:

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

4

Swift 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
}

Por que o guard?
precisa saber é o seguinte

verificar se o texto é nulo, se você quiser, você também pode usar se @oddRaven
Shan Ye

3

Swift 2.0 +

Antes de tudo, crie uma classe para esse processo. Vamos chamá-lo de StringValidator.swift.

Em seguida, basta colar o seguinte código dentro dele.

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
}

}

Agora salve a turma .....

Uso..

Agora vá para a classe viewController.swift e faça as saídas do seu campo de texto como ..

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

Agora vá para o método shouldChangeCharactersInRange do campo de texto e use como o seguinte.

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
    }

}

Não se esqueça de definir o protocolo / métodos de delegação de campos de texto.

Deixe-me explicar sobre isso ... Estou usando o processo simples de extensão de string que escrevi dentro de outra classe. Agora, estou apenas chamando esses métodos de extensão de outra classe em que preciso deles, adicionando cheque e valor máximo.

Recursos...

  1. Ele definirá o limite máximo de um campo de texto específico.
  2. Ele definirá o tipo de chaves aceitas para um campo de texto específico.

Tipos ...

containsOnlyCharactersIn // Aceita apenas caracteres.

containsCharactersIn // Aceita combinação de caracteres

doesNotContainsCharactersIn // Não aceita caracteres

Espero que isso tenha ajudado .... Obrigado ..


3

swift 3.0

Este código está funcionando bem quando você cola a string mais do que os limites de caracteres.

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
    }

Obrigado por seus votos. :)


2
UITextField, não UITextView.
Jonny

3

Dou uma resposta complementar com base no @Frouo. Eu acho que a resposta dele é a maneira mais bonita. Porque é um controle comum que podemos reutilizar.

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
    }

}

2

Esta é a maneira correta de lidar com o comprimento máximo no UITextField, permite que a tecla de retorno saia da renúncia do campo de texto como primeiro respondedor e permite que o usuário volte ao espaço quando atingir o limite

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

2

E essa abordagem simples. Está funcionando bem para mim.

extension UITextField {

    func  charactersLimit(to:Int) {

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

Então:

someTextField.charactersLimit(to:16)

1

Outras respostas não tratam do caso em que o usuário pode colar uma cadeia longa da área de transferência. Se eu colar uma string longa, ela deve ser truncada, mas mostrada. Use isso em seu delegado:

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'

}

1

Reduzi a 1 linha de código :)

Defina o delegado da sua exibição de texto como "self" e adicione o <UITextViewDelegate>.he o seguinte código no seu .m .... você pode ajustar o número "7" para o que você deseja que seu número MÁXIMO de caracteres seja.

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

Esse código é responsável pela digitação de novos caracteres, exclusão de caracteres, seleção de caracteres e digitação ou exclusão, seleção de caracteres e recorte, colagem em geral e seleção de caracteres e colagem.

Feito!






Como alternativa, outra maneira legal de escrever esse código com operações de bits seria

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

1

Abri de código aberto uma subclasse UITextField, STATextField , que oferece essa funcionalidade (e muito mais) com sua maxCharacterLengthpropriedade.


1

agora quantos caracteres você quer apenas dar valores

 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range   replacementString:(NSString *)string {
     NSUInteger newLength = [textField.text length] + [string length] - range.length;
     return (newLength > 25) ? NO : YES;
  }

1

Use este código aqui RESTRICTED_LENGTH é o comprimento que você deseja restringir para o campo de texto.

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

}

1

Eu fiz isso no Swift por um limite de 8 caracteres ao usar um teclado numérico.

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

Eu tive que testar a string! = "" Para permitir que o botão excluir funcionasse no teclado numérico, caso contrário, não permitiria excluir caracteres no campo de texto depois que atingisse o valor máx.


1

Para o Xamarin:

YourTextField.ShouldChangeCharacters = 
delegate(UITextField textField, NSRange range, string replacementString)
        {
            return (range.Location + replacementString.Length) <= 4; // MaxLength == 4
        };

1

Eu implementei uma extensão UITextField para adicionar uma propriedade maxLength a ela.

É baseado no Xcode 6 IBInspectables, para que você possa definir o limite maxLength no construtor Interface.

Aqui está a implementação:

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.