una teclas teclado tecla otra mueven mis lock las laptop funcionan flechas dirección desplazar desplazamiento despl desbloquear como celdas celda bloqueo bloq activar ios objective-c ios7 uitextfield space

ios - teclas - tecla bloqueo de desplazamiento o scroll lock



La barra espaciadora UITextField alineada a la derecha no avanza el cursor en iOS 7 (13)

¡Todas las respuestas anteriores son increíbles y muy indicativas! Especialmente gracias a la respuesta de meaning-matters continuación . Aquí hay una versión probada de Swift 2.0 . ¡Recuerde asignar el delegado del UITextField a su ViewController! Feliz codificación.

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { if (textField == self.desiredTextField) { var oldString = textField.text! let newRange = oldString.startIndex.advancedBy(range.location)..<oldString.startIndex.advancedBy(range.location + range.length) let newString = oldString.stringByReplacingCharactersInRange(newRange, withString: string) textField.text = newString.stringByReplacingOccurrencesOfString(" ", withString: "/u{00a0}"); return false; } else { return true; } }

-

¡Y aquí está Swift 3!

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if (textField == self.textfield) { let oldString = textField.text! let newStart = oldString.index(oldString.startIndex, offsetBy: range.location) let newEnd = oldString.index(oldString.startIndex, offsetBy: range.location + range.length) let newString = oldString.replacingCharacters(in: newStart..<newEnd, with: string) textField.text = newString.replacingOccurrences(of: " ", with: "/u{00a0}") return false; } else { return true; } }

En mi aplicación para iPad, noté un comportamiento diferente entre iOS 6 e iOS 7 con UITextFields.

Creo el UITextField de la siguiente manera:

UIButton *theButton = (UIButton*)sender; UITextField *textField = [[UITextField alloc] initWithFrame:[theButton frame]]; [textField setDelegate:self]; [textField setContentVerticalAlignment:UIControlContentVerticalAlignmentCenter]; [textField setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight]; textField.textAlignment = UITextAlignmentRight; textField.keyboardType = UIKeyboardTypeDefault; ... [textField becomeFirstResponder];

En iOS 6, cuando escribo "hello world" el cursor avanza un espacio en blanco cuando presiono la barra espaciadora después de "hola".

En iOS 7, el cursor no avanza cuando presiono la barra espaciadora. Sin embargo, cuando escribo "w" en "mundo", muestra el espacio y la w.

¿Cómo puedo avanzar el cursor cuando se toca la barra espaciadora en iOS 7?

Actualizar:

Si cambio el textoField.textAlignment a UITextAlignmentLeft, el espacio aparece en iOS 7. Me gustaría mantenerlo alineado a la derecha, si es posible.


Aquí está Swift 3 de la respuesta de @Jack Song

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if (textField == self.textfield) { let oldString = textField.text! let newStart = oldString.index(oldString.startIndex, offsetBy: range.location) let newEnd = oldString.index(oldString.startIndex, offsetBy: range.location + range.length) let newString = oldString.replacingCharacters(in: newStart..<newEnd, with: string) textField.text = newString.replacingOccurrences(of: " ", with: "/u{00a0}") return false; } else { return true; } }


Aquí hay una solución que siempre funciona, también para pegar y editar (es decir, cuando puede agregar / eliminar textos con múltiples espacios).

- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string { textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string]; textField.text = [textField.text stringByReplacingOccurrencesOfString:@" " withString:@"/u00a0"]; return NO; }

No se preocupe por el rendimiento de hacer stringByReplacingOccurrencesOfString cada vez; los textos en las IU son muy muy cortos en relación con la velocidad de la CPU.

Luego, cuando realmente desea obtener el valor del campo de texto:

NSString* text = [textField.text stringByReplacingOccurrencesOfString:@"/u00a0" withString:@" "];

Entonces esto es muy simétrico.


