51

私は 3.2 SDK を使用して iPad アプリに取り組んでいます。テキストフィールドがキーボードの後ろに隠れないように、キーボードのサイズを取得することに取り組んでいます。

Xcode で警告が表示されます -> UIKeyboardBoundsUserInfoKey is deprecated この警告が表示されないようにするには、代わりに何を使用すればよいですか?

4

9 に答える 9

87

以前に提供されたソリューションを試してみましたが、まだ問題がありました。代わりに私が思いついたのは次のとおりです。

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

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

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

// Get animation info from userInfo
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;

CGRect keyboardEndFrame;

[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];


[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];


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

CGRect newFrame = textView.frame;
CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil];

newFrame.origin.y -= keyboardFrame.size.height * (up? 1 : -1);
textView.frame = newFrame;

[UIView commitAnimations];
}
于 2010-05-29T08:21:25.010 に答える
57

ドキュメントからUIKeyboardBoundsUserInfoKey:

ウィンドウ座標でキーボードの境界矩形を識別する CGRect を含む NSValue オブジェクトのキー。この値は、キーボードのサイズを取得するのに十分です。画面上のキーボードの原点を (アニメーションの前または後に) 取得する場合は、UIKeyboardCenterBeginUserInfoKey または UIKeyboardCenterEndUserInfoKey 定数を介してユーザー情報辞書から取得した値を使用します。代わりに UIKeyboardFrameBeginUserInfoKey または UIKeyboardFrameEndUserInfoKey キーを使用してください。

Apple は、次のような便利なルーチンを実装することを推奨しています (これは、 へのカテゴリの追加として実装できますUIScreen)。

+ (CGRect) convertRect:(CGRect)rect toView:(UIView *)view {
    UIWindow *window = [view isKindOfClass:[UIWindow class]] ? (UIWindow *) view : [view window];
    return [view convertRect:[window convertRect:rect fromWindow:nil] fromView:nil];
}

ウィンドウで調整されたキーボード フレーム サイズのプロパティを回復します。

私は、デバイスの向きを確認することを含む別のアプローチを取りました。

CGRect _keyboardEndFrame;
[[notification.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue:&_keyboardEndFrame];
CGFloat _keyboardHeight = ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait || [[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) ? _keyboardEndFrame.size.height : _keyboardEndFrame.size.width;
于 2010-05-11T00:38:09.317 に答える
9

次のコードを使用するだけです。

//NSVale *aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
//instead of Upper line we can use either next line or nextest line.
//NSValue *aValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
NSValue *aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
于 2010-12-02T10:48:33.240 に答える
3

次のコードは、 Jay's answer の問題を修正します。これはUIKeyboardWillShowNotification、キーボードが既に存在する場合に再度起動しないことを前提としています。

UIKeyboardWillShowNotification日本語/中国語キーボードで入力すると、キーボードが既に存在する場合でも、iOS は新しいキーボード フレームでエクストラをself.textView起動し、元のコードで の高さが 2 度縮小されます。

これによりself.textView、ほとんど何もなくなります。UIKeyboardWillHideNotification次にキーボードが閉じられたときに単一のエラーしか発生しないと予想されるため、この問題から回復することは不可能になります。

self.textView元のコードのようにキーボードの表示/非表示に応じて高さを減算/加算する代わりに、次のコードself.textViewは、画面上のキーボードの高さを減算した後の最大可能高さを計算するだけです。

これはself.textView、View Controller のビュー全体を埋めることが想定されており、表示する必要がある他のサブビューがないことを前提としています。

- (void)resizeTextViewWithKeyboardNotification:(NSNotification*)notif {

    NSDictionary* userInfo = [notif userInfo];
    NSTimeInterval animationDuration;
    UIViewAnimationCurve animationCurve;
    CGRect keyboardFrameInWindowsCoordinates;

    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
    [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardFrameInWindowsCoordinates];

    [self resizeTextViewToAccommodateKeyboardFrame:keyboardFrameInWindowsCoordinates
                             withAnimationDuration:animationDuration
                                    animationCurve:animationCurve];

}

- (void)resizeTextViewToAccommodateKeyboardFrame:(CGRect)keyboardFrameInWindowsCoordinates
                           withAnimationDuration:(NSTimeInterval)duration
                                  animationCurve:(UIViewAnimationCurve)curve
{

    CGRect fullFrame = self.view.frame;

    CGRect keyboardFrameInViewCoordinates =
    [self.view convertRect:keyboardFrameInWindowsCoordinates fromView:nil];

    // Frame of the keyboard that intersects with the view. When keyboard is
    // dismissed, the keyboard frame still has width/height, although the origin
    // keeps the keyboard out of the screen.
    CGRect keyboardFrameVisibleOnScreen =
    CGRectIntersection(fullFrame, keyboardFrameInViewCoordinates);

    // Max frame availble for text view. Assign it to the full frame first
    CGRect newTextViewFrame = fullFrame;

    // Deduct the the height of any keyboard that's visible on screen from
    // the height of the text view
    newTextViewFrame.size.height -= keyboardFrameVisibleOnScreen.size.height;

    if (duration)
    {
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationDuration:duration];
        [UIView setAnimationCurve:curve];
    }

    // Adjust the size of the text view to the new one
    self.textView.frame = newTextViewFrame;

    if (duration)
    {
        [UIView commitAnimations];
    }

}

また、viewDidLoad にキーボード通知を登録することを忘れないでください。

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSNotificationCenter* notifCenter = [NSNotificationCenter defaultCenter];

    [notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillShowNotification object:nil];
    [notifCenter addObserver:self selector:@selector(resizeTextViewWithKeyboardNotification:) name:UIKeyboardWillHideNotification object:nil];
}

