2012-04-15 23 views
11

Questo potrebbe essere impossibile, ma sto cercando di salvare lo stato della mia applicazione tra le transizioni di scena, ma non riesco a capire cosa fare. Attualmente mi piace il modo in cui quando un'applicazione è in esecuzione e si preme il pulsante Home, è possibile tornare a quella applicazione esattamente dove si era interrotta, ma se si passa da una scena all'altra (in uno storyboard), una volta tornati a quella scena lo stato dell'applicazione non è stato salvato.Salvataggio stato scena applicazione iOS

Ho solo due scene diverse che devono essere salvate (si passa avanti e indietro dall'una all'altra). Come posso salvare lo stato di uno storyboard senza occupare una memoria precisa?

Ulteriori dettagli: Ecco il mio intero storyboard. Passi avanti e indietro tra le scene usando il pulsante della barra degli strumenti più. Nella seconda scena l'utente può toccare le celle vista tabella e un'immagine reale riempirà la visualizzazione dell'immagine (Vedere figura 1,2)

Figure 1.1 Figura 1.1

In figura 1.2 si vede cosa succede quando si tocca all'interno di uno delle molte cellule vista tabella (la visualizzazione di un'immagine risalga).

Figure 1.2 Figura 1.2

PROBLEMA: Quando si tocca una cella di vista tabella, che riempie la visualizzazione di un'immagine (mostrata in figura 1.2) it funziona bene se stai su quella scena o anche su premi il pulsante home di iPhone (se premi il pulsante home di iPhone e poi riapri l'app lo stato della scena è stato salvato e la visualizzazione dell'immagine riempita con un'immagine semplice continua a essere visualizzata come lo abbiamo lasciato), ma se eseguo la transizione (utilizzando il pulsante più) torna alla prima scena e poi usa il pulsante più sulla prima scena per tornare alla seconda scena, la vista dell'immagine che ho creato (mostrata nella figura 1.2) scompare e la seconda scena viene caricata senza salvare lo stato e le immagini riempita.

MODIFICA: Ho provato a utilizzare lo stesso controller di visualizzazione per entrambe le scene, ma non ha risolto il problema.

UPDATE: Ho appena trovato il seguente codice (che penso memorizzi uno stato di visualizzazione). Come potrei usare questo ed è questo quello che stavo cercando?

MyViewController *myViewController=[MyViewController alloc] initWithNibName:@"myView" bundle:nil]; 
[[self navigationController] pushViewController:myViewController animated:YES]; 
[myViewController release]; 
+2

Il sistema operativo dovrebbe salvare la "scena" per te. In cosa è specificamente diverso il tuo caso? – CodaFi

+0

Salva lo stato della scena quando premo il pulsante Home e riapro l'app, ma non salverò la scena quando passerò a una scena diversa e tornerò. –

risposta

2

vorrei suggerire una combinazione di due cose: 1. Prendere s' DBD consiglio e fare in modo che non si crea continuamente nuove viste 2. Creare una classe condivisa che è il titolare del trattamento (per i giocatori di golf, in modo che i dati siano indipendenti dalla scena)

Il modo corretto per rendere i folletti sarebbe avere uno in testa dal controller della vista a sinistra a quello a destra. Tuttavia, per respingere il quella a destra è possibile utilizzare

-(IBAction)buttonPushed:(id)sender 
     [self dismissModalViewControllerAnimated:YES]; 
} 

Questo vi porterà indietro il controller della vista, a sinistra, con il controller della vista su nel suo stato originale sinistra. Il problema ora è come salvare i dati a destra.

Per fare ciò, è possibile creare una classe singleton. Le classi Singleton hanno una sola istanza, quindi non importa quante volte vai al controller della vista sulla destra, i dati saranno sempre gli stessi.

Singleton classe di implementazione (di una classe denominata DataManager) - Header

@interface DataManager : NSObject { 
} 

+(id)initializeData; 
-(id)init; 
@end 

Singleton classe di implementazione (di una classe denominata DataManager) - principale

static DataManager *sharedDataManager = nil; 

@implementation DataManager 
+(id)initializeData { 
    @synchronized(self) { 
     if (sharedDataManager == nil) 
      sharedDataManager = [[self alloc] init]; 
    } 
    return sharedDataManager; 
} 

-(id)init { 
    if(self == [super init]) { 
    } 
    return self; 
} 
@end 

Poi, all'interno del vostro codice di visualizzazione del controller si puoi prendere questa istanza come questa

DataManager *sharedDataManager = [DataManager initializeDataManager]; 

