2014-10-15 13 views
9

Sono nuovo di swift e programmazione ios in generale. Sto provando a visualizzare una vista modale quando la mia app carica prima quello che fa. Il problema che sto incontrando è che la mia modale continua ad apparire più e più volte. Non sono sicuro di dove sto andando male.presentando una modal in viewdidappear con swift

DOMANDA BONUS: In definitiva mi piacerebbe che succedesse solo la prima volta che l'utente apre l'app.

class ViewController: UIViewController { 

    var introModalDidDisplay = false 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
    } 

    override func viewDidAppear(animated: Bool) { 
     super.viewDidAppear(animated) 
     showIntroModal() 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    func showIntroModal() { 
     if (!introModalDidDisplay) { 
      println(introModalDidDisplay) 
      introModalDidDisplay = true 
      let intro = self.storyboard?.instantiateViewControllerWithIdentifier("introModal") as IntroModalViewController 
      intro.modalPresentationStyle = UIModalPresentationStyle.FormSheet 
      self.presentViewController(intro, animated: true, completion: nil) 
     } 
    } 
} 
+0

si solo bisogno di definire in sostituzione func viewDidLoad() { super.viewDidLoad() showIntroModal()} –

risposta

4

Trovato. La mia classe "intro" si estendeva a ViewController anziché a UIViewController ... a quanto pare è male. Grazie per l'aiuto! Ci scusiamo per la caccia all'oca selvaggia.

0

Quando si chiude la vista modale si mostrano ancora una volta la vostra vista ViewController, sparando viewDidAppear una volta di più e entrare in un ciclo infinito di mostrare il vostro vista modale, dal momento che il primo punto di vista è sempre "apparire"

I suggerirei di farlo in viewDidLoad, poiché si suppone che la vista venga caricata solo una volta. Prova e sperimenta questi eventi e guarda quando vengono licenziati.

Per quanto riguarda l'attivazione solo una volta, suggerisco di impostare un flag in localStorage (plist) che indica se è la prima volta che l'utente apre l'app o meno. Ad esempio, imposta un flag nella prima vista viewDidLoad e se questo flag è falso mostra la tua vista modale e imposta il flag su true.

Ecco una domanda su come scrivere in plists a Swift: Save Data to .plist File in Swift

+0

Grazie per il commento! Ho provato viewDidLoad per primo e ha generato un errore perché (penso) la vista non aveva ancora finito di disegnare, quindi non ho potuto aggiungere la mia modale ad essa. I commenti che ho trovato quando cercavo una soluzione suggerivano di spostare le cose su viewDidAppear. – timT

+0

L'utilizzo del metodo che ho suggerito di usare un flag in localStorage risolverà il problema alla perfezione, poiché si attiva solo una volta. – lascort

0

Un paio di osservazioni:

  1. Sta dicendo che si sta vedendo questo appaiono ancora e ancora mentre sei usando l'app? Ciò suggerirebbe l'istanza di più istanze di questo controller di visualizzazione. Ad esempio, potresti tornare indietro a questo controller di visualizzazione (che creerà una nuova istanza) anziché svolgerlo/scartarlo/chiuderlo nuovamente (che tornerà all'istanza precedente).

    Suggerirei di avere un punto di interruzione o una dichiarazione di registrazione in viewDidLoad e confermare che si vede questo una sola volta. Se lo vedi più volte, significa che hai qualche riferimento circolare tra le scene dello storyboard (e, a proposito, stai abbandonando la memoria, un tipo di perdita).

  2. Per gestire questo solo presentandosi una volta tra gli usi dell'app, è necessario salvare questo introModalDidDisplay in qualche forma di archiviazione persistente. Spesso per questo viene utilizzato lo NSUserDefaults. Ad esempio, definire introModalDidDisplay per cercare lo stato delle impostazioni predefinite utente standard:

    var introModalDidDisplay = NSUserDefaults.standardUserDefaults().boolForKey("introModalDidDisplay") 
    

    Allora la vostra showIntroModal può aggiornare questa impostazione nelle impostazioni predefinite dell'utente:

    func showIntroModal() { 
        if !introModalDidDisplay { 
         introModalDidDisplay = true 
         NSUserDefaults.standardUserDefaults().setBool(true, forKey: "introModalDidDisplay") 
         NSUserDefaults.standardUserDefaults().synchronize() 
    
         let intro = self.storyboard?.instantiateViewControllerWithIdentifier("introModal") as IntroModalViewController 
         intro.modalPresentationStyle = UIModalPresentationStyle.FormSheet 
         self.presentViewController(intro, animated: true, completion: nil) 
        } 
    } 
    

    Chiaramente, è possibile utilizzare qualsiasi memoria persistente tecnica desiderata (plist, archivio, impostazioni predefinite dell'utente, Core Data, SQLite), ma l'idea è la stessa: recuperare lo stato dall'archiviazione permanente e una volta presentata la schermata di introduzione, aggiornare di conseguenza quella memoria permanente.

    A proposito, osservando questo nella memoria persistente, fissiamo anche il sintomo del problema che ho discusso al punto # 1. Ma vuoi veramente aggiustare la causa principale di quel primo punto, perché altrimenti ti perderai memoria (se, ovviamente, stai istanziando più copie della classe ViewController).


Tra l'altro, guardando al futuro, invece di memorizzare solo un valore booleano, Potrei suggerire la memorizzazione di un identificativo numero di versione, anche. In questo modo, quando rilascerai la versione 2.0 dell'app, sarai in grado di decidere se gli utenti della v1.0 potrebbero vedere di nuovo la schermata di introduzione aggiornata (o magari una schermata personalizzata che si concentra sulle novità).

+0

Hai ragione, viewDidLoad viene licenziato più volte, ma non sono sicuro del perché. Non ho nessun seguace sul posto. Sembra avere qualcosa a che fare con questa linea: 'self.presentViewController (intro, animated: true, completion: nil)' – timT

+0

Avrei immaginato che il problema fosse altrove. È necessario avere segues o altre occorrenze di 'presentViewController' che presentano nuove istanze di questo controller di visualizzazione. Dovrebbe essere facile da diagnosticare: aggiungi breakpoint o accedi a 'viewDidLoad' e poi esegui l'app e identifica la sequenza di azioni che genera la nuova istanza. Una volta capito dove viene generata la nuova istanza, dovrebbe essere facile guardare il codice e capire perché/come. – Rob

+0

BTW, presumo che la scena "intro" ritorni al 'ViewController' principale chiamando' dismissViewControllerAnimated', giusto? – Rob

Problemi correlati