2012-05-06 9 views
10

non stiamo parlando di migliaia di righe o altro, anche se se ci fosse un modo per far salire le cose così in alto, mi piacerebbe.animare un gran numero di righe/sezioni in UITableView scarse prestazioni

Ho una tabella con 27 sezioni e 180 righe distribuite su tutte le sezioni e lo scenario in cui mi sto attualmente bloccando è quando animo le cose a uno stato di modello con solo 3 sezioni e 5 righe e (anche peggio) di nuovo indietro.

Sto eseguendo il batching di tutte le animazioni con beginUpdates/endUpdates. La mia app si blocca piuttosto per 1-2 secondi su un iphone4 mentre capisce le cose, quindi iniziano le animazioni.

Ho provato ad animare la rimozione/aggiunta di ogni riga, mantenendo le sezioni intorno (e lasciando il conteggio delle righe a 0 nel caso di rimozione) e anche animando solo la rimozione/l'inserimento delle sezioni stesse (quando il conteggio delle righe sarebbe sceso a 0). Avrei pensato che quest'ultimo avrebbe dato prestazioni migliori, ma non ha cambiato nulla.

C'è qualcosa che può essere fatto sull'app per accelerare? In questo momento ho un po 'di codice alquanto grossolano per salvare le singole animazioni se ce ne sono più di 20, optando invece solo per ricaricare i dati.

modifica codice di esempio che presenta il problema. Le prestazioni di questo codice sono leggermente migliori rispetto al codice monotouch equivalente (che è quello che stavo usando prima), ma è ancora piuttosto brutto.

#import "TableViewController.h" 

@interface MyTableViewDataSource : NSObject<UITableViewDataSource> { 
    int rows; 
}; 

@end 

@implementation MyTableViewDataSource 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return 1; 
} 

- (void)setRowCount:(int)r 
{ 
    rows = r; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return rows; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (!cell) 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 

    cell.textLabel.text = [NSString stringWithFormat:@"row %d", indexPath.row]; 

    return cell; 
} 

@end 

@implementation MyTableViewController { 
    UIBarButtonItem *populateButtonItem; 
}; 

- (id)initWithStyle:(UITableViewStyle)style 
{ 
    self = [super initWithStyle:style]; 
    if (self) { 
     populateButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Populate" style:UIBarButtonItemStylePlain target:self action:@selector(populateDataSource)]; 
    } 
    return self; 
} 

- (void)populateDataSource 
{ 
    NSMutableArray* new_rows = [[NSMutableArray alloc] init]; 
    [((MyTableViewDataSource*)self.tableView.dataSource) setRowCount:200]; 

    for (int i = 0; i < 200; i ++) 
     [new_rows addObject:[NSIndexPath indexPathForRow:i inSection:0]]; 

    [self.tableView beginUpdates]; 
    [self.tableView insertRowsAtIndexPaths:new_rows withRowAnimation:UITableViewRowAnimationAutomatic]; 
    [self.tableView endUpdates]; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.tableView.dataSource = [[MyTableViewDataSource alloc] init]; 
    self.navigationItem.rightBarButtonItem = populateButtonItem; 
} 

@end 
+1

La mia prima ipotesi sarebbe che le celle del tavolo sono il colpevole. Stai usando celle personalizzate? – lyricsboy

+0

Puoi pubblicare del codice? Inoltre: il tuo UITableViewCells è opaco? – Ahti

+1

Che cosa indicano gli strumenti è il collo di bottiglia? Li stai eliminando in massa con una sola chiamata deleteRowsAtIndexPaths: ... o molte chiamate individuali? Stai chiamando reloadData nel mezzo di animazioni (non devi mai farlo)? –

risposta

3

ha senso solo per animare le righe visibili. Invece di fare l'animazione per tutte le righe che stai inserendo, considera solo l'animazione dell'inserimento di quelle file che saranno visibili.

Inoltre, sei sicuro che sia l'animazione a causare il ritardo? Ricevi lo stesso ritardo se superi l'UITableViewRowAnimationNone per l'animazione o è più veloce? Se è più veloce, ripeti, evita di animare quegli inserimenti che non saranno visibili.(È possibile capire quali file sono attualmente visibili utilizzando -indexPathsForVisibleRows.) Se non è più veloce, il problema probabilmente non è correlato all'animazione, ma piuttosto il sovraccarico di inserire poche centinaia di righe contemporaneamente. Ricaricare l'intera tabella come stai facendo ora è un'opzione; l'inserimento delle righe in lotti più piccoli è un altro.

Infine, sarebbe opportuno profilare l'app con gli strumenti mentre si effettua l'inserimento. Avrai un'idea migliore di ciò che l'app sta facendo durante quel ritardo, e questo è il primo passo verso l'eliminazione del ritardo.

+0

evitare di animare le righe che non saranno visibili è davvero quello che mi piacerebbe fare. Ma non sembra che indexPathsForVisibleRows mi dia quello che voglio - probabilmente l'animazione riempirà l'area visibile, quindi le righe attualmente visibili non sono quelle che voglio animare ... a meno che indexPathsForVisibleRows stia in qualche modo prendendo in considerazione delle righe (e/o sezioni) che aggiungerò/eliminerò. – toshok

+0

... detto questo, il passaggio a UITableViewRowAnimationNone era il ticket. C'è ancora una pausa iniziale molto piccola, appena percettibile. Quindi forse non è tanto il numero di animazioni, ma forse lo z-ordering (o il clipping?) Che UITableView sta facendo quando passa nei vari altri membri di enum che stava causando il rallentamento – toshok

0

Provare a testare la stessa funzionalità con alcune serie di stringhe hardcoded e vedere problema è scomparso. Se il problema è ancora lì, significa che il problema è con il rendering non con i dati.

Per diversi tipi di animazione ci sono alcuni controlli personalizzati già realizzati in cui è possibile avere l'animazione più veloce con qualche bella implementazione di una fodera: Here dare un'occhiata.

1

Stai usando UITableViewRowAnimationAutomatic (Riferimento: La vista tabella sceglie uno stile di animazione appropriato per voi (Introdotto in iOS 5.0)..), E per qualche motivo, la vista della tabella sceglie una pessima uno, che sfuma in tutta righe durante l'espansione. Cambiare l'opacità su 200 UIViews durante il ridimensionamento della cornice e spostandoli attorno a HAS per essere lenti. :)

Si può solo fare questo:

[self.tableView insertRowsAtIndexPaths:new_rows withRowAnimation:UITableViewRowAnimationNone]; 

Ciò consentirà di ridurre le animazioni per l'animazione molto di base del UITableView quando si inseriscono le righe, che, a mio parere, è assolutamente sufficiente durante l'inserimento che molti.

+0

sì, quello era davvero il trucco. – toshok

Problemi correlati