In questo modo avrai gli stessi dati, non importa quante volte cambi le visualizzazioni. Inoltre, è possibile aderire meglio alla programmazione MVC mantenendo separati i dati e i controller di visualizzazione. (http://en.wikipedia.org/wiki/Model–view–controller)

0

Capisco cosa intendi. Questo dovrebbe accadere ad ogni applicazione, come quando l'ultimo controller di visualizzazione nello stack di navigazione viene trasferito, viene deallocato e liberato. Se hai bisogno di salvare valori come posizioni di testo o oggetti, un plist può essere la strada da percorrere. Vedi this related question per come utilizzare un plist.

+0

c'è un modo in cui non posso rilasciare/liberare la scena –

+0

Non ho mai sentito parlare di singoletti di UIViewController ... suppongo che sarebbe possibile. – CodaFi

0

Apple non ha intenzione di farlo per voi. Probabilmente dovresti semplicemente salvare lo stato di ogni vista usando NSUserDefaults e ogni volta che la tua applicazione avvia il caricamento dei dati salvati.

Se si memorizza tutto in CoreData, è necessario salvare solo la vista attiva e alcuni ID oggetto, altrimenti non sarà necessario salvare i dati.

Non aspettatevi che iOS salvi tutto ciò che avete in memoria tra un lancio e l'altro. Basta archiviarlo in NSUserDefaults e caricarlo ogni volta.

+0

Come memorizzerei lo stato della scena? Quale oggetto dovrei memorizzare? Puoi mostrarmi il codice di esempio? - Sono nuovo per iOS e l'obiettivo c ... –

0

Memorizza lo stato della scena in NSUserDefaults o all'interno di un file plist, quindi quando carichi la scena caricala con le impostazioni da lì.Se le immagini vengono caricate da Internet, potresti anche volerle salvare localmente sul tuo hard disk per iPhone in modo che risulti più fluido.

+0

Come posso memorizzare lo stato della scena? Quale oggetto dovrei memorizzare? Puoi mostrarmi il codice di esempio? –

2

Figura 1.1 ha un difetto fondamentale che credo sia alla base del problema.

Segues (le frecce tra i controller sullo storyboard) creano nuove versioni dello UIViewControllers. Hai successi circolari. Quindi quando vai "indietro" allo schermo originale attraverso il seguito ti sta davvero portando avanti creando una nuova versione.

Questo può creare un grosso problema per l'utilizzo della memoria, ma significa anche che non è possibile mantenere lo stato perché ogni elemento appena creato è una lavagna vuota.

Dal momento che si sta usando un UINavigationController e pushViewController:animated: si dovrebbe "pop" il controller per sbarazzarsi di esso.

Sulla scena "secondo", rimuovere il seguito dal pulsante + e creare un IBAction su un evento touchUpInside. Nel codice IBAction aggiungere il "pop"

- (IBAction)plusButtonTapped { 
    [self.navigationController popViewControllerAnimated:YES]; 
} 
+0

Attualmente non sto usando UINavigation Controller, come potrei implementarlo nelle mie scene? –

+0

Nel tuo codice hai menzionato l'uso di '[[auto navigationController] pushViewController: myViewController animato: YES];' per visualizzare il tuo secondo screne che significa che stai usando un 'UINavigationController'. – DBD

0

Non credo che si dovrebbe ciclo i segues, basta usare quello che collega viewcontroller 1 da viewcontroller 2 dovrebbe essere sufficiente e in questo modo si fare in modo che non viewcontrollers aggiuntivi sono stati fatti (problemi di memoria forse?)

Tuttavia, per il tuo particolare problema, credo che dovresti utilizzare i dati di base per salvare lo stato esatto della tua tabella, vista perché iOS non salva affatto lo stato esatto della visualizzazione volte. richiederà lavoro ma otterrai ciò che desideri. Sarà necessario salvare la foto esatta (utilizzando un codice o enumerazione che verrà salvata), la posizione nella vista tabella, il punteggio o bene qualsiasi dato necessario per salvare tale stato.

Il migliore di tutti è che il coredata è così efficiente che ricarica i dati quando l'app viene rilasciata o in primo piano non richiede tempo e i dati core utilizzati per caricare più di 5k di record fino ad ora e funzionano bene e non è affatto lento.

Quando torno a casa malato, fornisci un codice che potresti usare per avere un'idea di cosa intendo.

0

La chiave qui è quello di:

  1. avere una sorta di archiviazione per i dati che le vostre esigenze applicative. Questo è il modello di dati della tua applicazione.

  2. Assegnare ad ogni controllore di vista l'accesso al modello o almeno alla parte del modello di cui ha bisogno per svolgere il proprio lavoro. Il controller della vista può quindi utilizzare i dati del modello per configurarsi quando viene creato o quando la vista sta per apparire.

  3. Ogni controller di visualizzazione aggiorna il modello in momenti appropriati, ad esempio quando la vista sta per sparire o anche ogni volta che l'utente apporta una modifica.

Ci sono un sacco di modi che si possono organizzare i dati in memoria, e ci sono un sacco di modi che è possibile memorizzare su disco (cioè nella conservazione a lungo termine). Elenchi di proprietà, Dati principali, semplici file di dati vecchi e archivi con chiave sono tutte possibilità per scrivere i dati in un file. NSArray, NSDictionary, NSSet e così via sono tutte le classi che è possibile utilizzare per organizzare i dati in memoria. Nulla di tutto ciò ha a che fare con il fatto che i tuoi controller di visualizzazione si sentano persistenti, comunque. Li userete, certo, ma quello che scegliete in realtà non ha importanza per quanto riguarda l'aggiornamento dei vostri controller di visualizzazione. La cosa importante, ancora una volta, è che hai una sorta di modello e che i tuoi controller di visualizzazione hanno accesso ad esso.

In genere, il delegato dell'app imposta il modello e lo trasferisce ai controller della vista secondo necessità.

Un'altra cosa che può aiutare è che non lo fai hanno di lasciare il vostro controller della vista (s) essere eliminato quando sono estratto dallo stack di navigazione. Puoi impostare entrambi i controller di visualizzazione nel tuo delegato dell'app, se lo desideri, in modo che restino attivi. Puoi quindi utilizzare quelli che hai invece di crearne di nuovi in ​​continuazione, e così facendo otterrai automaticamente un certo grado di persistenza.

Problemi correlati