2009-12-23 26 views
9

tengo un UIToolbar en el fondo de mi vista, y tengo un UITextField en esta barra de herramientas. Cuando comienzo a editar este campo, está oculto detrás del teclado. Para ver lo que he tipeado, quiero mover la barra de herramientas hacia arriba en el momento en que se presenta el teclado (y luego volver a moverla cuando termine de editar).moverse hacia arriba UIToolbar

¿Cómo puedo mover este UIToolbar arriba/abajo?

+0

duplicados de http://stackoverflow.com/questions/1247113/iphone-keyboard-covers-text-field/1533847#1533847 – cidered

+0

No es un duplicado. Esta pregunta es sobre la barra de herramientas, no sobre el campo de texto. – phatmann

Respuesta

13

agregue su clase viewController a la lista de observadores de UIKeyboardWillShowNotification/UIKeyboardWillHideNotification. luego puede mover su vista para hacer visible su textView. También puede obtener parámetros de animación de estas notificaciones para sincronizar su animación con los parámetros de animación del teclado de la versión actual del sistema operativo. el código que he usado para paginación

- (void) viewWillAppear:(BOOL)animated{ 
    [super viewWillAppear:animated]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(liftMainViewWhenKeybordAppears:) name:UIKeyboardWillShowNotification object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(returnMainViewToInitialposition:) name:UIKeyboardWillHideNotification object:nil]; 
} 
- (void) viewWillDisappear:(BOOL)animated{ 
    [super viewWillDisappear:animated]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

en los métodos a continuación me puse dos métodos para manejar notificaciones de teclado. y aquí están estos métodos:

- (void) liftMainViewWhenKeybordAppears:(NSNotification*)aNotification{ 
    NSDictionary* userInfo = [aNotification userInfo]; 
    NSTimeInterval animationDuration; 
    UIViewAnimationCurve animationCurve; 
    CGRect keyboardFrame; 
    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve]; 
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration]; 
    [[userInfo objectForKey:UIKeyboardBoundsUserInfoKey] getValue:&keyboardFrame]; 
    [UIView beginAnimations:nil context:nil]; 
    [UIView setAnimationDuration:animationDuration]; 
    [UIView setAnimationCurve:animationCurve]; 
    [self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y - keyboardFrame.size.height, self.view.frame.size.width, self.view.frame.size.height)]; 
    [UIView commitAnimations]; 
} 
- (void) returnMainViewToInitialposition:(NSNotification*)aNotification{ 
    NSDictionary* userInfo = [aNotification userInfo]; 
    NSTimeInterval animationDuration; 
    UIViewAnimationCurve animationCurve; 
    CGRect keyboardFrame; 
    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve]; 
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration]; 
    [[userInfo objectForKey:UIKeyboardBoundsUserInfoKey] getValue:&keyboardFrame]; 
    [UIView beginAnimations:nil context:nil]; 
    [UIView setAnimationDuration:animationDuration]; 
    [UIView setAnimationCurve:animationCurve]; 
    [self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y + keyboardFrame.size.height, self.view.frame.size.width, self.view.frame.size.height)]; 
    [UIView commitAnimations]; 
} 
+0

gracias por la buena solución. Pero todavía tengo problemas para mover la barra de herramientas. La vista se mueve pero no la ToolBar que creé en el método 'viewDidLoad'. ¿Podría darme una pista?Gracias – JFS

8

que trabajaron Gracias! Aquí está una ligera mejora:

- (void) liftMainViewWhenKeybordAppears:(NSNotification*)aNotification{ 
    [self scrollViewForKeyboard:aNotification up:YES]; 
} 

- (void) returnMainViewToInitialposition:(NSNotification*)aNotification{ 
    [self scrollViewForKeyboard:aNotification up:NO]; 
} 

- (void) scrollViewForKeyboard:(NSNotification*)aNotification up: (BOOL) up{ 
    NSDictionary* userInfo = [aNotification userInfo]; 

    // Get animation info from userInfo 
    NSTimeInterval animationDuration; 
    UIViewAnimationCurve animationCurve; 
    CGRect keyboardFrame; 
    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve]; 
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration]; 
    [[userInfo objectForKey:UIKeyboardBoundsUserInfoKey] getValue:&keyboardFrame]; 

    // Animate up or down 
    [UIView beginAnimations:nil context:nil]; 
    [UIView setAnimationDuration:animationDuration]; 
    [UIView setAnimationCurve:animationCurve]; 

    [self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y + (keyboardFrame.size.height * (up?-1:1)), self.view.frame.size.width, self.view.frame.size.height)]; 
    [UIView commitAnimations]; 
} 
2

Gracias tanto por este; funciona genial Sin embargo, el código tal como se presenta tiene 2 limitaciones ya que las experimentaron:

1) La vista que se está reposicionado simplemente se desliza hacia arriba fuera de la pantalla en lugar de cambio de tamaño para ajustarse al espacio disponible después de que el teclado aparece

2) Repetir las notificaciones debido a campos de texto de conmutación continúan aplicando el cambio de marco, lo que hace que la vista salga gradualmente de la pantalla.

La causa es que lo anterior es una reposición en relación con el marco actual de la vista en lugar de un cambio de tamaño en relación con el teclado. Aquí hay dos líneas modificadas de código que solucionar este problema:

