Estoy dando una vista de texto para tuitear alguna cadena.
Estoy aplicando el siguiente método para restringir el número de caracteres a 140 de longitud.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text{
return [[textView text] length] <= 140;
}
El código funciona bien, excepto la primera condición de que el retroceso no funciona. Supongamos que he alcanzado el límite de 140 caracteres para que el método me dé falso y el usuario no pueda insertar más caracteres pero luego de eso cuando intento borrar algunos caracteres la vista de texto se comporta como si estuviera deshabilitada.
Entonces, la pregunta es: "¿Cómo eliminar caracteres textview.text
o volver a habilitar la vista de texto?"
ios
iphone
uitextview
uitextviewdelegate
harshalb
fuente
fuente
Respuestas:
En su lugar, debería buscar una cadena vacía, como dice la referencia de Apple
Creo que la verificación que realmente desea hacer es algo así como
[[textView text] length] - range.length + text.length > 140
para tener en cuenta las operaciones de cortar / pegar.fuente
[[textView text] length] - range.length + text.length > 140
, para tener en cuenta las operaciones de cortar / pegar.- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { return textView.text.length + (text.length - range.length) <= 140; }
Esto tiene en cuenta que los usuarios cortan texto o eliminan cadenas de más de un carácter (es decir, si seleccionan y luego presionan la tecla de retroceso), o resaltan un rango y pegan cadenas más cortas o más largas que él.
Versión Swift 4.0
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { return textView.text.count + (text.count - range.length) <= 140 }
fuente
false
lo tanto , se devolverá) y luego intentará deshacer la acción.para Swift 4:
//MARK:- TextView Delegate func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { //300 chars restriction return textView.text.count + (text.count - range.length) <= 300 }
fuente
Sin embargo, también puede usar el siguiente código de trabajo.
- (void)textViewDidChange:(UITextView *)textView{ NSInteger restrictedLength=140; NSString *temp=textView.text; if([[textView text] length] > restrictedLength){ textView.text=[temp substringToIndex:[temp length]-1]; } }
fuente
Con Swift 5 y iOS 12, pruebe la siguiente implementación del
textView(_:shouldChangeTextIn:replacementText:)
método que forma parte delUITextViewDelegate
protocolo:func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { guard let rangeOfTextToReplace = Range(range, in: textView.text) else { return false } let substringToReplace = textView.text[rangeOfTextToReplace] let count = textView.text.count - substringToReplace.count + text.count return count <= 10 }
range
(NSRange
) arangeOfTextToReplace
(Range<String.Index>
). Vea este video tutorial para comprender por qué esta conversión es importante.textField
'ssmartInsertDeleteType
valor aUITextSmartInsertDeleteType.no
. Esto evitará la posible inserción de un espacio extra (no deseado) al realizar una operación de pegado.El código de muestra completo a continuación muestra cómo implementar
textView(_:shouldChangeTextIn:replacementText:)
en unUIViewController
:import UIKit class ViewController: UIViewController, UITextViewDelegate { @IBOutlet var textView: UITextView! // Link this to a UITextView in Storyboard override func viewDidLoad() { super.viewDidLoad() textView.smartInsertDeleteType = UITextSmartInsertDeleteType.no textView.delegate = self } func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { guard let rangeOfTextToReplace = Range(range, in: textView.text) else { return false } let substringToReplace = textView.text[rangeOfTextToReplace] let count = textView.text.count - substringToReplace.count + text.count return count <= 10 } }
fuente
Rápido:
// MARK: UITextViewDelegate let COMMENTS_LIMIT = 255 func textView(textView: UITextView, shouldChangeTextInRange range:NSRange, replacementText text:String ) -> Bool { return count(comments.text) + (count(text) - range.length) <= COMMENTS_LIMIT; }
fuente
countElements
ha sido reemplazado porcount
en swift 1.2ue esto
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { int limit = 139; return !([textField.text length]>limit && [string length] > range.length); }
esto solo ingresará 140 caracteres y puede eliminarlos si es necesario
fuente
¡Limite el desbordamiento, no el texto completo!
Al regresar
false
en el...shouldChangeTextInRange...
método delegado, en realidad está limitando todo el texto y manejar las siguientes situaciones podría ser muy difícil:Así que puedes:
Solo limita el desbordamiento del texto
Eliminando caracteres adicionales:
textView.text = String(textView.text.prefix(140))
¡Puedes hacerlo incluso sobre la marcha ! poniendo este código dentro de la acción del
textView
otextField
con el.editingChanged
evento.fuente
func textViewDidChange(_ textView: UITextView) {...}
funciona maravillosamente, solo recortando el final de un texto largo pegadoAunque necesitaba una
if-else
condición, esto funcionó para mí:- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { BOOL status = textView.text.length + (text.length - range.length) <= 15; if (status) { [self.btnShare setEnabled:YES]; [self.btnShare setAlpha:1]; } else { [self.btnShare setEnabled:NO]; [self.btnShare setAlpha:0.25]; } return status; }
Inicialmente, el botón está desactivado. Pero si desea que el usuario no pueda publicar una prueba vacía, simplemente ponga una condición al hacer clic en el botón:
- (void)btnShare_click:(id)sender { NSString *txt = [self.txtShare.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; if ([txt length] == 0) { [self.btnShare setEnabled:NO]; [self.btnShare setAlpha:0.25f]; [[[UIAlertView alloc]initWithTitle:nil message:@"Please enter some text to share." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show]; return; } . . . . . . // rest of your code }
fuente
El problema con algunas de las respuestas dadas anteriormente es, por ejemplo, tengo un campo de texto y tengo que establecer un límite de entrada de 15 caracteres, luego se detiene después de ingresar el 15º carácter. pero no permiten borrar. Ese es el botón de eliminar que tampoco funciona. Ya que estaba enfrentando el mismo problema. Salió con la solución, dada a continuación. Funciona perfecto para mí
- (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; } }
Tengo un campo de texto, cuya etiqueta he establecido "6" y he restringido el límite máximo de caracteres = 30; funciona bien en todos los casos
fuente
Versión Swift de @Tim Gostony:
// restrict the input for textview to 500 func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { return count(textView.text) + (count(text) - range.length) <= 500; }
fuente
Aquí vamos para lograr el mejor ajuste. Muestra el número de caracteres restantes: quedan 'n' caracteres.
var charCount = 0; let maxLength = 150 func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { if text == "" // Checking backspace { if textView.text.characters.count == 0 { charCount = 0 characterCount.text = String(format: "%i Characters Left", maxLength - charCount) return false } charCount = (textView.text.characters.count - 1) characterCount.text = String(format: "%i Characters Left", maxLength - charCount) return true } else { charCount = (textView.text.characters.count + 1) characterCount.text = String(format: "%i Characters Left", maxLength - charCount) if charCount >= maxLength + 1 { charCount = maxLength characterCount.text = String(format: "%i Characters Left", maxLength - charCount) return false; } } return true }
fuente
Si también está buscando poder pegar código hasta el número máximo de caracteres, mientras corta el desbordamiento y actualiza una etiqueta de recuento:
let maxChar: Int let countLabel: UILabel func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { let oldChar = textView.text.count - range.length let oldRemainingChar = maxChar - oldChar let newChar = oldChar + text.count let newRemainingChar = maxChar - newChar let replaceChar = newRemainingChar > 0 ? text.count : oldRemainingChar if let textRange = textView.textRange(for: range), replaceChar > 0 || range.length > 0 { textView.replace(textRange, withText: String(text.prefix(replaceChar))) countLabel.text = String(describing: maxChar - textView.text.count) } return false }
Con la extensión:
extension UITextInput { func textRange(for range: NSRange) -> UITextRange? { var result: UITextRange? if let start = position(from: beginningOfDocument, offset: range.location), let end = position(from: start, offset: range.length) { result = textRange(from: start, to: end) } return result } }
fuente
Probar esto:-
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { print("chars \(textView.text.count) \( text)") if(textView.text.count > 20 && range.length == 0) { print("Please summarize in 20 characters or less") return false } return true }
fuente
Escriba el siguiente código en el
textView:shouldChangeTextInRange:replacementText:
método:if ([textView.text length]>=3 && ![text isEqualToString:@""]) { return NO; } return YES;
fuente
Swift5:
let maxChars = 255 func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { if maxChars - aTextView.text.count == 0 { if range.length != 1 { return false } } return true }
fuente
Utilice el siguiente código.
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { if(text.length == 0) { return YES; } else if(self.txtViewComments.text.length > 255) { return NO; } else { return YES; } }
fuente
Aquí está la solución más simple para restringir que el usuario ingrese el número de caracteres en
UITextField
oUITextView
en iOS swiftfunc textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { return textField.text!.count < limit ? true : false }
Nota: aquí el límite puede ser cualquier cosa desde
1
hastan
según su requisito, por ejemplo: si está trabajando en el número de teléfono, ellimit
valor será10
si desea aplicar el mismo enUITextView
solo el método se cambiará y en el lugartextfield
donde se usarátextview
fuente