UITableView-przewiń do góry

W moim widoku tabeli muszę przewinąć do góry. Ale nie mogę zagwarantować, że pierwszym obiektem będzie sekcja 0, rząd 0. Być może mój widok tabeli rozpocznie się od sekcji numer 5.

Więc dostaję wyjątek, kiedy dzwonię:

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

Czy istnieje inny sposób przewijania do góry widoku tabeli?

Author: rmaddy, 2009-04-07

30 answers

UITableView jest podklasą UIScrollView, więc możesz również użyć:

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

Lub

[mainTableView setContentOffset:CGPointZero animated:YES];

I w języku Swift:

mainTableView.setContentOffset(CGPointZero, animated:true)

I w Swift 3 & powyżej:

mainTableView.setContentOffset(.zero, animated: true)
 871
Author: catlan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-17 16:58:30

Uwaga: Ta odpowiedź nie jest ważna dla systemu iOS 11 i nowszych.

Wolę

[mainTableView setContentOffset:CGPointZero animated:YES];

Jeśli masz górną wstawkę w widoku tabeli, musisz ją odjąć:

[mainTableView setContentOffset:CGPointMake(0.0f, -mainTableView.contentInset.top) animated:YES];
 247
Author: fabb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-03 05:32:53

Możliwe Działania:

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

Wyłącz Przewijanie Do Góry:

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

Zmodyfikuj i używaj go zgodnie z wymaganiami.

Swift 4

  func scrollToFirstRow() {
    let indexPath = IndexPath(row: 0, section: 0)
    self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
  }
 84
Author: A.G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-25 02:08:47

Lepiej nie używać NSIndexPath (pusta tabela), ani nie zakładać, że najwyższym punktem jest CGPointZero( wstawianie treści), tego właśnie używam-

[tableView setContentOffset:CGPointMake(0.0f, -tableView.contentInset.top) animated:YES];
Mam nadzieję, że to pomoże.
 27
Author: Kof,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-13 19:53:56

Swift 4:

To działa bardzo dobrze:

//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)
 21
Author: Alessandro Ornano,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-08 12:54:00

Napotkałem problem z wywołaniem niektórych metod na pustym tableView. Oto kolejna opcja dla Swift 4, która obsługuje puste tableviews.

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

Użycie:

// from yourViewController or yourTableViewController
tableView.scrollToTop(animated: true)//or false
 20
Author: Adrian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-02 19:25:20

W systemie iOS 11 użyj adjustedContentInset, aby poprawnie przewijać do góry w obu przypadkach, gdy pasek stanu połączenia jest widoczny lub nie.

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

Swift:

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)
}
 17
Author: Thanh Pham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-08 15:34:09

DONT USE

 tableView.setContentOffset(.zero, animated: true)

Czasami może nieprawidłowo ustawić offset. Na przykład, w moim przypadku komórka znajdowała się nieco powyżej widoku z bezpiecznymi wstawkami. Niedobrze.

ZAMIAST TEGO UŻYJ

 tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
 16
Author: ScottyBlades,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-11 03:49:33

W przypadku tabel z contentInset ustawienie offsetu zawartości na CGPointZero nie będzie działać. Będzie przewijać do góry zawartości, a następnie przewijać do góry stołu.

Wzięcie pod uwagę zawartości powoduje, że zamiast tego:

[tableView setContentOffset:CGPointMake(0, -tableView.contentInset.top) animated:NO];
 12
Author: Eran Goldin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-12 07:36:00

Ten kod pozwala na przewinięcie określonej sekcji do góry

CGRect cellRect = [tableinstance rectForSection:section];
CGPoint origin = [tableinstacne convertPoint:cellRect.origin 
                                    fromView:<tableistance>];
[tableinstance setContentOffset:CGPointMake(0, origin.y)];
 10
Author: Ramesh Muthe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-22 20:33:10

Swift:

tableView.setContentOffset(CGPointZero, animated: true)
 8
Author: Esqarrouth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-07 15:04:58

Swift 3

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

Jeśli tableView.setContentOffset nie działa.

Użycie:

tableView.beginUpdates()
tableView.setContentOffset(CGPoint.zero, animated: true)
tableView.endUpdates()
 8
Author: Исмаил Хасбулатов,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-11 08:23:04

Ponieważ moje {[2] } jest pełne wszelkiego rodzaju wstawek, to była jedyna rzecz, która działała dobrze:

Swift 3

if tableView.numberOfSections > 0 && tableView.numberOfRows(inSection: 0) > 0 {
  tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
}

Swift 2

if tableView.numberOfSections > 0 && tableView.numberOfRowsInSection(0) > 0 {
  tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: .Top, animated: true)
}
 7
Author: budiDino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-01 08:37:27

Dodając do tego, co już zostało powiedziane, możesz utworzyć rozszerzenie (Swift) lub kategorię (Objective C), aby ułatwić to w przyszłości:

Swift:

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

Za każdym razem, gdy chcesz przewinąć dany widok tableView na górę, możesz wywołać następujący kod:

tableView.scrollToTop(animated: true)
 7
Author: ocwang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-11 04:55:36

Swift 5, iOS 13

Wiem, że to pytanie ma już wiele odpowiedzi, ale z mojego doświadczenia ta metoda zawsze działa: {]}

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

