Tengo problemas con mi código. Estoy tratando de mover UIScrollView
cuando estoy editando un elemento UITextField
que debería estar oculto por la ventana emergente del teclado.
Estoy moviendo el marco principal en este momento porque no sé cómo 'desplazarme hacia arriba' en el código. Entonces, hice un poco de código, está funcionando bien, pero cuando edito un campo de texto de la interfaz de usuario y cambio a otro UITextField
sin presionar el botón 'regresar', la vista principal va muy arriba.
Hice una NSLog()
con mis variables tamaño, distancia y textFieldRect.origin.y como puede ver a continuación. Cuando pongo dos UITextField
en el mismo lugar (origen y) y hago este 'cambio' en particular (sin presionar retorno), obtengo los mismos números, mientras que mi código funcionó bien para la primera UITextField
edición pero no para la segunda edición.
Mira esto:
- (void)textFieldDidBeginEditing:(UITextField *)textField {
{
int size;
CGRect textFieldRect = [self.view.window convertRect:textField.bounds fromView:textField];
size = textFieldRect.origin.y + textFieldRect.size.height;
if (change == FALSE)
{
size = size - distance;
}
if (size < PORTRAIT_KEYBOARD_HEIGHT)
{
distance = 0;
}
else if (size > PORTRAIT_KEYBOARD_HEIGHT)
{
distance = size - PORTRAIT_KEYBOARD_HEIGHT + 5; // +5 px for more visibility
}
NSLog(@"origin %f", textFieldRect.origin.y);
NSLog(@"size %d", size);
NSLog(@"distance %d", distance);
CGRect viewFrame = self.view.frame;
viewFrame.origin.y -= distance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
change = FALSE;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
change = TRUE;
CGRect viewFrame = self.view.frame;
viewFrame.origin.y += distance;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:KEYBOARD_ANIMATION_DURATION];
[self.view setFrame:viewFrame];
[UIView commitAnimations];
}
Algunas ideas ?
fuente
activeField.frame
a un marco relativo, yaactiveField
que no tiene que ser un hijo inmediatoself.view
. El código actualizado debería verse así:CGRect aRect = self.view.frame; aRect.size.height -= kbSize.height; CGRect relativeFieldFrame = [activeField convertRect:activeField.frame toView:self.view]; if (!CGRectContainsPoint(aRect, relativeFieldFrame.origin) ) { CGPoint scrollPoint = CGPointMake(0.0, relativeFieldFrame.origin.y-kbSize.height); [self.mainView.scrollView setContentOffset:scrollPoint animated:YES]; }
UIKeyboardFrameEndUserInfoKey
clave en iOS 11 porque aUIKeyboardFrameBeginUserInfoKey
menudo me daría una altura de cero.Acabo de implementar esto con Swift 2.0 para iOS9 en Xcode 7 (beta 6), funciona bien aquí.
Editado para Swift 3
Parece que solo necesita configurar
contentInset
yscrollIndicatorInset
con Swift 3, el desplazamiento / contentOffset se realiza automáticamente ...fuente
Todas las respuestas aquí parecen olvidarse de las posibilidades del paisaje. Si desea que esto funcione cuando el dispositivo se gira a una vista horizontal, tendrá problemas.
El truco aquí es que, aunque la vista es consciente de la orientación, el teclado no. Esto significa que en Horizontal, el ancho del teclado es realmente su altura y viceversa.
Para modificar la forma recomendada de Apples para cambiar las inserciones de contenido y lograr que admita la orientación horizontal, recomendaría usar lo siguiente:
La parte a la que hay que prestar atención aquí es la siguiente:
Lo que hace es detectar en qué orientación se encuentra el dispositivo. Si es horizontal, "intercambiará" los valores de ancho y alto de la variable keyboardSize para garantizar que se estén utilizando los valores correctos en cada orientación.
fuente
Solución Swift 4 :
fuente
UIKeyboardFrameBeginUserInfoKey
aUIKeyboardFrameEndUserInfoKey
UIKeyboardWillShow
,UIKeyboardWillHide
YUIKeyboardFrameBeginUserInfoKey
han sido renombrados aUIResponder.keyboardWillShowNotification
,UIResponder.keyboardWillHideNotification
yUIResponder.keyboardFrameBeginUserInfoKey
.Para estas cosas, no es necesario codificar mucho, es muy fácil como el siguiente código: -
todo su texto archivado en UIScrollview desde nib como esta imagen: -
YourViewController.h
conecte IBOutlet desde nib y también conecte cada delegado de UItextfiled y delegado de scrollview desde NIB
NOTA si el delegado archivado por texto no está conectado, entonces ningún método funciona, asegúrese de que todo iBOulate y delegado estén conectados correctamente
fuente
La recomendación de Apple recodificada en Swift + Usando UIScrollView con Auto Layout en iOS (basándose en estos siguientes enlaces: enlace 1 , enlace 2 , enlace 3 ):
fuente
Lo único que actualizaría en el código de Apple es el método keyboardWillBeHidden: para proporcionar una transición suave.
fuente
Aquí hay una respuesta compatible con Swift 3 , que también funcionará con controladores de vista dentro de un controlador de navegación, ya que cambiarán la
contentInset.top
propiedad de vistas de desplazamiento .fuente
Solución Swift 4.2 que tiene en cuenta las posibles alturas de UIToolbar y UITabBar.
Y, si tiene como objetivo <iOS 9, debe cancelar el registro del observador en algún momento (gracias Joe )
fuente
Descubrí que las respuestas anteriores están desactualizadas. Tampoco es perfecto cuando se desplaza.
Aquí tienes una versión rápida.
Se desplazará justo debajo del campo de texto, sin espacio libre. Y se restaurará a la forma en que era como apareció por primera vez.
fuente
Esto es lo que he estado usando. Es simple y funciona bien.
Use la
UITextField
llamada de delegadotextFieldDidBeginEditing:
para cambiar su vista hacia arriba, y también agregue un observador de notificación para regresar la vista a la normalidad cuando el teclado se oculta:fuente
Este es el código final con mejoras en Swift
fuente
Una de las soluciones más sencillas es utilizar el siguiente protocolo:
Cuando desee utilizar este protocolo, solo debe ajustarse a él y asignar su vista de desplazamiento en su controlador de la siguiente manera:
fuente
Yo haría eso así. Es mucho código, pero asegura que el campo de texto actualmente en foco está centrado verticalmente en el 'espacio disponible':
Tenga en cuenta que la
- (IBAction)textFieldGotFocus:
acción está conectada a cada campo de textoDidBeginEditing
estado de .Además, sería un poco mejor obtener la duración de la animación de la notificación del teclado y usarla para la animación de vista de desplazamiento en lugar de un valor fijo, pero demándame, esto fue lo suficientemente bueno para mí;)
fuente
Use la siguiente extensión si no desea calcular demasiado:
Y tal vez desee mantener su UITextField siempre visible:
fuente
Prueba este código en Swift 3:
fuente
Solución Swift 5 basada en la solución de Masa anterior: cambios en relación con ella:
keyboardFrameEndUserInfoKey
lugar dekeyboardFrameBeginUserInfoKey
, porquekeyboardFrameBeginUserInfoKey
puede en la primera demostración devolver otro valor como se describe, por ejemplo, aquí: la altura del teclado varía cuando apareceUIResponder.keyboardWillShowNotification
/ enUIResponder.keyboardWillHideNotification
lugar deNSNotification.Name.UIKeyboardDidShow
/NSNotification.Name.UIKeyboardDidHide
Código:
fuente
En realidad, no necesita un UIScrollView para hacer esto. Usé este código y me funciona:
fuente
Puede desplazarse utilizando la propiedad
contentOffset
enUIScrollView
, por ejemplo,También hay un método para realizar un desplazamiento animado.
En cuanto a la razón por la que su segunda edición no se desplaza correctamente, podría deberse a que parece suponer que aparecerá un nuevo teclado cada vez que comience la edición. Puede intentar verificar si ya se ha ajustado para la posición visible del "teclado" (y también verificar la visibilidad del teclado en el momento antes de revertirla).
Una mejor solución podría ser escuchar la notificación del teclado, por ejemplo:
fuente
Sé que ahora es una vieja pregunta, pero pensé que podría ayudar a otros. Quería algo un poco más fácil de implementar para algunas aplicaciones que tenía, así que hice una clase para esto. Puede descargarlo aquí si lo desea: https://github.com/sdernley/iOSTextFieldHandler
Es tan simple como configurar todos los UITextFields para tener un delegado propio
Y luego agregue esto a su controlador de vista con el nombre de su scrollView y el botón de envío
fuente
Las siguientes son mis soluciones que funcionan (5 pasos)
Paso 1: agregue un observador para capturar qué UITEXTFIELD o UITEXTVIEW ShoudBeginEditing (donde se inicia el objeto o ViewDidLoad.
Paso 2: Publique una notificación cuando ... Debería comenzar a editar con OBJECT de UITEXTFIELD o UITEXTVIEW
Step3: El método que (Step1 calles) asigna el UITEXTFIELD o UITEXTVIEW actual
Paso 4: agregue el observador de teclado UIKeyboardWillShowNotification (mismo lugar que el paso 1)
y método:
Paso 5: agregue el observador de teclado UIKeyboardWillHideNotification (mismo lugar que el paso 1)
y método:
¡Recuerda eliminar a los observadores!
fuente
Usé esta respuesta proporcionada por Sudheer Palchuri https://stackoverflow.com/users/2873919/sudheer-palchuri https://stackoverflow.com/a/32583809/6193496
En ViewDidLoad, registre las notificaciones:
Agregue los siguientes métodos de observador que realizan el desplazamiento automático cuando aparece el teclado.
fuente
Mi solución tiene 4 pasos:
- Paso 1: la función escucha cuando aparece el teclado
- Paso 2: la función escucha cuando desaparece el teclado
- Paso 3: agregue estas funciones al centro de notificaciones:
- Paso 4: eliminar escuchar cuando el controlador de vista desaparece
fuente