UITableView-一番上までスクロール


393

テーブルビューで、一番上までスクロールする必要があります。しかし、最初のオブジェクトがセクション0、行0になることは保証できません。テーブルビューがセクション番号5から始まる可能性があります。

だから私が呼び出すと例外が発生します:

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

テーブルビューの上部にスクロールする別の方法はありますか?

回答:


857

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)

9
私はこれを最初にCGRectZeroで試しました。これはCGRectMake(0、0、0、0)と同等です。これは機能しませんが、奇妙なことに上記は機能します。正の幅と高さが必要だと思います。ありがとうございました。
Keller

5
テーブルを正しい位置で開始させるために、scrollToRowAtIndexPath:でこれを実行する場合、animationed :NOが必要になることに注意してください。それが役に立てば幸い!
Fattie、2014年

3
@ hasan83 CGRectMake(0、0、0、0)またはCGRectZeroは可視の四角形ではありません。また、[mainTableView setContentOffset:CGPointZero animated:YES]とも言えます。きれいな表現です。
カトラン2015

8
誰かがiOS11でこれがすべて壊れていて、場合によっては正しくスクロールしないことに気付いた人はいますか?
Peter Lapisu、2018年

11
@PeterLapisu self.tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: UITableViewScrollPosition.top, animated: true)はiOS 11で動作しているようです
ジョーダンS

246

:この回答はiOS 11以降では無効です。

私は好む

[mainTableView setContentOffset:CGPointZero animated:YES];

テーブルビューに上部インセットがある場合は、それを差し引く必要があります。

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

12
トマト、トマト。うーん...それは書面ではあまりわかりません。
FreeAsInBeer

14
これは、テーブルヘッダーまたはフッタービューがあり、それらも含めたい場合に使用する最良の方法です。
mafonya

6
これは確かに明確なコードですが、上からtableViewゼロでない場合は機能しませんcontentInset。次に例を示しますtableView.contentInset = UIEdgeInsetsMake(5.0f, 0.0f, 250.0f, 0.0f);。その場合は、コードでにtableViewスクロールし(0.0f, 5.0f)ます。
tolgamorf 2013年

25
私の以前のコメントの解決策:[tableView setContentOffset:CGPointMake(0.0f, -tableView.contentInset.top) animated:YES];
tolgamorf 2013年

3
iOS 11 -scrollView.adjustedContentInset.topでは、代わりに使用することを検討する必要があります。
マリアンチェルニー

79

可能なアクション:

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

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

それが完璧なソリューションです-scrollToFirstRow
Mehul

素晴らしい要約。セクションヘッダーがある場合は、option4 scrollToHeaderを使用する必要があります。
Vincent

Tableviewの上にある検索バーまでスクロールする方法はありますか?
タイラー・ラット

27

NSIndexPath(空のテーブル)を使用しないこと、またはトップポイントがCGPointZero(コンテンツインセット)であると想定しないことをお勧めします。これを使用します-

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

お役に立てれば。


iOS 11以降は無効
。– rmaddy

21

Swift 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にtableHeaderViewがあり、それがインラインである(コンテンツと共にスクロールする)場合は
finneycanhelp