Arregle la eliminación del espacio de texto alineado a la derecha al reemplazar el espacio con espacio sin interrupciones

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (textField.textAlignment == NSTextAlignmentRight) { NSString *text = [textField.text stringByReplacingCharactersInRange:range withString:string]; textField.text = [text stringByReplacingOccurrencesOfString:@" " withString:@"/u00a0"]; UITextPosition *startPos = [textField positionFromPosition:textField.beginningOfDocument offset:range.location + string.length]; UITextRange *textRange = [textField textRangeFromPosition:startPos toPosition:startPos]; textField.selectedTextRange = textRange; return NO; } return YES; }

Y viceversa

- (void)textFieldDidEndEditing:(UITextField *)textField { // Replacing non-breaking spaces with spaces and remove obsolete data NSString *textString = [[textField.text stringByReplacingOccurrencesOfString:@"/u00a0" withString:@" "] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; textField.text = textString; }


He encontrado una solución que subclasifica la clase UITextField y realiza el intercambio, sin la necesidad de copiar y pegar código en todas partes. Esto también evita el uso de sizzle de método para solucionar esto.

@implementation CustomTextField -(id) initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if( self ) { [self addSpaceFixActions]; } return self; } - (void)addSpaceFixActions { [self addTarget:self action:@selector(replaceNormalSpaces) forControlEvents:UIControlEventEditingChanged]; [self addTarget:self action:@selector(replaceBlankSpaces) forControlEvents:UIControlEventEditingDidEnd]; } //replace normal spaces with non-breaking spaces. - (void)replaceNormalSpaces { if (self.textAlignment == NSTextAlignmentRight) { UITextRange *textRange = self.selectedTextRange; self.text = [self.text stringByReplacingOccurrencesOfString:@" " withString:@"/u00a0"]; [self setSelectedTextRange:textRange]; } } //replace non-breaking spaces with normal spaces. - (void)replaceBlankSpaces { self.text = [self.text stringByReplacingOccurrencesOfString:@"/u00a0" withString:@" "]; }


He usado la respuesta de Jack Song para Swift 2 por un tiempo hasta que me di cuenta de que los espacios que no frenaban creaban problemas cuando se procesaban en HTML en otros lugares, y el salto de línea se complicaba en el UITextView. Por lo tanto, he mejorado la solución para que los personajes que no son de bracking se limpien de inmediato.

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { if (textField == self.desiredTextField) { var oldString = textView.text! oldString = oldString.stringByReplacingOccurrencesOfString("/u{00a0}", withString: " "); let newRange = oldString.startIndex.advancedBy(range.location)..<oldString.startIndex.advancedBy(range.location + range.length) let alteredText = text.stringByReplacingOccurrencesOfString(" ", withString: "/u{00a0}") textView.text = oldString.stringByReplacingCharactersInRange(newRange, withString: alteredText) return false; } else { return true; } }


Mi solución siguiente también soluciona el problema con el cursor saltando hasta el final al escribir un espacio en el medio o al principio de la cadena. Además, pegar una cadena ahora también se procesa correctamente.

También puse un cheque para los campos de la dirección de correo electrónico y otros controles, pero la parte interesante es la última parte. Funciona perfectamente para mí, todavía tengo que encontrar un problema con él.

Puedes copiarlo / pegarlo directamente en tu proyecto. ¡No olvide implementar el didBeginEditing y didEndEditing para reemplazar los espacios con espacios sin interrupciones y de regreso!

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (textField.textAlignment != NSTextAlignmentRight) //the whole issue only applies to right aligned text return YES; if (!([string isEqualToString:@" "] || string.length > 1)) //string needs to be a space or paste action (>1) to get special treatment return YES; if (textField.keyboardType == UIKeyboardTypeEmailAddress) //keep out spaces from email address field { if (string.length == 1) return NO; //remove spaces and nonbreaking spaces from paste action in email field: string = [string stringByReplacingOccurrencesOfString:@" " withString:@""]; string = [string stringByReplacingOccurrencesOfString:@"/u00a0" withString:@""]; } //special treatment starts here string = [string stringByReplacingOccurrencesOfString:@" " withString:@"/u00a0"]; UITextPosition *beginning = textField.beginningOfDocument; textField.text = [textField.text stringByReplacingCharactersInRange:range withString:string]; UITextPosition *start = [textField positionFromPosition:beginning offset:range.location+string.length]; UITextPosition *end = [textField positionFromPosition:start offset:range.length]; UITextRange *textRange = [textField textRangeFromPosition:start toPosition:end]; [textField setSelectedTextRange:textRange]; return NO; }


