ios - length - uitextfield limit number of characters objective c




Definir o comprimento máximo de caracteres de um UITextField (20)

Como posso definir a quantidade máxima de caracteres em um UITextField no iPhone SDK quando carrego um UIView ?


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

Editar: problema de vazamento de memória corrigido.


rápido 3.0

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

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. :)


Consegui até 1 linha de código :)

Defina o delegate da sua visão de texto para "self", em seguida, adicione o <UITextViewDelegate> em seu .h e o seguinte código em seu .m .... você pode ajustar o número "7" para ser o que você quiser que seu número MÁXIMO de caracteres seja estar.

-(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, digitação ou exclusão, seleção de caracteres e recorte, colagem geral e seleção de caracteres e colagem.

Feito!





Alternativamente, 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));
}

Embora a classe UITextField não tenha uma propriedade de tamanho máximo, é relativamente simples obter essa funcionalidade definindo o delegate do campo de texto e implementando o seguinte método de delegação:

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 do campo de texto mudar, o UITextField pergunta ao delegado se o texto especificado deve ser alterado. O campo de texto não mudou neste ponto, então pegamos o comprimento atual e o tamanho da string que estamos inserindo (ou através da colagem de texto copiado ou da digitação de um único caractere usando o teclado), menos o tamanho do intervalo. Se esse valor for muito longo (mais de 25 caracteres neste exemplo), retorne NO para proibir a alteração.

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

A exclusão de caracteres únicos ou do corte de vários caracteres é especificada por um range com comprimento diferente de zero e uma string vazia. A substituição é apenas uma exclusão de intervalo com uma string não vazia.

Uma nota sobre o erro "desfazer"

Como é mencionado nos comentários, há um bug no UITextField que pode levar a uma falha.

Se você colar no campo, mas a pasta for impedida pela sua implementação de validação, a operação de colagem ainda será registrada no buffer de desfazer do aplicativo. Se você, em seguida, disparar um desfazer (agitando o dispositivo e confirmando um Undo), o UITextField tentará substituir a seqüência de caracteres que acha que colou em si mesmo com uma seqüência vazia. Isso irá falhar porque nunca colou a string em si. Ele tentará substituir uma parte da string que não existe.

Felizmente você pode proteger o UITextField de se matar assim. Você só precisa garantir que o intervalo que ele propõe substituir exista em sua sequência atual. Isto é o que a verificação inicial de sanidade 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ê.


Eu STATextField uma subclasse UITextField, STATextField , que oferece essa funcionalidade (e muito mais) com sua propriedade maxCharacterLength .


Eu criei this subclasse UITextFieldLimit:

  • Vários campos de texto suportados
  • Definir o limite de tamanho do texto
  • Colar prevenção
  • Exibe um rótulo de caracteres à esquerda dentro do campo de texto, fica oculto quando você para de editar.
  • Agite a animação quando não houver mais caracteres.

Pegue o UITextFieldLimit.h UITextFieldLimit.m deste repositório GitHub:

this

e comece a testar!

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

Então 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 deseja 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 tamanho de 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 turma ajude você. Boa sorte!


Eu fiz isso no Swift para 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 delete funcionasse no teclado numérico, caso contrário, não permitiria a exclusão de caracteres no campo de texto depois que ele atingisse o seu limite máximo.


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

Ele é baseado no Xcode 6 IBInspectables, portanto, você pode 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

Existe uma solução genérica para definir o comprimento máximo no Swift. Por IBInspectable você pode adicionar um novo Attribute in 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<String.Index>(prospectiveText.startIndex ..< prospectiveText.startIndex.advancedBy(maxLength))
        )
        selectedTextRange = selection
    }

}

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

O código a seguir é semelhante à resposta do doente, mas lida corretamente com operações de copiar e colar. Se você tentar colar um texto maior que o limite, o código a seguir truncará o texto para se ajustar 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;
    }
}

Obrigado augusto! ( Post )

Este é o código que acabei com o que 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;}
}

Para Xamarin:

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

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

Eu não testei o código domness , mas o meu não fica preso se o usuário atingir o limite, e é compatível com uma nova string que vem substituir 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);
}

Swift 3 version // ***** 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 então você verá no Storyboard um novo campo (Max Length) quando você selecionar qualquer TextField

Se você ainda tem mais perguntas, confira 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/


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

}

Use este código aqui RESTRICTED_LENGTH é o tamanho 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;

}

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

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

Swift 2.0 +

Primeiro 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 sua classe viewController.swift e faça as tomadas 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 se segue.

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 delegado / métodos de campos de texto.

Deixe-me explicar sobre isso ... Eu estou usando o processo de extensão simples de string que eu escrevi dentro de uma outra classe. Agora eu estou apenas chamando esses métodos de extensão de outra classe onde eu preciso deles adicionando check e valor máximo.

Características...

  1. Ele irá definir o limite máximo de um determinado campo de texto.
  2. Ele definirá o tipo de chaves aceitas para determinado campo de texto.

Tipos ...

containsOnlyCharactersIn // Aceita apenas caracteres.

containsCharactersIn // Aceita combinação de caracteres

doesNotContainsCharactersIn // não aceita caracteres

Espero que isso ajudou .... Obrigado ..


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
}




uitextfield