En liftMainViewWhenKeybordAppears :, cambiar el tamaño en lugar de reposición, en relación con el teclado:

keyboardFrame = [self.view.window convertRect:keyboardFrame toView:self.view.superview]; 
    CGRect superviewFrame = [self.view.window convertRect:self.view.superview.frame toView:self.view]; 
    [self.view setFrame:CGRectMake(self.view.frame.origin.x, 
           self.view.frame.origin.y, 
           self.view.frame.size.width, 
           superviewFrame.size.height - keyboardFrame.size.height)]; 

En returnMainViewToInitialposition :, cambiar la animación a este setFrame: (esencialmente similar a la transformación de identidad).

[self.view setFrame:CGRectMake(self.view.frame.origin.x, 
           self.view.frame.origin.y, 
           self.view.frame.size.width, 
           keyboardFrame.origin.y + keyboardFrame.size.height)]; 
0

Aquí es una solución más elegante usando UIView categoría

#import <Foundation/Foundation.h> 


@interface UIView(AnimationUtils) 
-(void)scrollControlToCenter:(UIView *)view; 
-(void)scrollViewToOriginalPosition; 
@end 



#import "UIView+AnimationUtils.h" 


@implementation UIView(AnimationUtils) 
#pragma mark ScrollView Methods 

//Method Called whenever keyboard appears 
- (void)scrollControlToCenter:(UIView *)view { 
    if([view isKindOfClass:[UITextField class]]){ 
     CGRect viewFrame = [view frame]; 
     float verticalDistance = 216.0f - viewFrame.origin.y - (2*viewFrame.size.height); 
     if(viewFrame.size.height >= (460 - 216)/2){ 
      verticalDistance = 0; 
     } 
     [UIView beginAnimations:@"ScrollToCenter" context:nil]; 
     [UIView setAnimationDuration:0.5]; 
     [self setFrame:CGRectMake(0, verticalDistance, self.frame.size.width, self.frame.size.height)]; 
     [UIView commitAnimations]; 
    }else if([view isKindOfClass:[UITextView class]]){ 
     [UIView beginAnimations:@"ScrollToTop" context:nil]; 
     [UIView setAnimationDuration:0.5]; 
     UIView *viewBG = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]]; 
     [viewBG setTag:5]; 
     [viewBG setBackgroundColor:[UIColor blackColor]]; 
     [viewBG setAlpha:0.75]; 
     [self addSubview:viewBG]; 
     [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height)]; 
     [self setFrame:CGRectMake(0, -view.frame.origin.y , self.frame.size.width, self.frame.size.height)]; 
     [self insertSubview:view atIndex:[self.subviews count] + 1]; 
     [UIView commitAnimations]; 
    } 

} 
-(void)scrollViewToOriginalPosition{ 
    [UIView beginAnimations:@"ScrollToOriginal" context:nil]; 
    [UIView setAnimationDuration:0.5]; 
    for(UIView *view in self.subviews){ 
     if(view.tag == 5){ 
      [view removeFromSuperview]; 
     } 
    } 
    [self setFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)]; 
    [UIView commitAnimations]; 

} 

#pragma mark - 
@end 
5

Sobre la base de las respuestas anteriores y utilizando el método de conveniencia [UIView animateWithDuration ...]. Observe que se mostrarán/ocultarán las notificaciones del teclado y utilizarán estos controladores.

- (void)keyboardWillShow:(NSNotification*)aNotification 
{ 
    NSDictionary* info = [aNotification userInfo]; 
    NSNumber *durationValue = info[UIKeyboardAnimationDurationUserInfoKey]; 
    NSNumber *curveValue = info[UIKeyboardAnimationCurveUserInfoKey]; 
    NSValue *endFrame = info[UIKeyboardFrameEndUserInfoKey]; 

    [UIView animateWithDuration:durationValue.doubleValue 
          delay:0 
         options:(curveValue.intValue << 16) 
        animations:^{ 
         self.navigationController.toolbar.frame = CGRectMake(0, 
                       [endFrame CGRectValue].origin.y - self.navigationController.toolbar.bounds.size.height, 
                       self.navigationController.toolbar.bounds.size.width, 
                       self.navigationController.toolbar.bounds.size.height); 
        } 
        completion:nil]; 
} 

- (void)keyboardWillHide:(NSNotification*)aNotification 
{ 
    NSDictionary* info = [aNotification userInfo]; 
    NSNumber *durationValue = info[UIKeyboardAnimationDurationUserInfoKey]; 
    NSNumber *curveValue = info[UIKeyboardAnimationCurveUserInfoKey]; 

    [UIView animateWithDuration:durationValue.doubleValue 
          delay:0 
         options:(curveValue.intValue << 16) 
        animations:^{ 
         self.navigationController.toolbar.frame = CGRectMake(0, 
                       self.view.bounds.size.height - self.navigationController.toolbar.bounds.size.height, 
                       self.navigationController.toolbar.bounds.size.width, 
                       self.navigationController.toolbar.bounds.size.height); 
        } 
        completion:nil]; 
} 
+0

lanzando UIViewAnimationCurve en UIViewAnimationOptionCurve por cambio! ¡¿Cómo es que no podría haber venido con esto ?! Muchas gracias. –

Cuestiones relacionadas