ios - pickerview - Ocultar el cursor de un UITextField
uitextfield picker (13)
Estoy utilizando un UITextField
con un UIPickerView
para su inputView
, de modo que cuando el usuario toque el campo de texto, se convoque un selector para que seleccione una opción.
Casi todo funciona, pero tengo un problema: el cursor todavía parpadea en el campo de texto cuando está activo, lo que es feo e inapropiado, ya que no se espera que el usuario escriba en el campo y no se presente con un teclado. Sé que podría resolver esto de forma hackosa estableciendo la editing
en NO
en el campo de texto y haciendo un seguimiento de los toques, o reemplazándolo con un botón de estilo personalizado, y convocando al selector por código. Sin embargo, quiero utilizar los métodos UITextFieldDelegate
para todo el manejo de eventos en el campo de texto y los hacks como reemplazar el campo de texto con un botón no permiten este enfoque.
¿Cómo puedo simplemente ocultar el cursor en el UITextField
en UITextField
lugar?
A partir de iOS 7, ahora puede establecer el tintColor = [UIColor clearColor]
en el campo de texto y el símbolo de intercalación desaparecerá.
Es posible que también desee evitar que el usuario seleccione, copie o pegue cualquier texto para que la única entrada de texto provenga de la vista del selector.
- (CGRect) caretRectForPosition:(UITextPosition*) position
{
return CGRectZero;
}
- (NSArray *)selectionRectsForRange:(UITextRange *)range
{
return nil;
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (action == @selector(copy:) || action == @selector(selectAll:) || action == @selector(paste:))
{
returnNO;
}
return [super canPerformAction:action withSender:sender];
}
http://b2cloud.com.au/tutorial/disabling-the-caret-and-text-entry-in-uitextfields/
Para deshabilitar el cursor y el menú utilizo la subclase con estos 2 métodos:
- (CGRect)caretRectForPosition:(UITextPosition *)position {
return CGRectZero;
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
[UIMenuController sharedMenuController].menuVisible = NO;
self.selectedTextRange = nil;
return NO;
}
Puede agregar una propiedad sin BOOL cursorless
a UITextField
en una categoría a través de objetos asociados.
@interface UITextField (Cursorless)
@property (nonatomic, assign) BOOL cursorless;
@end
A continuación, utilice el método swizzling para swizzle caretRectForPosition:
con un método que alterna entre CGRectZero
y su valor predeterminado utilizando cursorless
.
Esto lleva a una interfaz simple a través de una categoría de acceso directo. Esto se demuestra en los siguientes archivos.
Simplemente colóquelos y obtenga el beneficio de esta interfaz simple
Categoría UITextField
: https://github.com/rexmas/RexDK/blob/master/RexDK/UI/UITextField%2BRXCursorless.h https://github.com/rexmas/RexDK/blob/master/RexDK/UI/UITextField%2BRXCursorless.m
Método Swizzling: https://github.com/rexmas/RexDK/blob/master/RexDK/Foundation/NSObject%2BRXRuntimeAdditions.h https://github.com/rexmas/RexDK/blob/master/RexDK/Foundation/NSObject%2BRXRuntimeAdditions.m
Puedes borrar el tinteColor del campo de texto
self.textField.tintColor = [UIColor clearColor];
Swift 3.0
self.textField.tintColor = .clear
Si quiere ocultar el cursor, ¡puede usarlo fácilmente! Funcionó para mí ...
[[textField valueForKey:@"textInputTraits"] setValue:[UIColor clearColor] forKey:@"insertionPointColor"]
Simplemente la subclase UITextField y reemplaza caretRectForPosition
- (CGRect)caretRectForPosition:(UITextPosition *)position
{
return CGRectZero;
}
Simplemente subclases UITextField
y layoutSubviews
siguiente manera:
- (void)layoutSubviews
{
[super layoutSubviews];
for (UIView *v in self.subviews)
{
if ([[[v class] description] rangeOfString:@"UITextSelectionView"].location != NSNotFound)
{
v.hidden = YES;
}
}
}
Es un truco sucio y puede fallar en el futuro (momento en el que el cursor volverá a estar visible, tu aplicación no se bloqueará), pero funciona.
Swift 3 versión de la publicación de Net
override func caretRect(for position: UITextPosition) -> CGRect {
return .zero
}
override func selectionRects(for range: UITextRange) -> [Any] {
return []
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return false
}
Verifique la propiedad selectedTextRange
del protocolo UITextInput
, al cual se ajusta la clase UITextField
. ¡Pocos! Esa es una lección de programación orientada a objetos allí mismo.
Ocultar Caret
Para ocultar el símbolo de intercalación, anule el campo de texto seleccionado del campo de texto.
textField.selectedTextRange = nil; // hides caret
Mostrar Caret
Aquí hay dos maneras de mostrar el cursor.
Establezca el rango de texto seleccionado del campo de texto al final del documento.
UITextPosition *end = textField.endOfDocument; textField.selectedTextRange = [textField textRangeFromPosition:end toPosition:end];
Para mantener el cursor en el mismo lugar, primero, almacene el rango de texto seleccionado del campo de texto en una variable de instancia.
_textFieldSelectedTextRange = textField.selectedTextRange; textField.selectedTextRange = nil; // hides caret
Luego, cuando desee mostrar el símbolo de intercalación, simplemente configure el campo de texto seleccionado del campo de texto como originalmente.
textField.selectedTextRange = _textFieldSelectedTextRange; _textFieldLastSelectedTextRange = nil;
establecer el tintColor para borrar el color
textfield.tintColor = [UIColor clearColor];
y también puedes configurar desde el constructor de interfaz
Respuesta proporcionada por el OP, copiada del cuerpo de la pregunta para ayudar a limpiar la cola cada vez mayor de preguntas sin respuesta.
Creo que tengo la solución correcta pero si se puede mejorar será bienvenida :) Bueno, hice una subclase de UITextField y anulé el método que devuelve el CGRect para los límites
-(CGRect)textRectForBounds:(CGRect)bounds {
return CGRectZero;
}
¿El problema? El texto no se muestra porque el rect es cero. Pero agregué un UILabel como una subvista del control y anulé el método setText así que, cuando ingresamos un texto como de costumbre, el texto del campo de texto es nulo y es la etiqueta que muestra el texto
- (void)setText:(NSString *)aText {
[super setText:nil];
if (aText == nil) {
textLabel_.text = nil;
}
if (![aText isEqualToString:@""]) {
textLabel_.text = aText;
}
}
Con esto, la cosa funciona como se esperaba. ¿Conoces alguna forma de mejorarlo?
Respuesta proporcionada por el OP, copiada del cuerpo de la pregunta para ayudar a limpiar la cola cada vez mayor de preguntas sin respuesta.
Encontré otra solución: subclase UIButton
y UIButton
estos métodos
- (UIView *)inputView {
return inputView_;
}
- (void)setInputView:(UIView *)anInputView {
if (inputView_ != anInputView) {
[inputView_ release];
inputView_ = [anInputView retain];
}
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
Ahora el botón, como un UIResponder
, tiene un comportamiento similar al de UITextField
y una implementación bastante sencilla.