2012-09-20 9 views
17

Questa mattina ho appena installato nuovo Xcode che include iOS 6.iOS UITableView scrollToRowAtIndexPath non funziona più

ho una visione tabella caricata con un file plist contenente i capitoli e le linee. I capitoli definiscono le sezioni.

L'utente seleziona capitolo e riga e la vista tabella viene automaticamente spostata nella posizione corretta (in viewDidLoad).

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:linePos inSection:chapterPos]; 
[self.tableView scrollToRowAtIndexPath:indexPath 
    atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

funziona perfettamente con il simulatore iOS5.

Provando questo nel simulatore iOS 6 lo scorrimento non viene eseguito. Non ho errori Ho controllato, linePos e chapterPos ricevono valori corretti ma lo scroll non viene eseguito.

Qualche idea, perché?

+4

solo per aggiungere dolore e sofferenza è rotto di nuovo 5 anni dopo in iOS 11. –

risposta

26

Per le versioni recenti di iOS, leggere la risposta di Fyodor Volchyok. Si noti che non è contrassegnato come risposta accettata semplicemente perché al momento della prima domanda (settembre 2012), la risposta corrente era la soluzione operativa. Anche le versioni più recenti di iOS hanno lo stesso problema risolto dalla risposta di Fyodor Volchyok, quindi è necessario fare +1 sulla sua risposta in quel momento.


Ho trovato la risposta. Devo ricaricare prima i dati nel Tableview

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:linePos inSection:chapterPos]; 

[self.tableView reloadData]; 

[self.tableView scrollToRowAtIndexPath:indexPath 
    atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

Anche se ho trovato la risposta non so il motivo per cui sta lavorando in iOS5 e non in iOS6.

EDIT

Forse dovrei aggiungere che anche se funzionava, ero ancora avendo un problema nella visualizzazione dell'ultima fila e postato una domanda per questo

UItableview scrollToRowAtIndexPath not displaying last row correctly

Come @ Raj ha anche chiesto, dovrei dire che stavo attivando quello nel viewDidLoad. Per correggere il problema dell'ultima riga che non veniva visualizzata correttamente, dovevo inserirla nello viewDidAppear.

+0

Grazie per queste informazioni, mi sono imbattuto nella stessa cosa. Ho anche notato che non anima lo scorrimento della tabella, lo visualizza solo sulla riga selezionata. –

+0

Stai attivando la chiamata scrollToRowAtIndexPath nel tuo metodo -viewDidLoad? –

40

Objective-C

[self.tableView reloadData]; 
dispatch_async(dispatch_get_main_queue(), ^{ 
     NSIndexPath *rowIndexPath = [NSIndexPath indexPathForRow:3 inSection:0]; 
     [self.tableView scrollToRowAtIndexPath:rowIndexPath atScrollPosition:UITableViewScrollPositionMiddle animated:YES]; 
}); 

Swift

tableView.reloadData() 
DispatchQueue.main.async { 
    let indexPath = IndexPath(row: linePos, section: chapterPos) 
    self.tableView.scrollToRow(at: indexPath, at: .top, animated: true) 
} 
+0

È una correzione importante, senza la quale l'applicazione potrebbe bloccarsi accidentalmente, a seconda dei processi reloadData. – BootMaker

+3

questa è l'unica cosa che funziona per me (iOS 9.1). Il 'scrollToRowAtIndexPath' non è mai riuscito a scorrere fino alla cella molto in basso a meno che non l'ho spostato in' dispatch_async (dispatch_get_main_queue(), {...} 'anche se' scrollToRowAtIndexPath' era già stato chiamato dal thread principale –

+0

Questa è probabilmente la risposta giusta , Metti questo nella viewDidAppear: –

1

Dopo iOS7 proprietà automaticallyAdjustsScrollViewInsets di UIViewController di default è YES. Il sistema modificherà lo contentOffset di tableView quando viene premuto il controller della vista. Anche tu chiami [self.tableView scrollToRowAtIndexPath:rowIndexPath atScrollPosition:UITableViewScrollPositionNone animated:NO]; nel viewWillAppear. Anche lo contentOffset verrà modificato dal sistema dopo viewWillAppear. Quindi la mia soluzione è:

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    self.automaticallyAdjustsScrollViewInsets = NO; 

    /// any other codes 
} 

- (void)viewWillLayoutSubviews { 
    self.tableView.contentInset = UIEdgeInsetsMake(self.topLayoutGuide.length, 0, 0, 0); 
} 

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 

    // change tableView data source 

    [self.tableView reloadData]; 
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[self.dataSourceArray count] - 1 inSection:0]; 
    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:NO]; 
} 
0

Sto aggiungendo questa risposta come aggiunta alla risposta di Fyodor Volchyok. Ho anche scoperto che il dispacciamento risolve il problema. Sono stato in grado di trovare una soluzione alternativa che non spedisca.

self.tableView.reloadData() 
let index = // the desired index path 

// For some reason, requesting the cell prior to 
// scrolling was enough to workaround the issue. 
self.tableView.cellForRowAtIndexPath(index) 

self.tableView.scrollToRowAtIndexPath(index, atScrollPosition: .Top, animated: false) 
+0

Ho avuto un problema con il multithreading: quando uso invio, uno dei miei metodi inizia a chiamare due volte e ora funziona come per magia !!! :-) –

0
risposta di

Fyodor Volchyok a Swift:

tableView.reloadData() 
let indexPath = NSIndexPath(forRow: linePos, inSection: chapterPos) 
// make sure the scroll is done after data reload was finished 
dispatch_async(dispatch_get_main_queue()) { 
    self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true) 
} 
0

ha funzionato per me in ios11

self.tableView.estimatedRowHeight = 0; 
self.tableView.estimatedSectionFooterHeight = 0; 
self.tableView.estimatedSectionHeaderHeight = 0 

dispatch_async(dispatch_get_main_queue(), ^{ 
    NSInteger numberOfSections = self.tableView.numberOfSections; 
    if (numberOfSections > 0) 
    { 
    NSInteger lastSection = numberOfSections - 1; 
    NSInteger lastRowInLastSections = [self.tableView numberOfRowsInSection:lastSection] - 1; 

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:lastRowInLastSections inSection:lastSection]; 
    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:isAnimated]; 
} 
}); 
1

Mi sono imbattuto in un altro problema (probabilmente un bug) con scrollToRowAtIndexPath specificamente su un iPhone X in esecuzione ios11. Il mio tavolo ha alcune centinaia di sezioni e in modalità compressa ~ 10 si inseriscono nello schermo visibile. Quando IndexPath si è approfondito, lo scorrimento è gradualmente scomparso.

Ad esempio, quando volevo che la ricerca trovasse l'elemento nella riga 30, ScrollPositionTop avrebbe una riga aggiuntiva prima della riga effettiva che mi aspetto di essere in alto.

E come ho provato a cercare file più profonde, ha iniziato a rimanere indietro ancora di più dove per dire qualcosa oltre 100 righe in profondità o giù di lì, la riga prevista non è nemmeno arrivata nell'area visibile.

La soluzione che ho trovato finora è animata: NO per lo scorrimento all'interno di dispatch_async, quindi funziona senza problemi.

Problemi correlati