UITableView - yukarı kaydır


393

Tablo görünümümde en üste kaydırmam gerekiyor. Ancak ilk nesnenin bölüm 0, satır 0 olacağını garanti edemem. Tablo görünümüm bölüm 5'ten başlayabilir.

Bu yüzden bir istisna alıyorum:

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

Tablo görünümünün en üstüne kaydırmanın başka bir yolu var mı?

Yanıtlar:


857

UITableView, UIScrollView öğesinin bir alt sınıfıdır, bu nedenle şunları da kullanabilirsiniz:

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

Veya

[mainTableView setContentOffset:CGPointZero animated:YES];

Ve Swift'te:

mainTableView.setContentOffset(CGPointZero, animated:true)

Ve Swift 3 ve üzeri:

mainTableView.setContentOffset(.zero, animated: true)

9
Bunu ilk olarak CGRectMake'e (0, 0, 0, 0) eşdeğer olan CGRectZero ile denedim. Bu işe yaramaz, ancak garip bir şekilde yukarıdakiler işe yarar. Sanırım pozitif bir genişliğe ve yüksekliğe ihtiyacı var. Teşekkür ederim.
Keller

5
Animasyon isteyeceksiniz : NO bunu scrollToRowAtIndexPath içinde çalıştırırsanız: tablonun doğru konumda başlamasını sağlamak için. Umarım yardımcı olur!
Ocak'ta Fattie

3
@ hasan83 CGRectMake (0, 0, 0, 0) veya CGRectZero görünür bir rekt değildir. Ayrıca [mainTableView setContentOffset: animasyonlu CGPointZero: YES]; daha güzel bir ifadedir.
catlan

8
Herkes iOS11 bu tüm kırık ve bazı durumlarda doğru kaydırma olmadığını fark ettiniz mi?
Peter Lapisu

11
@PeterLapisu self.tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: UITableViewScrollPosition.top, animated: true)iOS 11'de çalışıyor gibi görünüyor
Jordan S

246

Not : Bu cevap iOS 11 ve sonraki sürümler için geçerli değildir.

tercih ederim

[mainTableView setContentOffset:CGPointZero animated:YES];

Tablo görünümünüzde üstte bir iç metin varsa, onu çıkarmanız gerekir:

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

12
Domates, domates. Hmm ... Bu yazılı olarak çok açık bir şekilde ortaya çıkmıyor.
FreeAsInBeer

14
Tablo üstbilgisi veya altbilgisi görünümleriniz olduğunda ve bunların da dahil edilmesini istediğinizde kullanmanın en iyi yolu budur.
mafonya

6
Bu gerçekten açık bir koddur, ancak tableViewsıfırdan çıkmadığınız zaman işe yaramaz contentInset. Örneğin: tableView.contentInset = UIEdgeInsetsMake(5.0f, 0.0f, 250.0f, 0.0f);. Bu durumda, kodunuzda tableViewkaydırılır (0.0f, 5.0f).
tolgamorf

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

3
İOS 11'de -scrollView.adjustedContentInset.topbunun yerine kullanmayı düşünmelisiniz .
Marián Černý

79

Muhtemel Eylemler:

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

Başa Kaydır özelliğini devre dışı bırak:

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

İhtiyaca göre değiştirin ve kullanın.

Hızlı 4

  func scrollToFirstRow() {
    let indexPath = IndexPath(row: 0, section: 0)
    self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
  }

İşte bu çözüm, mükemmel - scrollToFirstRow
Mehul

Mükemmel özet. Bölüm başlıklarına sahip olduğunuzda option4 scrollToHeader'ı kullanmanız gerekir.
Vincent

Tablo Görünümü'nün üstündeki bir arama çubuğuna gitmenin bir yolu var mı?
Tyler Rutt

27

NSIndexPath (boş tablo) kullanmamak veya üst noktanın CGPointZero (içerik ekleri) olduğunu varsaymak daha iyidir, kullandığım şey budur -

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

Bu yardımcı olur umarım.


İOS

21

Hızlı 4 :

Bu çok iyi çalışıyor:

//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
Tablonuzda bir tableHeaderView varsa ve satır içi ise (içerikle kayar)
finneycanhelp

