Con el SDK de iOS:
Tengo una UIView
con UITextField
s que muestra un teclado. Lo necesito para poder:
Permita el desplazamiento del contenido del
UIScrollView
para ver los otros campos de texto una vez que aparezca el tecladoAutomáticamente "salta" (desplazándose hacia arriba) o acorta
Sé que necesito a UIScrollView
. Intenté cambiar la clase de mi UIView
a a UIScrollView
pero todavía no puedo desplazar los cuadros de texto hacia arriba o hacia abajo.
¿Necesito tanto a UIView
como a UIScrollView
? ¿Uno va dentro del otro?
¿Qué debe implementarse para desplazarse automáticamente al campo de texto activo?
Idealmente, la mayor parte posible de la configuración de los componentes se realizará en Interface Builder. Me gustaría escribir solo código para lo que lo necesita.
Nota: el UIView
(o UIScrollView
) con el que estoy trabajando aparece en una barra de pestañas ( UITabBar
), que debe funcionar normalmente.
Editar: estoy agregando la barra de desplazamiento solo cuando aparece el teclado. Aunque no es necesario, creo que proporciona una mejor interfaz porque, por ejemplo, el usuario puede desplazarse y cambiar cuadros de texto.
Lo tengo funcionando donde cambio el tamaño del cuadro UIScrollView
cuando el teclado sube y baja. Simplemente estoy usando:
-(void)textFieldDidBeginEditing:(UITextField *)textField {
//Keyboard becomes visible
scrollView.frame = CGRectMake(scrollView.frame.origin.x,
scrollView.frame.origin.y,
scrollView.frame.size.width,
scrollView.frame.size.height - 215 + 50); //resize
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
//keyboard will hide
scrollView.frame = CGRectMake(scrollView.frame.origin.x,
scrollView.frame.origin.y,
scrollView.frame.size.width,
scrollView.frame.size.height + 215 - 50); //resize
}
Sin embargo, esto no "sube" o centra automáticamente los campos de texto inferiores en el área visible, que es lo que realmente me gustaría.
fuente
Respuestas:
Solo necesitará un
ScrollView
si los contenidos que tiene ahora no caben en la pantalla del iPhone. (Si está agregando elScrollView
como la supervista de los componentes solo paraTextField
desplazarse hacia arriba cuando aparece el teclado, entonces no es necesario).La forma estándar de evitar que el
TextField
teclado cubra los correos electrónicos es mover la vista hacia arriba / abajo cada vez que se muestra el teclado.Aquí hay un código de muestra:
fuente
textFieldDidBeginEditing
sección.También tenía muchos problemas con la
UIScrollView
composición de múltiplesUITextFields
, de los cuales, uno o más de ellos se oscurecían con el teclado cuando se editaban.Aquí hay algunas cosas a tener en cuenta si su
UIScrollView
desplazamiento no es correcto.1) Asegúrese de que su contentSize sea mayor que el
UIScrollView
tamaño del marco. La forma de entenderUIScrollViews
es queUIScrollView
es como una ventana de visualización del contenido definido en contentSize. Por lo tanto, cuando seUIScrollview
desplaza a cualquier lugar, contentSize debe ser mayor queUIScrollView
. De lo contrario, no se requiere desplazamiento ya que todo lo definido en contentSize ya está visible. Por cierto, por defecto contentSize =CGSizeZero
.2) Ahora que comprende que
UIScrollView
realmente es una ventana a su "contenido", la forma de asegurarse de que el teclado no oculte suUIScrollView's
"ventana" de visualización sería cambiar el tamaño deUIScrollView
modo que cuando el teclado esté presente, tenga laUIScrollView
ventana dimensionado solo alUIScrollView
frame.size.height original menos la altura del teclado. Esto asegurará que su ventana sea solo esa pequeña área visible.3) Aquí está el truco: cuando implementé esto por primera vez, pensé que tendría que obtener el campo
CGRect
de texto editado y llamarUIScrollView's
al método scrollRecToVisible. Implementé elUITextFieldDelegate
métodotextFieldDidBeginEditing
con la llamada alscrollRecToVisible
método. En realidad, esto trabajó con un efecto secundario raro que el desplazamiento sería romper laUITextField
en su posición. Durante mucho tiempo no pude entender qué era. ¡Entonces comenté eltextFieldDidBeginEditing
método Delegate y todo funciona! (???). Al final resultó que, creo que laUIScrollView
realidad trae implícitamente lo editado actualmenteUITextField
en la ventana visible de forma implícita. Mi implementación delUITextFieldDelegate
método y la posterior llamada alscrollRecToVisible
fue redundante y fue la causa del extraño efecto secundario.Así que aquí están los pasos para desplazarlo correctamente
UITextField
en suUIScrollView
lugar cuando aparezca el teclado.viewDidLoad
viewDidUnload
contentSize
se establece y mayor que elUIScrollView
deviewDidLoad
UIScrollView
cuando el teclado está presenteUIScrollView
cuando el teclado desaparece.UITextField
se presiona a incluso si el teclado ya está presente para evitar reducir el tamañoUIScrollView
cuando ya está encogido.Una cosa a tener en cuenta es que se
UIKeyboardWillShowNotification
activará incluso cuando el teclado ya esté en la pantalla cuando presionas otroUITextField
. Me ocupé de esto usando un ivar para evitar cambiar el tamañoUIScrollView
cuando el teclado ya está en la pantalla. ¡Cambiar de tamaño inadvertidamenteUIScrollView
cuando el teclado ya está allí sería desastroso!Espero que este código les ahorre muchos dolores de cabeza.
fuente
UIKeyboardBoundsUserInfoKey
está en desuso. 2. keyboardSize está en "coordenadas de pantalla", por lo que sus cálculos de viewFrame fallarán si el marco se gira o se escala.CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
lugar de obsoletoUIKeyboardBoundsUserInfoKey
[[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size
debería ser[[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size
. ¡Gran solución sin embargo!En realidad, es mejor usar la implementación de Apple, como se proporciona en los documentos . Sin embargo, el código que proporcionan es defectuoso. Reemplace la parte que se encuentra
keyboardWasShown:
justo debajo de los comentarios a lo siguiente:Los problemas con el código de Apple son los siguientes: (1) Siempre calculan si el punto está dentro del marco de la vista, pero es un
ScrollView
, por lo que es posible que ya se haya desplazado y que deba tener en cuenta ese desplazamiento:(2) Cambian el contenido Offset por la altura del teclado, pero queremos lo contrario (queremos cambiar
contentOffset
la altura que es visible en la pantalla, no lo que no es):fuente
UIKeyboardFrameEndUserInfoKey
lugar deUIKeyboardFrameBeginUserInfoKey
obtener el tamaño del teclado, ya que esto recogerá cosas como los cambios personalizados del teclado y la activación / desactivación del texto predictivo.self.scrollView.contentOffset = self.currentSVoffset;
In
textFieldDidBeginEditting
y intextFieldDidEndEditing
call la función[self animateTextField:textField up:YES]
así:Espero que este código te ayude.
En Swift 2
SWIFT 3
fuente
[UIView animateWithDuration: animations:^{ }];
?Solo usando TextFields:
1a) Uso
Interface Builder
: Seleccione All TextFields => Edit => Embed In => ScrollView1b) Incruste manualmente TextFields en UIScrollView llamado scrollView
2) Establecer
UITextFieldDelegate
3) Establecer cada uno
textField.delegate = self;
(o hacer conexionesInterface Builder
)4) Copiar / Pegar:
fuente
textField
ya es visible.CGPointMake(0, textField.frame.origin.y);
aCGPointMake(0, textField.frame.origin.y + scrollView.contentInset.top);
Para Universal Solution , aquí estaba mi enfoque para implementar IQKeyboardManager .
Paso 1: - añadí notificaciones globales de
UITextField
,UITextView
yUIKeyboard
en una clase Singleton. Lo llamo IQKeyboardManager .Paso 2: - Si se encuentran
UIKeyboardWillShowNotification
,UITextFieldTextDidBeginEditingNotification
oUITextViewTextDidBeginEditingNotification
notificaciones, trato de obtener unatopMostViewController
instancia de laUIWindow.rootViewController
jerarquía. Con el fin de destapar adecuadamenteUITextField
/UITextView
en él,topMostViewController.view
's marco necesita ser ajustado.Paso 3: - Calculé la distancia de movimiento esperada
topMostViewController.view
con respecto a la primera respuestaUITextField
/UITextView
.Paso 4: - Me moví
topMostViewController.view.frame
hacia arriba / abajo según la distancia de movimiento esperada.Paso 5: - Si se encuentra
UIKeyboardWillHideNotification
,UITextFieldTextDidEndEditingNotification
oUITextViewTextDidEndEditingNotification
notificación, nuevamente intento obtener unatopMostViewController
instancia de laUIWindow.rootViewController
jerarquía.Paso 6: - Calculé la distancia perturbada de la
topMostViewController.view
cual debe restaurarse a su posición original.Paso 7: - Me restaure de
topMostViewController.view.frame
acuerdo con la distancia perturbada.Paso 8: - Ejecuté la instancia de clase IQKeyboardManager singleton en la carga de la aplicación, por lo que cada
UITextField
/UITextView
en la aplicación se ajustará automáticamente de acuerdo con la distancia de movimiento esperada.¡Eso es todo lo que IQKeyboardManager hace por usted SIN NINGUNA LÍNEA DE CÓDIGO realmente! solo necesita arrastrar y soltar el archivo fuente relacionado al proyecto. IQKeyboardManager también es compatible con la Orientación del dispositivo , la Gestión automática de UIToolbar , KeybkeyboardDistanceFromTextField y mucho más de lo que piensas.
fuente
He reunido un universal, sin cita
UIScrollView
,UITableView
e inclusoUICollectionView
subclase que se encarga de mover todos los campos de texto dentro de ella fuera del camino del teclado.Cuando el teclado está a punto de aparecer, la subclase encontrará la subvista que está a punto de editarse, y ajustará el marco y el desplazamiento del contenido para asegurarse de que la vista sea visible, con una animación que coincida con la ventana emergente del teclado. Cuando el teclado desaparece, restaura su tamaño anterior.
Debería funcionar básicamente con cualquier configuración, ya sea una
UITableView
interfaz basada en o una que consista en vistas colocadas manualmente.Aquí está: solución para mover campos de texto fuera del camino del teclado
fuente
Esto hará todo por usted, simplemente
UITextFieldDelegate
colóquelos en su clase de controlador de vista e implemente el en su controlador de vista y configure el delegado de textField enself
Implemente los métodos de devolución de llamada delegados:
Para Swift 4, 4.2, 5: Cambiar
a
Última nota sobre esta implementación: si inserta otro controlador de vista en la pila mientras se muestra el teclado, esto creará un error en el que la vista vuelve a su marco central pero el desplazamiento del teclado no se restablece. Por ejemplo, su teclado es el primer respondedor para nameField, pero luego presiona un botón que empuja su Controlador de vista de ayuda a su pila. Para corregir el error de desplazamiento, asegúrese de llamar a nameField.resignFirstResponder () antes de abandonar el controlador de vista, asegurándose de que también se llame al método delegado textFieldDidEndEditing. Hago esto en el método viewWillDisappear.
fuente
self.view.frame = CGRectOffset(self.view.frame, 0, movement)
así que cambié esa línea aself.view.frame.offsetInPlace(dx: 0, dy: movement)
Ya hay muchas respuestas, pero ninguna de las soluciones anteriores tenía todo el material de posicionamiento necesario para una animación "perfecta" sin errores, compatible con versiones anteriores y sin parpadeos. (error al animar el marco / límites y el contenido Offset juntos, diferentes orientaciones de interfaz, teclado dividido iPad, ...)
Permítanme compartir mi solución:
(suponiendo que haya configurado
UIKeyboardWill(Show|Hide)Notification
)fuente
UIApplication.shared.sendAction(...)
. Aquí está la versión de Swift 3 de su respuesta (menos la porción deHideHide), con lasendAction
implementación: gist.github.com/xaphod/7aab1302004f6e933593a11ad8f5a72dShiun dijo "Al final resultó que, creo que UIScrollView en realidad trae implícitamente el UITextField actualmente editado a la ventana visible" Esto parece ser cierto para iOS 3.1.3, pero no 3.2, 4.0 o 4.1. Tuve que agregar un scrollRectToVisible explícito para hacer visible el UITextField en iOS> = 3.2.
fuente
[UITextField scrollTextFieldToVisibleIfNecessary]
método privado que a su vez llama[UIScrollView scrollRectToVisible]
cuando[UITextField becomeFirstResponder]
se llama. Ver github.com/leopatras/ios_textfields_on_scrollview . Si las restricciones y los controladores de vista están configurados correctamente, en realidad no hay necesidad de llamarscrollRectToVisible
explícitamente (al menos desde IOS 11).Una cosa a tener en cuenta es si alguna vez quieres usar un
UITextField
solo. No he encontrado ninguna aplicación para iPhone bien diseñada que realmente useUITextFields
fuera deUITableViewCells
.Será un trabajo adicional, pero le recomiendo que implemente todas las vistas de entrada de datos y vistas de tabla. Agrega un
UITextView
a tuUITableViewCells
.fuente
UITableView
Es tristemente el único camino a seguir. Las notificaciones del teclado son frágiles y han cambiado las horas extraordinarias. Código de muestra en Stack Overflow: stackoverflow.com/a/32390936/218152Este documento detalla una solución a este problema. Mire el código fuente en 'Mover contenido que se encuentra debajo del teclado'. Es bastante sencillo.
EDITAR: Noté que hay un pequeño error en el ejemplo. Probablemente querrá escuchar en
UIKeyboardWillHideNotification
lugar deUIKeyboardDidHideNotification
. De lo contrario, la vista de desplazamiento detrás del teclado se recortará mientras dure la animación de cierre del teclado.fuente
La solución más fácil encontrada
fuente
int movement = (up ? -movementDistance : movementDistance);
if (textField.frame.origin.y < self.view.frame.size.height - keyboard.height) { movementDistance = 0 }
Por favor, no es que lakeyboard
variable sea el CGRect del teclado que aparece al hacerlo:let keyboard = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey]!.CGRectValue())!
Pequeña solución que funciona para muchos UITextFields
fuente
rect.origin.y=+currTextField.frame.origin.y
trabajando bien graciasEl código RPDP mueve con éxito el campo de texto fuera del camino del teclado. Pero cuando se desplaza hacia la parte superior después de usar y cerrar el teclado, la parte superior se ha desplazado hacia arriba fuera de la vista. Esto es cierto para el simulador y el dispositivo. Para leer el contenido en la parte superior de esa vista, uno tiene que volver a cargar la vista.
¿No se supone que su siguiente código reducirá la vista?
fuente
No estoy seguro de si mover la vista hacia arriba es el enfoque correcto, lo hice de una manera diferente, cambiando el tamaño del UIScrollView. Lo expliqué en detalle en un pequeño artículo.
fuente
Para volver al estado de vista original, agregue:
fuente
Prueba este pequeño truco.
fuente
Hay tantas soluciones, pero he pasado algunas horas antes de que comience a funcionar. Entonces, puse este código aquí (solo pegue en el proyecto, no es necesario realizar ninguna modificación):
PD: Espero que el código ayude a alguien a lograr el efecto deseado rápidamente. (Xcode 4.5)
fuente
@ user271753
Para que su vista vuelva al original, agregue:
fuente
No requiere una vista de desplazamiento para poder mover el marco de vista. Puede cambiar el marco de una
viewcontroller's
vista para que toda la vista se mueva hacia arriba lo suficiente como para colocar el campo de texto del primer respondedor sobre el teclado. Cuando me encontré con este problema, creé una subclase deUIViewController
que hace esto. Observa que el teclado aparecerá notificación y encuentra la primera subvista del respondedor y (si es necesario) anima la vista principal hacia arriba lo suficiente para que el primer respondedor esté por encima del teclado. Cuando el teclado se oculta, anima la vista donde estaba.Para usar esta subclase, haga que su controlador de vista personalizado sea una subclase de GMKeyboardVC y herede esta característica (solo asegúrese de implementar
viewWillAppear
yviewWillDisappear
deben llamar a super). La clase está en github .fuente
Rápido 4 .
Fácilmente puede moverse arriba y abajo
UITextField
OUIView
ConUIKeyBoard
ConAnimation
fuente
Aquí está la solución de hackeo que se me ocurrió para un diseño específico. Esta solución es similar a la solución de Matt Gallagher, ya que desplaza una sección a la vista. Todavía soy nuevo en el desarrollo de iPhone y no estoy familiarizado con el funcionamiento de los diseños. Por lo tanto, este truco.
Mi implementación necesitaba admitir el desplazamiento al hacer clic en un campo, y también el desplazamiento cuando el usuario selecciona el siguiente en el teclado.
Tuve una UIView con una altura de 775. Los controles se distribuyen básicamente en grupos de 3 en un espacio grande. Terminé con el siguiente diseño de IB.
Aquí viene el truco
Configuré la altura UIScrollView en 500 unidades más grande que el diseño real (1250). Luego creé una matriz con las posiciones absolutas a las que necesito desplazarme, y una función simple para obtenerlas en función del número de etiqueta IB.
Ahora todo lo que necesita hacer es usar las siguientes dos líneas de código en textFieldDidBeginEditing y textFieldShouldReturn (este último si está creando un próximo campo de navegación)
Un ejemplo.
Este método no se 'desplaza hacia atrás' como lo hacen otros métodos. Esto no fue un requisito. Nuevamente, esto fue para una UIView bastante 'alta', y no tuve días para aprender los motores de diseño interno.
fuente
Según los documentos , a partir de iOS 3.0, la
UITableViewController
clase cambia automáticamente el tamaño y vuelve a colocar su vista de tabla cuando hay una edición en línea de los campos de texto. Creo que no es suficiente poner el campo de texto dentro de unUITableViewCell
como algunos han indicado.De los documentos :
fuente
Solo necesita copiar y pegar debajo del código de muestra y cambiar su campo de texto o cualquier vista que desee subir.
Paso 1
Paso 2
Paso 3
Referencia : bueno, aprecia a este chico , que compartió este hermoso recorte de código, solución limpia.
Espero que esto sea muy útil para alguien por ahí.
fuente
He estado buscando un buen tutorial para principiantes sobre el tema, encontré el mejor tutorial aquí .
En el
MIScrollView.h
ejemplo al final del tutorial, asegúrese de poner un espacio encomo ves.
fuente
Cuando
UITextField
está en unUITableViewCell
desplazamiento debe configurarse automáticamente.Si no es así, probablemente se deba a un código / configuración incorrectos de la vista de tabla.
Por ejemplo, cuando volví a cargar mi tabla larga con una
UITextField
en la parte inferior de la siguiente manera,entonces mi campo de texto en la parte inferior estaba oscurecido por el teclado que apareció cuando hice clic dentro del campo de texto.
Para solucionar esto, tuve que hacer esto:
fuente
viewWillAppear
no se llama. YreloadData
no hace que las filas oscuras se vuelvan visibles.Use este tercero, no necesita escribir ni una sola línea
https://github.com/hackiftekhar/IQKeyboardManager
descargue el proyecto y arrastre y suelte
IQKeyboardManager
su proyecto. Si encuentra algún problema, lea elREADME
documento.Chicos realmente es eliminar el dolor de cabeza para administrar el teclado.
fuente
Nota : esta respuesta asume que su textField está en scrollView.
Prefiero lidiar con esto usando scrollContentInset y scrollContentOffset en lugar de jugar con los marcos de mi vista.
Primero escuchemos las notificaciones del teclado
El siguiente paso es mantener una propiedad que represente el primer respondedor actual (UITextfield / UITextVIew que actualmente tiene el teclado).
Usamos los métodos delegados para establecer esta propiedad. Si está utilizando otro componente, necesitará algo similar.
Tenga en cuenta que para textfield lo configuramos en didBeginEditing y para textView en shouldBeginEditing. Esto se debe a que se llama a textViewDidBeginEditing después de UIKeyboardWillShowNotification por algún motivo.
Finalmente, aquí está la magia.
fuente
Esta es la solución usando Swift.
fuente