I jest to szczególnie ważne, jeśli pracujesz z animacjami (takimi jak klawiatura) lub niektórymi zadaniami asynchronicznymi-inne odpowiedzi często przewijają się do prawie dołu. Jeśli z jakiegoś powodu nie doprowadzi cię to do samego dna, to prawie na pewno z powodu konkurencyjnej animacji, więc obejściem jest wysłanie tej animacji do końca kolejki głównej:

DispatchQueue.main.async {
    let last = IndexPath(row: self.someArray.count - 1, section: 0)
    self.tableView.scrollToRow(at: last, at: .bottom, animated: true)
}

Może to wydawać się zbędne, ponieważ jesteś już w kolejce głównej, ale nie dlatego, że serializuje animacje.

 7
Author: bsod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-09 18:32:31

Wolę następujące, ponieważ bierze pod uwagę wstawkę. Jeśli nie ma wstawki, będzie ona nadal przewijać do góry, ponieważ wstawka będzie wynosić 0.

tableView.setContentOffset(CGPoint(x: 0, y: -tableView.contentInset.top), animated: true)
 6
Author: jacob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-04 19:01:36

Swift:

Jeśli nie masz nagłówka tableView:

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

Jeśli TAK:

tableView.setContentOffset(CGPointMake(0, -tableViewheader.frame.height   + UIApplication.sharedApplication().statusBarFrame.height ), animated: true)
 5
Author: jmcastel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-04 08:23:18

Oto, czego używam do poprawnego działania na 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
Author: Hans Brende,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-22 20:32:21

In Swift 5, Thanks @ Adrian ' s answer a lot

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

}

Użycie:

tableView.scrollToTop()
 4
Author: dengST30,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-30 08:32:57

Używanie contentOffset nie jest właściwym sposobem. tak byłoby lepiej, ponieważ jest to naturalny sposób widoku tabeli

tableView.scrollToRow(at: NSIndexPath.init(row: 0, section: 0) as IndexPath, at: .top, animated: true)
 3
Author: Gulz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-12 04:41:46

To był jedyny fragment kodu, który zadziałał dla mnie

Swift 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 to wysokość mojej komórki nagłówka i widoku tabeli

 3
Author: jimmyruby,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-10 05:14:54
func scrollToTop() {
        NSIndexPath *topItem = [NSIndexPath indexPathForItem:0 inSection:0];
        [tableView scrollToRowAtIndexPath:topItem atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

Wywołaj tę funkcję gdziekolwiek chcesz UITableView przewiń do góry

 2
Author: Sayali Shinde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-04 06:24:37

Swift 4 poprzez rozszerzenie, obsługuje pusty widok tabeli:

extension UITableView {
    func scrollToTop(animated: Bool) {
        self.setContentOffset(CGPoint.zero, animated: animated);
    }
}
 2
Author: Shawn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-20 06:23:32

Używam tabBarController i mam kilka sekcji w moim tableview na każdej karcie, więc jest to najlepsze rozwiązanie dla mnie.

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

    }

}
 2
Author: Okan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-07 10:22:59

Musiałem dodać mnożenie przez -1 * do sumy paska stanu i paska nawigacyjnego, ponieważ szedł tak wysoko poza ekran,

self.tableView.setContentOffset(CGPointMake(0 , -1 * 
  (self.navigationController!.navigationBar.height +  
  UIApplication.sharedApplication().statusBarFrame.height) ), animated:true)
 1
Author: Carlos.V,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-12 23:58:51

In swift

Twój wiersz = selectioncellRowNumber twoja sekcja jeśli masz = selectionNumber jeśli nie masz ustawionego to zero

/ / UITableViewScrollPosition.Middle or Bottom or Top

var lastIndex = NSIndexPath(forRow:  selectioncellRowNumber, inSection: selectionNumber)
self.tableView.scrollToRowAtIndexPath(lastIndex, atScrollPosition: UITableViewScrollPosition.Middle, animated: true)
 1
Author: idris yıldız,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-29 09:07:57

Oto Kod Do Przewijania Na Górę Programowo

Swift:

self.TableView.setContentOffset(CGPointMake(0, 1), animated:true)
 1
Author: Kavin Kumar Arumugam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-04 06:29:00

W Języku Swift-3:

self.tableView.setContentOffset(CGPoint.zero, animated: true)
 1
Author: Jeni Khant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-24 07:41:50

Oto prosty przykład rozszerzenia UIScrollView, którego możesz używać wszędzie w swojej aplikacji.

1) Najpierw należy utworzyć {[3] } z możliwymi kierunkami przewijania:

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) Następnie dodaj rozszerzenie do UIScrollView:

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

3) to jest to! Teraz możesz go użyć:

myScrollView.scrollTo(.top, animated: false)

To przewijanie wiąże się z rozmiarem zawartości tableView i wygląda bardziej naturalnie niż przewijanie do CGPoint.zero

 1
Author: Roman Shinyavski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-11 06:01:27

Jeśli chcesz przenieść animację przewijania w tabeli, użyj tego kodu. Przewijanie przenieś do góry z animacją .5 sekund.

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

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

[UIView commitAnimations];
 0
Author: Matheus Veloza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-12 03:58:29