リサイズコードの2分割について

resizeTextViewWithKeyboardNotification:textView のサイズ変更コードが 2 つの部分 (および)に分割されている理由は、resizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:あるビュー コントローラーから別のビュー コントローラーへのプッシュによってキーボードが持続する場合の別の問題を修正するためです (「コントローラー間で iOS キーボードが起動しているときに、iOS キーボードを検出するにはどうすればよいですか?」を参照してください) 。 .

ビュー コントローラーがプッシュされる前にキーボードが既に存在するため、iOS によって追加のキーボード通知が生成されることはありません。したがって、textViewこれらのキーボード通知に基づいて のサイズを変更する方法はありません。

したがって、サイズを変更する上記のコード (および元のコード)は、ビューが読み込まれたself.textViewにキーボードが表示されている場合にのみ機能します。

私の解決策は、最後のキーボード座標を格納するシングルトンを作成し- viewDidAppear:、viewController で次を呼び出すことです。

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // Resize the view if there's any keyboard presence before this
    // Only call in viewDidAppear as we are unable to convertRect properly
    // before view is shown
    [self resizeViewToAccommodateKeyboardFrame:[[UASKeyboard sharedKeyboard] keyboardFrame]
                         withAnimationDuration:0
                                animationCurve:0];
}

UASKeyboardここに私のシングルトンがあります。理想的には でこれを呼び出す必要があります- viewWillAppear:が、私の経験では (少なくとも iOS 6 では) でconvertRect:fromView:使用する必要があるメソッドはresizeViewToAccommodateKeyboardFrame:withAnimationDuration:animationCurve:、ビューが完全に表示される前にキーボード フレームをビュー座標に適切に変換しません。

于 2012-10-18T11:21:02.880 に答える
2

UIKeyboardFrameBeginUserInfoKeyの代わりにまたはUIKeyboardFrameEndUserInfoKeyキーを使用するだけですUIKeyboardBoundsUserInfoKey

于 2012-10-05T05:26:49.260 に答える
1

@ジェイソン、1点を除いて問題なければコーディングします。

現時点では、実際には何もアニメーション化しておらず、ビューは単純に新しい size.height に「ポップ」します。

アニメーション化する状態を指定する必要があります。アニメーションは一種の (状態から) -> (状態へ) のものです。

幸いなことに、ビューの現在の状態を (元の状態) として指定する非常に便利な方法があります。

[UIView setAnimationBeginsFromCurrentState:YES];

beginAnimations:context: の直後にその行を追加すると、コードは完全に機能します。

于 2010-06-22T09:39:14.347 に答える
1
- (CGSize)keyboardSize:(NSNotification *)aNotification {
    NSDictionary *info = [aNotification userInfo];
    NSValue *beginValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];

    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

    CGSize keyboardSize;
    if ([UIKeyboardDidShowNotification isEqualToString:[aNotification name]]) {
        _screenOrientation = orientation;
        if (UIDeviceOrientationIsPortrait(orientation)) {
            keyboardSize = [beginValue CGRectValue].size;
        } else {
            keyboardSize.height = [beginValue CGRectValue].size.width;
            keyboardSize.width = [beginValue CGRectValue].size.height;
        }
    } else if ([UIKeyboardDidHideNotification isEqualToString:[aNotification name]]) {
        // We didn't rotate
        if (_screenOrientation == orientation) {
            if (UIDeviceOrientationIsPortrait(orientation)) {
                keyboardSize = [beginValue CGRectValue].size;
            } else {
                keyboardSize.height = [beginValue CGRectValue].size.width;
                keyboardSize.width = [beginValue CGRectValue].size.height;
            }
        // We rotated
        } else if (UIDeviceOrientationIsPortrait(orientation)) {
            keyboardSize.height = [beginValue CGRectValue].size.width;
            keyboardSize.width = [beginValue CGRectValue].size.height;
        } else {
            keyboardSize = [beginValue CGRectValue].size;
        }
    }


    return keyboardSize;
}
于 2011-03-07T10:32:02.843 に答える
0

詳細はこちら http://i-phone-dev.blogspot.com/2012/01/different-way-to-show-keyboard-and.html

于 2012-01-18T11:47:22.343 に答える