Resolví este problema en mi aplicación utilizando un campo de texto alineado a la izquierda y luego utilicé AutoLayout para alinear todo el campo de texto a la derecha. Esto simula un campo de texto alineado a la derecha y maneja los espacios finales sin jugar con los caracteres espaciales, etc.

El principal obstáculo en este enfoque es que UITextField no actualiza su tamaño de contenido intrínseco a medida que cambia el texto. Para evitar esto, subclasé UITextField para calcular automáticamente el tamaño del contenido intrínseco a medida que cambia el texto. Aquí está mi subclase:

@implementation PLResizingTextField - (instancetype)init { self = [super init]; if(self) { [self addTarget:self action:@selector(invalidateIntrinsicContentSize) forControlEvents:UIControlEventEditingChanged]; } return self; } - (CGSize)intrinsicContentSize { CGSize size = [super intrinsicContentSize]; NSString *text = self.text.length ? self.text : self.placeholder; CGRect rect = [text boundingRectWithSize:CGSizeMake(CGFLOAT_MAX,CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:self.font} context:nil]; size.width = CGRectGetWidth(rect); return size; } @end

Y aquí hay un fragmento de mi código de diseño automático, usando la biblioteca PureLayout:

[textField autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:10]; [textField autoPinEdge:ALEdgeLeading toEdge:ALEdgeTrailing ofView:cell.textLabel withOffset:10 relation:NSLayoutRelationGreaterThanOrEqual]; [textField setContentHuggingPriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal];

Puntos importantes a tener en cuenta aquí:

  1. establecer contenido que abraza la prioridad en el campo de texto
  2. utilice una relación NSLayoutRelationGreaterThanOrEqual entre el borde izquierdo del campo de texto y la vista a la izquierda (o el borde izquierdo de la supervista).

