定数UIKeyboardFrameEndUserInfoKey
については、Apple docsで、次のように述べています。
これらの座標は、インターフェースの向きの変更の結果としてウィンドウのコンテンツに適用される回転係数を考慮していません。したがって、使用する前に、四角形をウィンドウ座標(convertRect:fromWindow:メソッドを使用)またはビュー座標(convertRect:fromView:メソッドを使用)に変換する必要がある場合があります。
したがって、[view1 convertRect:rect fromView:view2]
回転値を正しく変換するには、上記のパラメーターに何を挿入しますか?つまり:
view1 =? rect =? (私が想定しているキーボードフレーム)view2 =?
いくつかのことを試し、面白いものを手に入れました。
最初のビューは自分のビューでなければなりません。 2番目のビューは、ウィンドウ/画面座標を意味するnilである必要があります。したがって:
NSDictionary* d = [notification userInfo];
CGRect r = [d[UIKeyboardFrameEndUserInfoKey] CGRectValue];
r = [myView convertRect:r fromView:nil];
これで、ビューの観点から、キーボードが占める範囲が得られました。ビューが現在のビューコントローラーのビュー(またはそのサブビュー)である場合、回転などが考慮されます。
私は受け入れられた答えを試してみましたが、ビュー内のキーボードのCGRectを実際には提供していません。 CGRectをUIScreenオブジェクトからUIWindowオブジェクトに、UIWindowオブジェクトからUIViewオブジェクトに変換する必要があることがわかりました。
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];
上記を使用して、キーボードで非表示にならないようにルートビューのサイズを変更します。
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];
+ (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);
}
このように使用できます
- (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];
}];
}