在表格视图中,我必须滚动到顶部。但我不能保证第一个对象是section 0,第0行。可能我的表视图将从第5节开始。
所以当我调用:
[mainTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
有其他方法滚动到表视图的顶部吗?
在表格视图中,我必须滚动到顶部。但我不能保证第一个对象是section 0,第0行。可能我的表视图将从第5节开始。
所以当我调用:
[mainTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
有其他方法滚动到表视图的顶部吗?
当前回答
Swift 5, iOS 13
我知道这个问题已经有很多答案了,但从我的经验来看,这个方法总是有效的:
let last = IndexPath(row: someArray.count - 1, section: 0)
tableView.scrollToRow(at: last, at: .bottom, animated: true)
如果你正在处理动画(比如键盘)或某些异步任务,这尤其正确——其他答案通常会滚动到底部。如果由于某种原因,这不能让你一直到底部,这几乎肯定是因为竞争动画,所以解决方法是将这个动画分派到主队列的末尾:
DispatchQueue.main.async {
let last = IndexPath(row: self.someArray.count - 1, section: 0)
self.tableView.scrollToRow(at: last, at: .bottom, animated: true)
}
这似乎是多余的,因为你已经在主队列上了,但这并不是因为它序列化了动画。
其他回答
因为我的tableView充满了各种各样的insets,这是唯一一件工作得很好的事情:
斯威夫特3
if tableView.numberOfSections > 0 && tableView.numberOfRows(inSection: 0) > 0 {
tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
}
斯威夫特2
if tableView.numberOfSections > 0 && tableView.numberOfRowsInSection(0) > 0 {
tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: .Top, animated: true)
}
可能的行动:
1
func scrollToFirstRow() {
let indexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
}
2
func scrollToLastRow() {
let indexPath = NSIndexPath(forRow: objects.count - 1, inSection: 0)
self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Bottom, animated: true)
}
3
func scrollToSelectedRow() {
let selectedRows = self.tableView.indexPathsForSelectedRows
if let selectedRow = selectedRows?[0] as? NSIndexPath {
self.tableView.scrollToRowAtIndexPath(selectedRow, atScrollPosition: .Middle, animated: true)
}
}
4
func scrollToHeader() {
self.tableView.scrollRectToVisible(CGRect(x: 0, y: 0, width: 1, height: 1), animated: true)
}
5
func scrollToTop(){
self.tableView.setContentOffset(CGPointMake(0, UIApplication.sharedApplication().statusBarFrame.height ), animated: true)
}
禁用滚动到顶部:
func disableScrollsToTopPropertyOnAllSubviewsOf(view: UIView) {
for subview in view.subviews {
if let scrollView = subview as? UIScrollView {
(scrollView as UIScrollView).scrollsToTop = false
}
self.disableScrollsToTopPropertyOnAllSubviewsOf(subview as UIView)
}
}
根据需求修改和使用它。
斯威夫特4
func scrollToFirstRow() {
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}
在Swift 5中,非常感谢@Adrian的回答
extension UITableView{
func hasRowAtIndexPath(indexPath: IndexPath) -> Bool {
return indexPath.section < numberOfSections && indexPath.row < numberOfRows(inSection: indexPath.section)
}
func scrollToTop(_ animated: Bool = false) {
let indexPath = IndexPath(row: 0, section: 0)
if hasRowAtIndexPath(indexPath: indexPath) {
scrollToRow(at: indexPath, at: .top, animated: animated)
}
}
}
用法:
tableView.scrollToTop()
迅速:
如果你没有tableView头文件:
tableView.setContentOffset(CGPointMake(0, UIApplication.sharedApplication().statusBarFrame.height ), animated: true)
如果有:
tableView.setContentOffset(CGPointMake(0, -tableViewheader.frame.height + UIApplication.sharedApplication().statusBarFrame.height ), animated: true)
我更喜欢下面的,因为它考虑到一个插图。如果没有插入,它仍然会滚动到顶部,因为插入将是0。
tableView.setContentOffset(CGPoint(x: 0, y: -tableView.contentInset.top), animated: true)