web-dev-qa-db-ja.com

行を含まないセクションにUITableViewをスクロールするにはどうすればよいですか?

私が取り組んでいるアプリには、ゼロ行を含むセクションを含めることができるプレーンスタイルのUITableViewがあります。 scrollToRowAtIndexPath:atScrollPosition:animated:を使用してこのセクションにスクロールできるようにしたいのですが、子行がないため、このセクションにスクロールしようとするとエラーが発生します。

Appleのカレンダーアプリケーションはこれを行うことができます。カレンダーをリストビューで見て、今日のカレンダーにイベントがない場合、今日の空のセクションが挿入され、ツールバーの[今日]ボタンを使用してスクロールできます。画面の下部にあります。私が知る限り、AppleはカスタマイズされたUITableViewを使用しているか、プライベートAPIを使用しています...

私が考えることができる唯一の回避策は、高さ0ピクセルの空のUITableCellを挿入し、そこまでスクロールすることです。しかし、高さが異なるセルを使用することは、スクロールのパフォーマンスにとって本当に悪いことだと私は理解しています。それでも私はとにかくそれを試してみます、多分パフォーマンスヒットはそれほど悪くないでしょう。

更新

これに対する解決策がないように思われるので、私はAppleにバグレポートを提出しました。これも影響を受ける場合は、これをより速く修正したい場合は、rdar:// problem/6263339( Open Radar link) の複製を提出してください。

更新#2

私はこの問題に対して適切な回避策を持っています。以下の私の答えを見てください。

32
Mike Akers

更新:このバグはiOS 3.0で修正されたようです。次のNSIndexPathを使用して、0行を含むセクションにスクロールできます。

[NSIndexPath indexPathForRow:NSNotFound inSection:section]

2.x SDKを使用してプロジェクトを維持している人のために、ここでは元の回避策を残します。


適切な回避策が見つかりました:

CGRect sectionRect = [tableView rectForSection:indexOfSectionToScrollTo];
[tableView scrollRectToVisible:sectionRect animated:YES];

上記のコードは、目的のセクションが表示されるようにテーブルビューをスクロールしますが、必ずしも表示領域の上部または下部にあるわけではありません。セクションが一番上になるようにスクロールする場合は、次のようにします。

CGRect sectionRect = [tableView rectForSection:indexOfSectionToScrollTo];
sectionRect.size.height = tableView.frame.size.height;
[tableView scrollRectToVisible:sectionRect animated:YES];

必要に応じてsectionRectを変更し、目的のセクションを表示領域の下部または中央にスクロールします。

119
Mike Akers

これは古い質問ですが、Appleは、セクションに行がない場合のクラッシュのバグを支援または修正するものをまだ追加していません。

私にとっては、新しいセクションを追加するときに中央までスクロールする必要があったので、次のコードを使用します。

if (rowCount > 0) {
    [self.tableView scrollToRowAtIndexPath: [NSIndexPath indexPathForRow: 0 inSection: sectionIndexForNewFolder] 
                          atScrollPosition: UITableViewScrollPositionMiddle
                                  animated: TRUE];
} else { 
    CGRect sectionRect = [self.tableView rectForSection: sectionIndexForNewFolder];
    // Try to get a full-height rect which is centred on the sectionRect
    // This produces a very similar effect to UITableViewScrollPositionMiddle.
    CGFloat extraHeightToAdd = sectionRect.size.height - self.tableView.frame.size.height;
    sectionRect.Origin.y -= extraHeightToAdd * 0.5f;
    sectionRect.size.height += extraHeightToAdd;
    [self.tableView scrollRectToVisible:sectionRect animated:YES];
}

お気に召してください。ご覧のとおり、Mike Akersのコードに基づいていますが、上ではなく中央までスクロールするための計算を行います。ありがとうマイク-あなたはスターです。

4
Simon Tillson

Swift同じアプローチ:

if rows > 0 {
    let indexPath = IndexPath(row: 0, section: section)
    self.tableView.setContentOffset(CGPoint.zero, animated: true)
    self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}

else {
    let sectionRect : CGRect = tableView.rect(forSection: section)
    tableView.scrollRectToVisible(sectionRect, animated: true)
}
1
Chaitanya Ramji

セクションに行がない場合は、これを使用してください

let indexPath = IndexPath(row: NSNotFound, section: section)
tableView.scrollToRow(at: indexPath, at: .middle, animated: true)
0