1
Ben hem düz hem de bir UITableViewStyleGrouped(başlıklar içeriği ile kaydırır) ve bu kod çalışır. Ana iş parçacığında olduğunuzdan ve görünüm göründükten sonra bu kodu başlattığınızdan emin olun ( viewDidAppear). Hâlâ sorun yaşıyorsanız kodu içine koymaya çalışın:DispatchQueue.main.asyncAfter(deadline: .now()+0.1, execute: { // the code }
Alessandro Ornano

1
Teşekkür ederim. Seni ilk hücreye götürecek. Ancak, tablo görünümü üstbilgisini göstermez.
finneycanhelp

TableView herhangi bir nedenle boşsa (0 satırında 0 bölümünde 0 yok)
Maxim Skryabin

17

Boş bir yöntem denemek isteyen bir sorunla karşılaştım tableView. Swift 4 için boş tablo görüntülerini işleyen başka bir seçenek.

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

Kullanımı:

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

Bu, herhangi bir tablo üstbilgisini veya bölüm üstbilgisini dikkate almaz.
rmaddy

16

KULLANIM YOK

 tableView.setContentOffset(.zero, animated: true)

Bazen ofseti yanlış ayarlayabilir. Örneğin, benim durumumda, hücre aslında güvenli alan ekleri ile görünümün biraz üzerindeydi. İyi değil.

INSTEAD KULLANIM

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

1
Mükemmel çözüm.
Bebek Groot

Tam olarak aradığım şey, teşekkürler.
Simon

Bu çözümlerin hiçbiri geçerli değildir. Birincisi iOS 11 veya sonraki sürümlerde çalışmıyor. Tablo görünümü bir tablo üstbilgisine sahipse veya ilk bölümün üstte ilk satırı gerçekten istemediğiniz ve herhangi bir üstbilgi göstermeyi ummadığınız sürece, ikinci bölümün bir bölüm üstbilgisi varsa ikincisi çalışmaz.
rmaddy

@rmaddy en iyi çözüm nedir?
ScottyBlades

15

İOS 11'de, adjustedContentInsetarama sırasında durum çubuğu görünür olduğunda veya görünmediğinde her iki durumda da doğru şekilde yukarı kaydırmak için kullanın .

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

12

A içeren tablolar contentInsetiçin içerik ofsetiniCGPointZero çalışmaz. İçerik üstüne kaydırır, masa üstüne kaydırır.

İçerik iç metinini hesaba katmak bunun yerine şunu üretir:

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

1
Teşekkürler, CGPointZero olarak ayarlamaya devam ettim ve bunun neden olduğunu anlayamadım.
johnrechd

İOS

10

Bu kod, belirli bir bölümü yukarı kaydırmanıza izin verir

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

Bu en basit kod ve Tamam çalıştı. Aslında CGPointMake (0.0f, 0.0f) koydum. Şerefe!
Felipe

Bu kod bölümü kaydırmak için çok kullanışlıdır
srinivas n


8

Hızlı 3

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

Eğer tableView.setContentOffset işe yaramazsa.

kullanın:

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

1
Bu iOS 11 veya sonraki sürümler için geçerli değildir.
rmaddy

7

Benim tableViewher türlü iç metinle dolu olduğu için, iyi çalışan tek şey buydu:

Hızlı 3

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

Hızlı 2

if tableView.numberOfSections > 0 && tableView.numberOfRowsInSection(0) > 0 {
  tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: .Top, animated: true)
}

Bu benim için daha yararlı oldu
Tejzeratul

büyük cevap, takdir
Jeremy Bader

7

Daha önce söylenenlere ekleyerek, gelecekte bunu kolaylaştırmak için bir uzantı (Swift) veya kategori (Hedef C) oluşturabilirsiniz:

Swift:

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

Herhangi bir tabloyu istediğiniz zaman kaydırmak istediğinizde aşağıdaki kodu arayabilirsiniz:

tableView.scrollToTop(animated: true)

2
İOS

6

Bir iç metni dikkate aldığı için aşağıdakileri tercih ederim. İç metin yoksa, iç metin 0 olacağından yine de yukarı kaydırılır.

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

İOS

5

Swift:

tableView başlığınız yoksa:

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

Öyleyse :

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

5

Swift 5, iOS 13

Bu sorunun zaten çok fazla cevabı olduğunu biliyorum, ancak deneyimlerime göre, her zaman çalışan sadece bir yöntem var:

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

Zaman uyumsuz, klavyeyle canlandırılan tablolar vb. Üzerinde çalışıyorsanız, diğer yanıtlar mutlak alt kısma değil, hemen hemen aşağıya kayar . Bu yöntem sizi her seferinde bir tablonun mutlak sonuna götürecektir.


Ayrıca bir bölüm olup olmadığını da kontrol etmeniz gerekiyor
Onur Tuna

4

İşte iOS 11'de düzgün çalışmak için kullandığım şeyler:

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'te, Teşekkürler @ Adrian'ın cevabı çok

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

}

Kullanımı:

tableView.scrollToTop()

2
1. Bu, Swift 4'te de geçerlidir. 2. Bir tablo başlığı veya bir bölüm başlığı varsa bu çalışmaz.
rmaddy

3

contentOffset kullanmak doğru yol değildir. bu tablo görünümünün doğal yolu olduğu için daha iyi olurdu

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

2
Tablo üstbilgisi veya bölüm üstbilgisi varsa bu çalışmaz.
rmaddy

3

Bu benim için çalışan tek kod snippet'iydi

Hızlı 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, üstbilgim ve tablo görünümü hücresimin yüksekliği


Bu, yukarı kaydırmanın doğru yolundan uzaktır. Yalnızca içerik dengesini ayarlamak için üç ayrı satır kullanmak mantıklı değildir. Sadece son satıra ihtiyaç vardır, ancak belirli bir ofseti sabit kodlamak doğru çözüm değildir.
rmaddy

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

bu işlevi UITableView kaydırmak istediğiniz yere çağır


2

Uzantı yoluyla Swift 4 , boş tablo görünümünü işler:

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

Bu, iOS 11'den itibaren geçerli değildir.
rmaddy

2

TabBarController kullanın ve her sekmesinde benim tableview birkaç bölüm var, bu yüzden bu benim için en iyi çözümdür.

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 *Durum çubuğunun ve gezinme çubuğunun toplamına çarpmayı eklemek zorunda kaldım , çünkü bu yükseklik ekrandan çıkıyordu,

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

1

hızlıca

Satırınız = selectioncellRowNot varsa bölümünüzü = ayarlamadıysanız, selectionNumber sıfıra ayarlar

//UITableViewScrollPosition.Middle veya Bottom veya Top

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

1

ScrollTableView Programlı Başa Dönmek İçin Kod İşte

Swift:

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

1

Swift-3'te:

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

0

Tabloda kaydırma animasyonu taşımak isterseniz, bu kodu kullanın. Kaydırma, animasyonda .5 saniye içinde en üste gider.

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

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

[UIView commitAnimations];

0

Swift ile:

self.scripSearchView.quickListTbl?.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.