2012-01-12 2 views
10

Ho un'app universale, dove sto condividendo lo stesso controller per uno storyboard IPad e IPhone. Ho messo un UILongPressGestureRecognizer su un UITableView, che quando si preme una cella iPhone richiama un'azione che esegue un segue:prepareForSegue non viene chiamato dopo performSegue: withIdentifier: con stile popover

-(IBAction)showDetail:(id)sender { 
    UILongPressGestureRecognizer *gesture = (UILongPressGestureRecognizer*)sender; 
    if (gesture.state == UIGestureRecognizerStateBegan) { 
     CGPoint p = [gesture locationInView:self.theTableView]; 

     NSIndexPath *indexPath = [self.theTableView indexPathForRowAtPoint:p]; 
     if (indexPath != nil) { 
      [self performSegueWithIdentifier:SEGUE_DETAIL sender:indexPath]; 
     } 
    } 
} 

la segue è una vista di dettaglio eseguita come una 'spinta'. La prima cosa che dovresti notare è che il mittente è un NSIndexPath, è l'unico modo che ho trovato per passare la cella selezionata. Forse c'è una soluzione migliore. Tutto funziona bene, nel senso che viene eseguito il seguito e prima che venga chiamato anche prepareForSegue.

Tuttavia accade che su iPad, ho cambiato l'identificatore di seguito a Popover. Ora le cose funzionano in parte, il seguito viene eseguito, ma prepareForSegue non viene chiamato e quindi il controller della vista di destinazione non è impostato come dovrebbe essere.

Cosa sto sbagliando?

+0

Sto vivendo lo stesso problema. viewdidload viene chiamato ma non esegue segue – 1dayitwillmake

risposta

20

Quello che ho scoperto finora, è che con qualsiasi identificatore segue che non è Popover queste sono le invocazioni fatte da iOS:

  • prepareForSegue (sul controller fonte)
  • viewDidLoad (sul controller di destinazione)

mentre in popover segue l'ordine invocazione è:

  • viewDidLoad (sul controller di destinazione)
  • prepareForSegue (sul controller fonte)

solo perché ho messo tutta la mia logica nel viewDidLoad, il controller non è stato inizializzato correttamente, e un incidente accaduto. Quindi non è esattamente vero che prepareForSegue non è chiamato, la verità è che stavo ricevendo un'eccezione, e ho erroneamente sbagliato come preparazione per Forsky non viene chiamato.

Non riuscivo a mettere tutto in viewWillAppear perché era necessario effettuare una chiamata a CoreData e non volevo controllare se le entità fossero ok ogni volta che veniva visualizzata la vista.

Come ho risolto questo? Ho creato un altro metodo controller destinazione

-(void)prepareViewController { 
    // initialization logic... 
} 

e cambiando il metodo prepareForSegue controller fonte stessa:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    MyViewController *mvc = (MyViewController*)[segue destinationViewController]; 
    // passing variable 
    // with segue style other than popover this called first than viewDidLoad 
    [email protected]"prop1"; 
    [email protected]"prop2"; 

    // viewWillAppear is not yet called 
    // so by sending message to controller 
    // the view is initialized 
    [mvc prepareViewController]; 

} 

non so se questo è il comportamento previsto con popover, comunque ora le cose stanno funzionando.

+0

La tua correzione ha funzionato anche per me, grazie, ma questo è uno strano problema dato che è appena spuntato per me anche se ho molti altri pop over che funzionano bene e si affidano a prepareForSegue per inoltrare gli oggetti. – GeoffCoope

+0

Lo stesso qui, a volte prepareForSegue viene chiamato prima di viewDidLoad, a volte dopo ... Grazie per la correzione. –

+0

Penso che prepareForSegue venga chiamato dopo viewDidLoad quando il seguito viene richiamato dallo Storyboard, ed è l'altro modo se lo si attiva manualmente usando -performSegueWithIdentifier :. – gklka

1

ho notato che il codice piastra della caldaia per il modello Master-Detail di Xcode (iPhone) utilizza il seguente schema per la configurazione vista dettaglio del VC:

  1. dettaglio setter di VC (per immobili) vengono sovrascritti in per richiamare il metodo configureView (configureView aggiornerebbe tutti i controlli nella vista, ad es. etichette, ecc.)
  2. dettaglio il metodo di VC viewDidLoad invoca anche il metodo configureView

non ho seguito questo schema, l'altro giorno quando stavo cercando di riutilizzare un dettaglio VC nel mio film app, e questo mi ha dato problemi .

Non ho molta esperienza con i popover; tuttavia, se il pattern precedente viene utilizzato con un VC di dettaglio che viene visualizzato all'interno di un popover, la vista VC del dettaglio non viene configurata quando si impostano le proprietà del VC del dettaglio all'interno del metodo prepareForSegue?