1

キーボードが表示されてカバーされているときに、UITextView のキャレットまでスクロールしようとしています。残念ながら、Apple が Notes アプリで同じことをしているにもかかわらず、アニメーション化しない場合にのみ機能します。Apple のドキュメントで説明されているのと同じアプローチを使用しています。

これがコードです。他の干渉なしにテストするために、隔離されたプロジェクトに配置されています。UITextView が追加された View Controller は 1 つだけです。シミュレーターとデバイスの両方で、iOS 7 でこれをテストしています。

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedKeyboardDidShowNotification:) name:UIKeyboardDidShowNotification object:nil];
}

- (void)receivedKeyboardDidShowNotification:(NSNotification *)notification {
    CGRect keyboardBounds = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
    CGFloat keyboardDistanceFromBottomOfScreen = screenHeight - CGRectGetMinY(keyboardBounds);
    UITextView *textView = self.textView;
    UIEdgeInsets contentInset = textView.contentInset;
    contentInset.bottom += keyboardDistanceFromBottomOfScreen;
    textView.contentInset = contentInset;
    textView.scrollIndicatorInsets = contentInset;

    CGRect caretRect = [textView caretRectForPosition:textView.selectedTextRange.end];
    [textView scrollRectToVisible:caretRect animated:YES];
}

animated最後の行のパラメーターを に設定するとNO、これは完全に機能します (ただし、もちろんアニメーションは必要ありません)。渡すYESと奇妙な動作が発生します。ほとんどの場合、ビューはスクロールしないか、数ピクセルしかスクロールしませんが、必要な動作が発生する場合があるため、結果はランダムです。

setContentOffset:animated:キャレットのオフセットを計算して の代わりにメソッドを使用しようとしましたscrollRectToVisible:animated:が、結果は同じです。の場合に機能しanimatedますNO。それを使用YESすると、同じ奇妙な結果が生成されます。

さらに奇妙なことに、この 2 番目のソリューションでは、通知が 1 回しか配信されなかったにもかかわらず、その行のブレークポイントが 2 回ヒットしました。前の行またはその後に追加した行 (何もせず、テスト用のログ ステートメントのみ) のブレークポイントは 1 回だけヒットしました。さらに奇妙なことに、3 行にロギング ブレークポイントを配置すると、次の結果が得られました。

Line before
Buggy line
Line after
Buggy line

そのため、ラインの 2 番目のヒットは故障しました。インスペクタを見ると、すべてのローカル変数がスコープ外にあるように見えました。

また、両方のソリューションのコードを別のメソッドに入れて、遅延後に呼び出しようとしましたperformSelector:withObject:afterDelay:が、1 秒のような長い遅延があっても何も変更されませんでした。最初のソリューションでは、このブレークポイントでのダブル ヒットは発生しませんでした。

この時点で私は解決策を使い果たしました。これは iOS のバグのように思えますが、前述したように Notes アプリで機能するため、少なくとも 1 つの解決策があります。

編集:さらに調査を行ったところ、テキストビューがファーストレスポンダーでキーボードが表示されている場合にのみバグが発生します(どちらが責任があるかはわかりません)。キーボード通知ではなくコードからトリガー scrollRectToVisible:animated:すると、アニメーションは正常に機能します。しかし、最初[textView becomeFirstResponder]にキーボードを表示する を呼び出すと、アニメーションが再び中断されます。

4

0 に答える 0