5

この質問は数回尋ねられましたが、私は本当に答えを見つけることができませんでした...

iOS6 では、キーボードが表示されるたびに次のように UITextView のサイズを変更しました。iOS7 の動作は本来あるべきものではありません (私の場合、何もサイズ変更されていないようです)。iOS7のオートレイアウト・コンストレイント動作が原因と思われます。助言がありますか?(「notePad」は私の UITextView です)?

- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    //NSLog(@"KeyboardSize: %f.%f", kbSize.width, kbSize.height);

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, (kbSize.width > kbSize.height ? 
    kbSize.height : kbSize.width), 0);
    self.notePad.contentInset = contentInsets;
    self.notePad.scrollIndicatorInsets = contentInsets;
}
4

6 に答える 6

15

ビューで自動レイアウトを使用している場合は、次の方法が役立つ場合があります。

最初に、下部レイアウト ガイドの制約用に IBOutlet を定義し、ストーリーボード要素にリンクします。

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewBottomConst;

次に、キーボード通知用のオブザーバーを追加します。

- (void)observeKeyboard {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

最後に、キーボードの変更を処理するメソッドです。

- (void)keyboardWillShow:(NSNotification *)notification {
    NSDictionary *info = [notification userInfo];
    NSValue *kbFrame = [info objectForKey:UIKeyboardFrameEndUserInfoKey];

    NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    CGRect keyboardFrame = [kbFrame CGRectValue];

    CGRect finalKeyboardFrame = [self.view convertRect:keyboardFrame fromView:self.view.window];

    int kbHeight = finalKeyboardFrame.size.height;

    int height = kbHeight + self.textViewBottomConst.constant;

    self.textViewBottomConst.constant = height;

    [UIView animateWithDuration:animationDuration animations:^{
        [self.view layoutIfNeeded];
    }];
}

- (void)keyboardWillHide:(NSNotification *)notification {
    NSDictionary *info = [notification userInfo];

    NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];

    self.textViewBottomConst.constant = 10;

    [UIView animateWithDuration:animationDuration animations:^{
        [self.view layoutIfNeeded];
    }];
}

このメソッドは、向きの変更とさまざまなキーボード サイズをサポートします。それが役に立てば幸い。

于 2013-11-12T07:26:54.043 に答える
4

あなたのコードは論理的に正しいです。キーボードが表示されているとき、スクロールビューの動作でオブジェクトのフレームを変更することはほとんどありませんが、インセットのみを変更する必要があります。iOS7 がナビゲーション バーの調整を処理するため、インセットは現在のバージョンに対して相対的に変更する必要があります。新しいインセットを提供すると、UI で何かが壊れる可能性があります。あなたのコードは、主に 2 つの理由で iOS7 で壊れています。

  1. 自動レイアウト制約を textview コンテナーに追加する必要があります。(おそらく、テキスト ビューは予想よりも大きくなっています)
  2. インセットを絶対に変更しないでください。

textview を適切に構成する手順は次のとおりです。

  • xib (またはストーリーボード) で、コンテナーの上、左、右、下に制約を追加します (私の場合、以下に示すように {0, 0, 0, 0}

自動レイアウトの制約

  • キーボード通知に登録する

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    
  • keyboardWillShowフレームを変更しませんが、インkeyboardWillHideセットを既存のものと相対的に変更します。

    - (void)keyboardWillShow:(NSNotification *)notification
    {
        // Take frame with key: UIKeyboardFrameEndUserInfoKey because we want the final frame not the begin one
        NSValue *keyboardFrameValue = [notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
        CGRect keyboardFrame = [keyboardFrameValue CGRectValue];
    
        UIEdgeInsets contentInsets = self.textView.contentInset;
        contentInsets.bottom = CGRectGetHeight(keyboardFrame);
    
        self.textView.contentInset = contentInsets;
        self.textView.scrollIndicatorInsets = contentInsets;
    }
    
    - (void)keyboardWillHide:(NSNotification *)notification
    {
        UIEdgeInsets contentInsets = self.textView.contentInset;
        contentInsets.bottom = .0;
    
        self.textView.contentInset = contentInsets;
        self.textView.scrollIndicatorInsets = contentInsets;
    }
    
    • 次に、オブザーバーを削除することを忘れないでください
于 2014-02-15T08:02:17.513 に答える
0

私はこれと1週間戦っていましたが、キーボードサイズの高さを下に追加してもcontentInsetうまくいかないことがわかりました.

うまくいったのは、次のように上から差し引くことでした。

UIEdgeInsets insets = UIEdgeInsetsMake(-(kbSize.height), 0.0, 0.0, 0.0);
[self.textView setContentInset:insets];
于 2013-12-29T17:35:06.173 に答える