Attualmente sto implementando la conservazione/ripristino automatico dello stato in un'app solo iOS6.Strane chiamate a modelIdentifierForElementAtIndexPath: inView: (UIDataSourceModelAssociation)
Per un restauro di una vista tabella, ho aggiunto il protocollo UIDataSourceModelAssociation
ai miei controller di vista tavolo e implementato
- (NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)idx inView:(UIView *)view
e
- (NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view
Quando si preme il tasto home, il i metodi di conservazione dello stato, incluso modelIdentifierForElementAtIndexPath:iView:
, vengono richiamati come previsto e restituiscono stringhe di identificatore valido per i percorsi dell'indice specificati.
Quando si uccide l'app e la si riavvia, i lavori di ripristino dello stato sono più o meno. Cioè l'app riapre la vista tabella corretta. Tuttavia, la vista tabella viene sempre spostata verso l'alto, anche se prima era stata spostata in un'altra posizione.
Ecco l'implementazione dei metodi UIDataSourceModelAssociation
nel mio controller di visualizzazione tabella. Niente di speciale succedendo in là (la proprietà NdlFriend::accountUid
restituisce una stringa identificatore univoco per un determinato record NdlFriend):
#pragma mark - UIDataSourceModelAssociation
- (NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)idx inView:(UIView *)view
{
NSString* identifier = nil;
NSArray* content = self.contentArray;
// Sometimes idx might be nil...
if(idx && idx.row<content.count)
{
NdlFriend* friend = content[idx.row];
identifier=friend.accountUid;
}
return identifier;
}
- (NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view
{
NSIndexPath * indexPath=nil;
NSArray* content = self.contentArray;
NSInteger count = content.count;
for(NSInteger i=0;i<count;i++)
{
NdlFriend* friend = content[i];
if([identifier isEqualToString:friend.accountUid])
{
indexPath = [NSIndexPath indexPathForRow:i inSection:0];
break;
}
}
return indexPath;
}
ho impostato rompere i punti in entrambi i metodi.
Per testare i metodi, ho aperto la vista tabella e fatto scorrere verso il basso un po '. Quindi, quando si preme il tasto home:
modelIdentifierForElementAtIndexPath:inView:
viene chiamato una volta, con il percorso dell'indice della riga più visibile in alto. Il metodo restituisce l'uid corretto per questa riga.
Fin qui tutto bene.
Quindi mi fermo e riavvio l'app. Ecco cosa succede (sto soprattutto perplesso il primo punto di interruzione colpo):
modelIdentifierForElementAtIndexPath:inView:
viene chiamato, connil
come percorso dell'indice (l'argomento vista contiene il corretto puntatore della vista tabella).indexPathForElementWithModelIdentifier:inView:
viene chiamato con una stringa di identificatore valida (e il metodo restituisce un percorso indice valido).indexPathForElementWithModelIdentifier:inView:
viene chiamato di nuovo (con la stessa stringa di identificatore).- La vista tabella viene aggiornata, ma scorre verso l'alto.
Qualcuno sa, perché il ripristino della posizione di scorrimento non riesce? Forse la chiamata di modelIdentifierForElementAtIndexPath:inView:
con nil
come indexPath ha qualcosa a che fare con esso (o è questo comportamento normale).
Mentre il ripristino della posizione di scorrimento della vista tabella (principalmente) funziona ora in iOS 9, il comportamento interrotto descritto nella domanda dove 'modelIdentifierForElementAtIndexPath: inView:' _gets ha chiamato, con nil come percorso dell'indice_ talvolta si verifica quando una vista tabella vuota è ripristinato, risultando in un'eccezione _bad accesso_. Una soluzione alternativa consiste nel cambiare la firma del metodo per accettare un 'NSIndexPath!' E proteggerlo da 'nil' (restituendo' nil'), anche se ** non dovrebbe mai accadere **! (In alternativa, per evitare l'avvertimento, restituire 'nil' se' numberOfRowsInSection (0) 'è zero funziona anche.) – penfold