2009-12-23 12 views
9

Ho una UIToolbar in fondo alla mia vista, e ho un UITextField in questa barra degli strumenti. Quando comincio a modificare questo campo, è nascosto dietro la tastiera. Per vedere cosa ho digitato, voglio spostare la barra degli strumenti nel momento in cui viene presentata la tastiera (e poi spostarla quando ho finito di modificare).sposta su UIToolbar

Come si sposta questo UIToolbar su/giù?

+0

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

+0

Non un duplicato. Questa domanda riguarda la barra degli strumenti e non il campo di testo. – phatmann

risposta

13

aggiungi la tua classe viewController all'elenco di osservatori di UIKeyboardWillShowNotification/UIKeyboardWillHideNotification. quindi puoi spostare la vista per rendere visibile la tua vista testo. È inoltre possibile ottenere parametri di animazione da queste notifiche per sincronizzare l'animazione con i parametri di animazione della tastiera della versione del sistema operativo corrente. questo codice ho usato per la paginazione

- (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]; 
} 

nei metodi di seguito ho impostato due metodi per gestire le notifiche della tastiera. e qui ci sono questi metodi:

- (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

grazie per la bella soluzione. Ma ho ancora problemi con lo spostamento della barra degli strumenti. La vista si sposta ma non la barra degli strumenti che ho creato nel metodo 'viewDidLoad'. Potresti darmi un suggerimento?Grazie a – JFS

8

Grazie che hanno lavorato! Ecco un leggero miglioramento:

- (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

Grazie tanto per questo; funziona alla grande Tuttavia, il codice come presentato ha 2 limitazioni come li ho sperimentato:

1) La vista in fase di riposizionamento semplicemente scorre fuori dello schermo, piuttosto che il ridimensionamento per adattarsi allo spazio disponibile dopo la tastiera appare

2) Ripetizione le notifiche dovute al cambio di campo di testo continuano ad applicare la modifica del frame, facendo sì che la vista voli in modo incrementale dallo schermo.

La causa è che quanto sopra è una modifica relativa al fotogramma corrente della vista piuttosto che un ridimensionamento relativo alla tastiera. Qui ci sono due linee modificate di codice che risolvere questo problema:

In liftMainViewWhenKeybordAppears :, ridimensionare piuttosto che riposiziona, relativi alla tastiera:

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)]; 

In returnMainViewToInitialposition :, modificare l'animazione a questo SETFRAME: (essenzialmente simile alla trasformazione dell'identità).

[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

Ecco una soluzione più elegante utilizzando UIView categoria

#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

Basandosi sulle risposte di cui sopra e utilizzando il metodo comodo [UIView animateWithDuration ...]. Osservare la volontà di mostrare/nascondere le notifiche della tastiera e utilizzare questi gestori.

- (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

, lancia UIViewAnimationCurve in UIViewAnimationOptionCurve spostandoti! Come mai non avrei potuto inventare questo !? Grazie mille. –