UITableViewを行が含まれていないセクションにスクロールするにはどうすればよいですか?
-
03-07-2019 - |
質問
作業中のアプリには、ゼロ行を含むセクションを含むことができるプレーンスタイルのUITableViewがあります。 scrollToRowAtIndexPath:atScrollPosition:animated:を使用してこのセクションにスクロールできるようにしたいのですが、子行がないためにこのセクションにスクロールしようとするとエラーが発生します。
Appleのカレンダーアプリケーションはこれを行うことができます。リストビューでカレンダーを表示し、今日のカレンダーにイベントがない場合、今日の空のセクションが挿入され、Todayボタンを使用してスクロールできます画面下部のツールバーで。私が知る限り、AppleはカスタマイズされたUITableViewを使用している可能性があるか、プライベートAPIを使用しています...
考えられる唯一の回避策は、高さ0ピクセルの空のUITableCellを挿入し、それまでスクロールすることです。しかし、高さの異なるセルを持つことは、スクロールのパフォーマンスにとって本当に悪いことだと理解しています。それでも、とにかく試してみますが、パフォーマンスへの影響はそれほど悪くないでしょう。
更新
これに対する解決策はないと思われるので、アップルにバグレポートを提出しました。これも影響がある場合は、rdar:// problem / 6263339(レーダーリンクを開く)これをより早く修正したい場合。
更新#2
この問題に対する適切な回避策があります。以下の回答をご覧ください。
解決
更新:このバグは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を変更して、目的のセクションを表示領域の下部または中央にスクロールします。
他のヒント
これは古い質問ですが、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のコードに基づいていますが、上部ではなく中央にスクロールする計算を行います。マイクに感謝-あなたはスターです。
同じものへの迅速なアプローチ:
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)
}
セクションに行がない場合はこれを使用します
let indexPath = IndexPath(row: NSNotFound, section: section)
tableView.scrollToRow(at: indexPath, at: .middle, animated: true)
おそらく空行がそこに行く唯一の方法だと思います。 「空」となるようにUIを再設計することは可能ですか?行は有用なものを表示できますか?
試してみて、パフォーマンスがどのようなものかを確認してください。リストアイテムで透過的なサブビューを使用することについて、非常に悲惨な警告を発しますが、アプリケーションではそれほど重要ではないことがわかりました。