2013-03-14 5 views
25

Für die Konstante UIKeyboardFrameEndUserInfoKey, in der Apple-Dokumentation heißt es:Konvertieren UIKeyboardFrameEndUserInfoKey Anzeigen oder Fensterkoordinaten

Diese Koordinaten berücksichtigen nicht jede Drehung Faktoren auf die als Folge der Schnittstelle Ausrichtung des Fensters aufgebracht Inhalte ändert sich. Daher müssen Sie das Rechteck möglicherweise in das Fenster Koordinaten konvertieren (mit der Methode convertRect: fromWindow:) oder Koordinaten anzeigen (mit der Methode convertRect: fromView:), bevor Sie es verwenden.

Also, wenn ich [view1 convertRect:rect fromView:view2]

Was würde ich für die oben genannten Parameter einfügen, um es richtig die Rotationswerte zu konvertieren? dh:

view1 =? rect =? (der Tastaturrahmen nehme ich an) view2 =?

Sie haben einige Dinge versucht und einige lustige Sachen bekommen.

+0

verwendet werden Hoffe, dass die Antwort unten hilft. Ich habe vorher auch 'convertRect' verwendet, aber der Code unten ist sauberer, IMO. – memmons

+0

Offensichtlich stimme ich @Answerbot nicht zu, was "sauberer" ist :) BTW der Code, den ich zeige, stammt aus meinem Buch, das Sie in dieser Angelegenheit konsultieren können: http://www.apeth.com/iOSBook/ ch23.html # _summoning_and_dismissing_the_keyboard – matt

+0

@matt Gute Sachen. Ich habe eines deiner Bücher gelesen und es hat mir sehr gefallen. Der Grund, warum ich die Verwendung von 'convertRect' aufgehört habe, ist, dass es nur innerhalb eines View-Controllers funktioniert, wo Sie eine' myView' haben, die die oberste Ansicht darstellt. Wenn Sie jedoch auf Benachrichtigungen innerhalb einer UITextField-Unterklasse warten, ist die Umwandlung mithilfe von self nicht besonders hilfreich. – memmons

Antwort

66

Die erste Ansicht sollte Ihre Ansicht sein. Die zweite Ansicht sollte null sein, also Fenster-/Bildschirmkoordinaten. Also:

NSDictionary* d = [notification userInfo]; 
CGRect r = [d[UIKeyboardFrameEndUserInfoKey] CGRectValue]; 
r = [myView convertRect:r fromView:nil]; 

Jetzt haben Sie die rect, dass die Tastatur besetzen, in Bezug auf Ihre Ansicht. Wenn Ihre Ansicht die Ansicht des aktuellen Ansichtscontrollers (oder eine Unteransicht davon) ist, wird die Rotation usw. berücksichtigt.

+4

+1, aber ich denke, das ist nur nützlich, wenn 'myView' die Stammansicht eines View-Controllers darstellt. Was, wenn es nicht so ist und stattdessen myView eine Unteransicht wie '{100,100,200,200}' ist? – memmons

+1

Beachten Sie, dass Sie auch das Rect- in Fensterkoordinatensystem konvertieren müssen! Die Antwort von @ david-m-syzdek ist vollständiger. –

+1

@DiogoTridapalli Nur um klar zu sein, in iOS 8 gibt es keine Notwendigkeit, durch das Fenster Koordinatensystem zu konvertieren, um den Fall der Querformat zu behandeln, weil die gesamte App rotiert und die Tastatur mit ihm gedreht hat. – matt

21

Ich versuchte die akzeptierte Antwort und stellte fest, dass es das CGRect der Tastatur innerhalb der Ansicht nicht tatsächlich bereitstellt. Ich fand, dass ich die CGRect vom UIScreen Objekt zum UIWindow Objekt konvertieren, und vom UIWindow Objekt zum UIView Objekt:

NSValue * keyboardEndFrame; 
CGRect screenRect; 
CGRect windowRect; 
CGRect viewRect; 

// determine's keyboard height 
screenRect = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; 
windowRect = [self.view.window convertRect:screenRect fromWindow:nil]; 
viewRect  = [self.view  convertRect:windowRect fromView:nil]; 

Ich verwende die oben die Root-Ansicht, um die Größe nicht durch die versteckt werden Tastatur:

NSTimeInterval duration; 
CGRect   frame; 

// determine length of animation 
duration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 

// resize the view 
frame    = self.view.frame; 
frame.size.height -= viewRect.size.height; 

// animate view resize with the keyboard movement 
[UIView beginAnimations:nil context:NULL]; 
[UIView setAnimationBeginsFromCurrentState:YES]; 
[UIView setAnimationDuration:duration]; 
self.view.frame = frame; 
[UIView commitAnimations]; 
+0

Ich stieß auf einen Fall, wo ich das auch tun musste. Also, ich werde es von jetzt an so machen. – ma11hew28

+0

Ich benutze diese Methode, aber offensichtlich falsche 'Herkunft' Werte der viewRect für Querformat (negative 'y'). In Ihrer Lösung verwenden Sie nur die 'Höhe'. Hat Ihr 'Ursprung' den richtigen' y' Wert? – burax

1
+ (void)parseKeyboardNotification:(NSNotification *)notification 
       inRelationToView:(UIView *)view 
          info:(void(^)(NSTimeInterval keyboardAnimationDuration, CGRect keyboardFrameInView, UIViewAnimationOptions keyboardAnimationOptions))callback 
{ 
    NSParameterAssert(notification != nil); 
    NSParameterAssert(view != nil); 

    NSDictionary *userInfo = [notification userInfo]; 

    UIViewAnimationCurve animationCurve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]; 
    UIViewAnimationOptions animationOption = animationCurve << 16; // https://devforums.apple.com/message/878410#878410 
    NSTimeInterval animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 

    // http://stackoverflow.com/a/16615391/202451 
    CGRect screenRect = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; 
    CGRect windowRect = [view.window convertRect:screenRect fromWindow:nil]; 
    CGRect viewRect  = [view  convertRect:windowRect fromView:nil]; 

    callback(animationDuration, viewRect, animationOption); 
} 

kann wie folgt

- (void)keyboardWillShowOrHide:(NSNotification *)notification 
{  
    [AGKeyboardInfo parseKeyboardNotification:notification inRelationToView:self.view info:^(NSTimeInterval keyboardAnimationDuration, CGRect keyboardFrameInView, UIViewAnimationOptions keyboardAnimationOptions) { 

     [UIView animateWithDuration:keyboardAnimationDuration delay:0 options:keyboardAnimationOptions animations:^{ 

      // do any modifications to your views 

     } completion:nil]; 
    }]; 
} 
Verwandte Themen