1
私はプレーンとa UITableViewStyleGrouped(ヘッダーはコンテンツと共にスクロールします)の両方を持っていて、このコードは機能します。メインスレッドにいることを確認し、ビューが表示された後にこのコードを起動します(viewDidAppear)。:あなたはまだ問題が、この内のコードを配置しようとしている場合DispatchQueue.main.asyncAfter(deadline: .now()+0.1, execute: { // the code }
アレッサンドロオルナーノ

1
ありがとうございました。最初のセルに移動します。ただし、テーブルビューのヘッダーは表示されません。
finneycanhelp 2018年

何らかの理由でtableViewが空の場合、これは失敗します(0行の0セクションにセルがない)
Maxim Skryabin

17

空のでいくつかのメソッドを試すという問題が発生しました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

これは、テーブルヘッダーやセクションヘッダーを考慮していません。
rmaddy

16

使用しないでください

 tableView.setContentOffset(.zero, animated: true)

オフセットが正しく設定されない場合があります。たとえば、私の場合、実際にはセルはビューの少し上にあり、セーフエリアが挿入されています。良くない。

即時使用

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

1
完璧なソリューション。
Baby Groot

まさに私が探していたもの、ありがとう。
Simon

これらのソリューションはどちらも無効です。1つ目はiOS 11以降では機能しません。2番目は、テーブルビューにテーブルヘッダーがある場合、または最初のセクションにセクションヘッダーがある場合、最初の行を一番上にしたいがヘッダーを表示する必要がない場合を除き、機能しません。
rmaddy

@rmaddy最善の解決策は何ですか?
ScottyBlades

15

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

12

あるテーブルの場合 contentInset、コンテンツオフセットをに設定してCGPointZeroも機能しません。コンテンツの上部にスクロールするか、テーブルの上部にスクロールします。

代わりにコンテンツインセットを考慮すると、次のようになります。

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

1
ありがとう、私はそれをCGPointZeroに設定し続け、これがなぜ起こっているのか理解できませんでした。
johnrechd

iOS 11以降は無効です
。– rmaddy

10

このコードでは、特定のセクションを上にスクロールできます

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

これは最も単純なコードで、問題なく動作しました。実際にCGPointMake(0.0f、0.0f)を入れました。乾杯!
フェリペ

このコードは、セクションを上にスクロールするのに非常に便利です
srinivas n


8

スウィフト3

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

もし tableView.setContentOffsetしない。

使用する:

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

1
これはiOS 11以降では無効です。
rmaddy

7

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

これは私にとってより便利でした
Tejzeratul 2017

すばらしい回答、感謝
Jeremy Bader 2017

7

すでに述べられていることに加えて、拡張機能(Swift)またはカテゴリ(Objective C)を作成して、これを将来的に簡単にすることができます。

迅速:

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

特定のtableViewを一番上にスクロールしたいときはいつでも、次のコードを呼び出すことができます。

tableView.scrollToTop(animated: true)

2
iOS 11以降は無効です
。– rmaddy

6

はめ込みを考慮に入れるので、私は以下を好む。インセットがない場合でも、インセットは0になるため、一番上までスクロールします。

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

iOS 11以降は無効
。– rmaddy

5

スウィフト:

tableViewヘッダーがない場合:

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

もしそうなら:

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

5

Swift 5、iOS 13

この質問にはすでに多くの答えがあることを知っていますが、私の経験から、常に機能する方法は1つしかありません。

tableView.scrollToRow(at: IndexPath(row: someArray.count - 1, section: 0), at: .bottom, animated: true)

非同期、キーボードでアニメーション化するテーブルなどで作業している場合、他の回答は、多くの場合、絶対的な底ではなく、ほぼ底までスクロールします。このメソッドを使用すると、常にテーブルの完全な終わりに到達します。


セクションがあるかどうかも確認する必要があります
Onur Tuna

4

これが私が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)
    }
}

4

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

2
1.これはSwift 4でも有効です。2.テーブルヘッダーまたはセクションヘッダーがある場合、これは機能しません。
rmaddy

3

contentOffsetの使用は正しい方法ではありません。テーブルビューの自然な方法なので、これはより良いでしょう

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

2
これは、テーブルヘッダーまたはセクションヘッダーがある場合は機能しません。
rmaddy

3

これは私のために働いた唯一のコードスニペットでした

スウィフト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)

PS 70は、ヘッダーとテーブルビューセルの高さです。


これは、上にスクロールする正しい方法とはかけ離れています。コンテンツのオフセットを設定するためだけに3つの別々の行を使用しても意味がありません。最後の行だけが必要ですが、特定のオフセットをハードコーディングすることは正しい解決策ではありません。
rmaddy

2
func scrollToTop() {
        NSIndexPath *topItem = [NSIndexPath indexPathForItem:0 inSection:0];
        [tableView scrollToRowAtIndexPath:topItem atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

UITableViewを上にスクロールする場所にこの関数を呼び出します


2

拡張機能によるSwift 4、空のテーブルビューを処理します。

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

これはiOS 11では無効です
。– rmaddy

2

私は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
            }
        }

    }

}

1

-1 *ステータスバーとナビゲーションバーの合計に乗算を追加する必要がありました。これは、画面からその高さになるためです。

self.tableView.setContentOffset(CGPointMake(0 , -1 * 
  (self.navigationController!.navigationBar.height +  
  UIApplication.sharedApplication().statusBarFrame.height) ), animated:true)

1

迅速に

行= selectioncellRowNumberがある場合はセクション=設定していない場合はselectionNumberがゼロ

//UITableViewScrollPosition.MiddleまたはBottomまたはTop

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



0

テーブルでスクロールアニメーションを移動する場合は、このコードを使用します。スクロールは、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];

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.