10

静的セルを含むテーブル ビューがあります。1 つのセルには a が含まれてUITextViewおりheightForRowAtIndexPath:、セルが常にテキストを収容するのに十分な高さになるように、 が動的に計算されます (iOS 7 では、実際には、textView にその を単純に要求することができなくなったため、その部分に多少の作業が必要でしたcontentSize)。

テキストビュー内をタップして編集を開始すると、キーボードが所定の位置にアニメーション化し、これを考慮して tableView の contentInsets が自動的に調整され (つまり、iPhone の縦向きの場合は下部インセットが 216px)、カーソル/キャレットが表示され、次に、テーブル ビューが別の場所にスクロールします。バウンスのように見えてしまいます。

これは、シミュレーターでのビデオです: https://www.dropbox.com/s/htdbb0t7985u6n4/textview-bounce.mov

キャレットがキーボードのすぐ上にあることに注意してください。私はテーブルビューをログに記録しており、contentOffsetそれが適切な値までスクロールし、突然「向きを変えて」スクロールバックするのを見ることができます。

奇妙なことに、シミュレーターで遅いアニメーションをオンにすると、問題はなくなります。contentOffset反転は起こらず、期待どおりに動作します (つまり、iOS 6 の動作) 。

遅いアニメーションのビデオは次のとおりです: https://www.dropbox.com/s/nhn7vspx86t4exb/textview-nobounce.mov

実装上の注意:

  • テキスト ビューはピンク色で、距離 0 のセルにピン留めする AutoLayout 制約があります (10 ポイントの左側を除く)。
  • boundingRectWithSize:lineFragmentPadding と上下のインセットを調整して、テーブルビューの高さを計算するために使用しています。うまくいくようです。
  • textView をスクロールできないように設定しましたが、scrollEnabled== YESの場合に違いはありませんでした
  • これはテーブルビューコントローラーであり、automaticallyAdjustsScrollViewInsets== YES
4

1 に答える 1

3

キーボードが表示されたときに UITableView フレームを調整してみてください。viewWillAppear[self attachKeyboardHelper]と viewWillDisappear[self detachKeyboardHelper]で呼び出します。

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

- (void)detachKeyboardHelper{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)keyboardWillAppear:(NSNotification *)notification{
    NSDictionary* userInfo = [notification 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];

    CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil];
    if(self.view==self.tableView){
        CGRect newTableFrame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y, self.tableView.frame.size.width, self.view.bounds.size.height-keyboardFrame.size.height);
        self.tableView.frame = newTableFrame;
    }else{
        CGRect newTableFrame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y, self.tableView.frame.size.width, self.view.bounds.size.height-self.tableView.frame.origin.y-keyboardFrame.size.height);
        self.tableView.frame = newTableFrame;
    }

    [UIView commitAnimations];
}

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

    NSTimeInterval animationDuration;
    UIViewAnimationCurve animationCurve;
    CGRect keyboardEndFrame;

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


    CGRect newTableFrame = CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y, self.tableView.frame.size.width, self.view.superview.bounds.size.height-self.tableView.frame.origin.y);
    self.tableView.frame = newTableFrame;
    if(newTableFrame.size.height>self.tableView.contentSize.height-self.tableView.contentOffset.y){
        float newOffset=MAX(self.tableView.contentSize.height-newTableFrame.size.height, 0);
        [self.tableView setContentOffset:CGPointMake(0, newOffset) animated:YES];
    }

}
于 2013-12-11T04:16:32.920 に答える