UITableView -滚动到顶部

在表格视图中,我必须滚动到顶部。但我不能保证第一个对象是section 0,第0行。可能我的表视图将从第5节开始。

所以当我调用:

[mainTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];

有其他方法滚动到表视图的顶部吗?

270421 次浏览

UITableView是UIScrollView的子类,所以你也可以使用:

[mainTableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];

[mainTableView setContentOffset:CGPointZero animated:YES];

在Swift中:

mainTableView.setContentOffset(CGPointZero, animated:true)

在Swift 3 &上图:

mainTableView.setContentOffset(.zero, animated: true)

请注意:这个答案对iOS 11和更高版本无效。

我更喜欢

[mainTableView setContentOffset:CGPointZero animated:YES];

如果你在你的表格视图中有一个top inset,你必须减去它:

[mainTableView setContentOffset:CGPointMake(0.0f, -mainTableView.contentInset.top) animated:YES];

这段代码让你滚动一个特定的部分顶部

CGRect cellRect = [tableinstance rectForSection:section];
CGPoint origin = [tableinstacne convertPoint:cellRect.origin
fromView:<tableistance>];
[tableinstance setContentOffset:CGPointMake(0, origin.y)];

最好不要使用NSIndexPath(空表),也不要假设顶点是CGPointZero(内容嵌入),这就是我使用的-

[tableView setContentOffset:CGPointMake(0.0f, -tableView.contentInset.top) animated:YES];

希望这能有所帮助。

如果你想在表格中移动滚动动画,请使用此代码。滚动移动到顶部的动画在0.5秒。

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];


[_tableContent scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];


[UIView commitAnimations];

如果你不想要滚动,你可以启动和停止滚动动画,只要你启动它。

    $('document').ready(function() {
$("html, body").animate({ scrollTop: 0 }, 500);
return true;
});

此外,为了使'x'和'y'的值动画化,传入0,0将立即将页面滚动到左上角。

window.scrollTo(x, y);

迅速:

tableView.setContentOffset(CGPointZero, animated: true)

迅速:

如果你没有tableView头文件:

tableView.setContentOffset(CGPointMake(0,  UIApplication.sharedApplication().statusBarFrame.height ), animated: true)

如果有:

tableView.setContentOffset(CGPointMake(0, -tableViewheader.frame.height   + UIApplication.sharedApplication().statusBarFrame.height ), animated: true)

对于具有contentInset的表,将内容偏移量设置为CGPointZero将不起作用。它会滚动到内容顶部,而不是滚动到桌面顶部。

将内容嵌入考虑在内会产生这样的结果:

[tableView setContentOffset:CGPointMake(0, -tableView.contentInset.top) animated:NO];

在斯威夫特

your row = selectioncellRowNumber 你的section如果你有= selectionNumber如果你没有set是零

/ / UITableViewScrollPosition。中间或底部或顶部

var lastIndex = NSIndexPath(forRow:  selectioncellRowNumber, inSection: selectionNumber)
self.tableView.scrollToRowAtIndexPath(lastIndex, atScrollPosition: UITableViewScrollPosition.Middle, animated: true)

添加到已经说过的,你可以创建一个扩展(Swift)或类别(Objective C),使这在未来更容易:

迅速:

extension UITableView {
func scrollToTop(animated: Bool) {
setContentOffset(CGPointZero, animated: animated)
}
}

任何时候你想要滚动任何给定的tableView到顶部,你可以调用以下代码:

tableView.scrollToTop(animated: true)

我必须将状态栏和导航栏的和乘以-1 *,因为它离屏幕有那么高,

self.tableView.setContentOffset(CGPointMake(0 , -1 *
(self.navigationController!.navigationBar.height +
UIApplication.sharedApplication().statusBarFrame.height) ), 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)
}
func scrollToTop() {
NSIndexPath *topItem = [NSIndexPath indexPathForItem:0 inSection:0];
[tableView scrollToRowAtIndexPath:topItem atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

调用这个函数,无论你想让UITableView滚动到顶部

这是代码ScrollTableView到顶部编程

迅速:

self.TableView.setContentOffset(CGPointMake(0, 1), animated:true)

在Swift-3中:

self.tableView.setContentOffset(CGPoint.zero, animated: true)

由于我的tableView充满了各种各样的嵌入,这是唯一工作得很好的事情:

斯威夫特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)
}

使用此代码在swift中实现UITableview:

var cell = tableView.dequeueReusableCellWithIdentifier(“cell”)
if cell == nil {
cell = UITableViewCell(style: .Value1, reuseIdentifier: “cell”)
}

迅速:

self.scripSearchView.quickListTbl?.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)

我更喜欢下面的,因为它考虑到一个插图。如果没有插入,它仍然会滚动到顶部,因为插入将是0。

tableView.setContentOffset(CGPoint(x: 0, y: -tableView.contentInset.top), animated: true)

要在完成时有一个完成,请添加此扩展

// MARK: - UIScrollView


extension UIScrollView {


/// Animate scroll to top with completion
///
/// - Parameters:
///   - duration:   TimeInterval
///   - completion: Completion block
func animateScrollToTop(withDuration duration:  TimeInterval,
completion:             @escaping (()->())) {


UIView.animate(withDuration: duration, animations: { [weak self] in
self?.setContentOffset(CGPoint.zero, animated: false)
}, completion: { finish in
guard finish else {
return
}
completion()
})
}
}


tableView.animateScrollToTop(withDuration: 0.25) {
// Finish
}

使用contenttoffset不是正确的方法。这样会更好,因为这是表视图的自然方式