Sería una especie de truco, pero si realmente necesitas eso para mirar el camino de iOS6, puedes reemplazar el espacio con el espacio sin interrupción tal como está escrito. Se trata de manera diferente. El código de ejemplo podría verse así:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { // only when adding on the end of textfield && it''s a space if (range.location == textField.text.length && [string isEqualToString:@" "]) { // ignore replacement string and add your own textField.text = [textField.text stringByAppendingString:@"/u00a0"]; return NO; } // for all other cases, proceed with replacement return YES; }

En caso de que no esté claro, textField:shouldChangeCharactersInRange:replacementString: es un método de protocolo UITextFieldDelegate , por lo que en su ejemplo, el método anterior estaría en el controlador de vista designado por [textField setDelegate:self] .

Si desea recuperar sus espacios habituales, obviamente también deberá recordar convertir el texto reemplazando las apariciones de @"/u00a0" con @" " al sacar la cadena del campo de texto.


Swift 4 versión:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool{ if var text = textField.text, range.location == text.count, string == " " { let noBreakSpace: Character = "/u{00a0}" text.append(noBreakSpace) textField.text = text return false } return true }


Tendrá que reemplazar los espacios normales con espacios sin interrupción . Lo mejor es activar una acción en un evento de cambio para esto:

  1. En algún lugar, agregue una acción para el evento UIControlEventEditingChanged en su campo de texto:

    [myTextField addTarget:self action:@selector(replaceNormalSpacesWithNonBreakingSpaces) forControlEvents:UIControlEventEditingChanged];

  2. A continuación, implemente el método replaceNormalSpacesWithNonBreakingSpaces :

    - (void)replaceNormalSpacesWithNonBreakingSpaces { self.text = [self.text stringByReplacingOccurrencesOfString:@" " withString:@"/u00a0"]; }

Esto es más seguro que usar textField:shouldChangeCharactersInRange:replacementString: porque si devuelve NO de este método, en realidad está diciendo que el texto especificado no debe modificarse. Esto provocará que los eventos de cambio (como IBActions textFieldEditingChanged: o el evento UIControlEventEditingChanged de UIControlEventEditingChanged ) no se UIControlEventEditingChanged .

Solucionarlo en todas partes:

Si desea esta solución para todos sus UITextFields, puede crear una category donde agregue estas acciones de evento cuando se inicie un UITextField. En el ejemplo a continuación, también cambio los espacios sin interrupción a espacios normales cuando finaliza la edición, de modo que los posibles problemas con los espacios sin interrupción no ocurrirán cuando los datos se usen en otro lugar. Tenga en cuenta que este ejemplo usa el método Swizzling para que se vea un poco raro, pero es correcto.

El archivo de encabezado:

// UITextField+RightAlignedNoSpaceFix.h #import <UIKit/UIKit.h> @interface UITextField (RightAlignedNoSpaceFix) @end

El archivo de implementación:

// UITextField+RightAlignedNoSpaceFix.m #import "UITextField+RightAlignedNoSpaceFix.h" @implementation UITextField (RightAlignedNoSpaceFix) static NSString *normal_space_string = @" "; static NSString *non_breaking_space_string = @"/u00a0"; +(void)load { [self overrideSelector:@selector(initWithCoder:) withSelector:@selector(initWithCoder_override:)]; [self overrideSelector:@selector(initWithFrame:) withSelector:@selector(initWithFrame_override:)]; } /** * Method swizzles the initWithCoder method and adds the space fix * actions. */ -(instancetype)initWithCoder_override:(NSCoder*)decoder { self = [self initWithCoder_override:decoder]; [self addSpaceFixActions]; return self; } /** * Method swizzles the initWithFrame method and adds the space fix * actions. */ -(instancetype)initWithFrame_override:(CGRect)frame { self = [self initWithFrame_override:frame]; [self addSpaceFixActions]; return self; } /** * Will add actions on the text field that will replace normal * spaces with non-breaking spaces, and replaces them back after * leaving the textfield. * * On iOS 7 spaces are not shown if they''re not followed by another * character in a text field where the text is right aligned. When we * use non-breaking spaces this issue doesn''t occur. * * While editing, the normal spaces will be replaced with non-breaking * spaces. When editing ends, the non-breaking spaces are replaced with * normal spaces again, so that possible problems with non-breaking * spaces won''t occur when the data is used somewhere else. */ - (void)addSpaceFixActions { [self addTarget:self action:@selector(replaceNormalSpacesWithNonBreakingSpaces) forControlEvents:UIControlEventEditingDidBegin]; [self addTarget:self action:@selector(replaceNormalSpacesWithNonBreakingSpaces) forControlEvents:UIControlEventEditingChanged]; [self addTarget:self action:@selector(replaceNonBreakingSpacesWithNormalSpaces) forControlEvents:UIControlEventEditingDidEnd]; } /** * Will replace normal spaces with non-breaking spaces. */ - (void)replaceNormalSpacesWithNonBreakingSpaces { self.text = [self.text stringByReplacingOccurrencesOfString:normal_space_string withString:non_breaking_space_string]; } /** * Will replace non-breaking spaces with normal spaces. */ - (void)replaceNonBreakingSpacesWithNormalSpaces { self.text = [self.text stringByReplacingOccurrencesOfString:non_breaking_space_string withString:normal_space_string]; } @end


Transformó la respuesta de Triazotan en Swift3.

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool{ if (range.location == textField.text?.characters.count && string == " ") { let noBreakSpace: Character = "/u{00a0}" textField.text = textField.text?.append(noBreakSpace) return false } return true }


Una vieja pregunta, pero todas las soluciones anteriores parecen demasiado complicadas. Aquí es cómo resolví el problema:

Me suscribí a dos eventos de campo de texto ->

  • TextFieldEditingDidBegin
  • TextFieldEditingEnded

En TextFieldEditingDidBegin, simplemente configuro textField.textAlignment a UITextAlignmentLeft. En TextFieldEditingEnded, establezco textField.textAlignment a UITextAlignmentRight.

Esto funcionó perfectamente para mí y siento que no es un truco. ¡Espero eso ayude!