Con el SDK de iOS:
Tengo una UIViewcon UITextFields que muestra un teclado. Lo necesito para poder:
Permita el desplazamiento del contenido del
UIScrollViewpara 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 UIViewa a UIScrollViewpero todavía no puedo desplazar los cuadros de texto hacia arriba o hacia abajo.
¿Necesito tanto a UIViewcomo 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 UIScrollViewcuando 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
ScrollViewsi los contenidos que tiene ahora no caben en la pantalla del iPhone. (Si está agregando elScrollViewcomo la supervista de los componentes solo paraTextFielddesplazarse hacia arriba cuando aparece el teclado, entonces no es necesario).La forma estándar de evitar que el
TextFieldteclado 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
textFieldDidBeginEditingsección.También tenía muchos problemas con la
UIScrollViewcomposició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
UIScrollViewdesplazamiento no es correcto.1) Asegúrese de que su contentSize sea mayor que el
UIScrollViewtamaño del marco. La forma de entenderUIScrollViewses queUIScrollViewes como una ventana de visualización del contenido definido en contentSize. Por lo tanto, cuando seUIScrollviewdesplaza 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
UIScrollViewrealmente 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 deUIScrollViewmodo que cuando el teclado esté presente, tenga laUIScrollViewventana dimensionado solo alUIScrollViewframe.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
CGRectde texto editado y llamarUIScrollView'sal método scrollRecToVisible. Implementé elUITextFieldDelegatemétodotextFieldDidBeginEditingcon la llamada alscrollRecToVisiblemétodo. En realidad, esto trabajó con un efecto secundario raro que el desplazamiento sería romper laUITextFielden su posición. Durante mucho tiempo no pude entender qué era. ¡Entonces comenté eltextFieldDidBeginEditingmétodo Delegate y todo funciona! (???). Al final resultó que, creo que laUIScrollViewrealidad trae implícitamente lo editado actualmenteUITextFielden la ventana visible de forma implícita. Mi implementación delUITextFieldDelegatemétodo y la posterior llamada alscrollRecToVisiblefue redundante y fue la causa del extraño efecto secundario.Así que aquí están los pasos para desplazarlo correctamente
UITextFielden suUIScrollViewlugar cuando aparezca el teclado.viewDidLoadviewDidUnloadcontentSizese establece y mayor que elUIScrollViewdeviewDidLoadUIScrollViewcuando el teclado está presenteUIScrollViewcuando el teclado desaparece.UITextFieldse presiona a incluso si el teclado ya está presente para evitar reducir el tamañoUIScrollViewcuando ya está encogido.Una cosa a tener en cuenta es que se
UIKeyboardWillShowNotificationactivará incluso cuando el teclado ya esté en la pantalla cuando presionas otroUITextField. Me ocupé de esto usando un ivar para evitar cambiar el tamañoUIScrollViewcuando el teclado ya está en la pantalla. ¡Cambiar de tamaño inadvertidamenteUIScrollViewcuando el teclado ya está allí sería desastroso!Espero que este código les ahorre muchos dolores de cabeza.
fuente
UIKeyboardBoundsUserInfoKeyestá 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].sizedeberí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
contentOffsetla altura que es visible en la pantalla, no lo que no es):fuente
UIKeyboardFrameEndUserInfoKeylugar deUIKeyboardFrameBeginUserInfoKeyobtener 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
textFieldDidBeginEdittingy intextFieldDidEndEditingcall 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
UITextFieldDelegate3) Establecer cada uno
textField.delegate = self;(o hacer conexionesInterface Builder)4) Copiar / Pegar:
fuente
textFieldya 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,UITextViewyUIKeyboarden una clase Singleton. Lo llamo IQKeyboardManager .Paso 2: - Si se encuentran
UIKeyboardWillShowNotification,UITextFieldTextDidBeginEditingNotificationoUITextViewTextDidBeginEditingNotificationnotificaciones, trato de obtener unatopMostViewControllerinstancia de laUIWindow.rootViewControllerjerarquía. Con el fin de destapar adecuadamenteUITextField/UITextViewen él,topMostViewController.view's marco necesita ser ajustado.Paso 3: - Calculé la distancia de movimiento esperada
topMostViewController.viewcon respecto a la primera respuestaUITextField/UITextView.Paso 4: - Me moví
topMostViewController.view.framehacia arriba / abajo según la distancia de movimiento esperada.Paso 5: - Si se encuentra
UIKeyboardWillHideNotification,UITextFieldTextDidEndEditingNotificationoUITextViewTextDidEndEditingNotificationnotificación, nuevamente intento obtener unatopMostViewControllerinstancia de laUIWindow.rootViewControllerjerarquía.Paso 6: - Calculé la distancia perturbada de la
topMostViewController.viewcual debe restaurarse a su posición original.Paso 7: - Me restaure de
topMostViewController.view.frameacuerdo 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/UITextViewen 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,UITableViewe inclusoUICollectionViewsubclase 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
UITableViewinterfaz 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
UITextFieldDelegatecolóquelos en su clase de controlador de vista e implemente el en su controlador de vista y configure el delegado de textField enselfImplemente 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 lasendActionimplementació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 llamarscrollRectToVisibleexplícitamente (al menos desde IOS 11).Una cosa a tener en cuenta es si alguna vez quieres usar un
UITextFieldsolo. No he encontrado ninguna aplicación para iPhone bien diseñada que realmente useUITextFieldsfuera deUITableViewCells.Será un trabajo adicional, pero le recomiendo que implemente todas las vistas de entrada de datos y vistas de tabla. Agrega un
UITextViewa tuUITableViewCells.fuente
UITableViewEs 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
UIKeyboardWillHideNotificationlugar 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 lakeyboardvariable 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.ytrabajando 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'svista 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 deUIViewControllerque 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
viewWillAppearyviewWillDisappeardeben llamar a super). La clase está en github .fuente
Rápido 4 .
Fácilmente puede moverse arriba y abajo
UITextFieldOUIViewConUIKeyBoardConAnimationfuente
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
UITableViewControllerclase 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 unUITableViewCellcomo 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.hejemplo al final del tutorial, asegúrese de poner un espacio encomo ves.
fuente
Cuando
UITextFieldestá en unUITableViewCelldesplazamiento 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
UITextFielden 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
viewWillAppearno se llama. YreloadDatano 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
IQKeyboardManagersu proyecto. Si encuentra algún problema, lea elREADMEdocumento.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