tableView.scrollToRow(at: NSIndexPath.init(row: 0, section: 0) as IndexPath, at: .top, animated: true)

以下是我在iOS 11上正确运行的方法:

extension UIScrollView {
func scrollToTop(animated: Bool) {
var offset = contentOffset
if #available(iOS 11, *) {
offset.y = -adjustedContentInset.top
} else {
offset.y = -contentInset.top
}
setContentOffset(offset, animated: animated)
}
}

我遇到了一个问题,在一个空的tableView上调用尝试一些方法。下面是Swift 4处理空表视图的另一个选项。

extension UITableView {
func hasRowAtIndexPath(indexPath: IndexPath) -> Bool {
return indexPath.section < self.numberOfSections && indexPath.row < self.numberOfRows(inSection: indexPath.section)
}


func scrollToTop(animated: Bool) {
let indexPath = IndexPath(row: 0, section: 0)
if self.hasRowAtIndexPath(indexPath: indexPath) {
self.scrollToRow(at: indexPath, at: .top, animated: animated)
}
}
}

用法:

// from yourViewController or yourTableViewController
tableView.scrollToTop(animated: true)//or false

斯威夫特4:

这个方法非常有效:

//self.tableView.reloadData() if you want to use this line remember to put it before
let indexPath = IndexPath(row: 0, section: 0)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)

斯威夫特3

tableView.setContentOffset(CGPoint.zero, animated: true)

如果tableView.setContentOffset不工作。

使用:

tableView.beginUpdates()
tableView.setContentOffset(CGPoint.zero, animated: true)
tableView.endUpdates()

在iOS 11上,使用adjustedContentInset来正确地滚动到顶部,无论来电状态栏是否可见。

if (@available(iOS 11.0, *)) {
[tableView setContentOffset:CGPointMake(0, -tableView.adjustedContentInset.top) animated:YES];
} else {
[tableView setContentOffset:CGPointMake(0, -tableView.contentInset.top) animated:YES];
}

迅速:

if #available(iOS 11.0, *) {
tableView.setContentOffset(CGPoint(x: 0, y: -tableView.adjustedContentInset.top), animated: true)
} else {
tableView.setContentOffset(CGPoint(x: 0, y: -tableView.contentInset.top), animated: true)
}

斯威夫特4通过扩展,处理空表视图:

extension UITableView {
func scrollToTop(animated: Bool) {
self.setContentOffset(CGPoint.zero, animated: animated);
}
}

我使用tabBarController,我有几个节在我的表视图在每个选项卡,所以这是我最好的解决方案。

extension UITableView {


func scrollToTop(){


for index in 0...numberOfSections - 1 {
if numberOfSections > 0 && numberOfRows(inSection: index) > 0 {
scrollToRow(at: IndexPath(row: 0, section: index), at: .top, animated: true)
break
}


if index == numberOfSections - 1 {
setContentOffset(.zero, animated: true)
break
}
}


}


}

这是唯一适合我的代码片段

斯威夫特4:

    tableView.scrollRectToVisible(CGRect(x: 0, y: 0, width: 1, height: 1), animated: true)
tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
tableView.setContentOffset(CGPoint(x: 0, y: -70), animated: true)

P.S. 70是我的头和表格视图单元格的高度

不使用

 tableView.setContentOffset(.zero, animated: true)

它有时会不正确地设置偏移量。例如,在我的例子中,单元格实际上略高于带有安全区域嵌入的视图。不好的。

而不是使用

 tableView.scrollToRow(at: IndexPath(row: 0, section: 0), 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()

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)
}

这似乎是多余的,因为你已经在主队列上了,但这并不是因为它序列化了动画。

这是一个简单的UIScrollView扩展的例子,你可以在你的应用程序的任何地方使用。

1)首先,你应该创建enum和可能的滚动方向:

enum ScrollDirection {
case top, right, bottom, left


func contentOffsetWith(_ scrollView: UIScrollView) -> CGPoint {
var contentOffset = CGPoint.zero
switch self {
case .top:
contentOffset = CGPoint(x: 0, y: -scrollView.contentInset.top)
case .right:
contentOffset = CGPoint(x: scrollView.contentSize.width - scrollView.bounds.size.width, y: 0)
case .bottom:
contentOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height)
case .left:
contentOffset = CGPoint(x: -scrollView.contentInset.left, y: 0)
}
return contentOffset
}
}

2)然后添加扩展到UIScrollView:

extension UIScrollView {
func scrollTo(direction: ScrollDirection, animated: Bool = true) {
self.setContentOffset(direction.contentOffsetWith(self), animated: animated)
}
}

3)就是这样!现在你可以使用它:

myScrollView.scrollTo(.top, animated: false)

这个滚动绑定到tableView的内容大小,它看起来比滚动到CGPoint.zero更自然

如果你需要使用Objective-C或者你仍然喜欢:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[_tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];

scrollToRow解决方案,它修复了空TableView(需要搜索)的问题。

import UIKit


extension UITableView {
    

public func scrollToTop(animated: Bool = false) {
if numberOfRows(inSection: 0) > 0 {
scrollToRow(
at: .init(row: 0, section: 0),
at: .top,
animated: animated
)
}
}
    

}

我发现强迫UITableViewController在iPhone, iPad和macCatalyst (macOS)下滚动到顶部的最简单的方法如下:

  • 准备从[tableView:numberOfRowsInSection:]返回0
  • [self.tableView reloadData]
  • [self.tableView layoutIfNeeded]
  • 准备返回来自[tableView:numberOfRowsInSection:]的实际行数
  • [self.tableView reloadData]