2015-04-24 16 views
11

Storyboard ImageCome Segue con i dati da una scheda all'altra Tab correttamente

Ho un Tab Bar controller che è la View Controller iniziale, che ha anche una PFLoginViewController che i cuccioli fino se un utente non è connesso. Il flusso di accesso/registrazione funziona correttamente.

Le due schede sono 1. un UICollectionView cui mi riferirò come IntroVC da ora in poi 2. un UITableView cui mi riferirò come FeedVC

Quando un utente fa clic una foto in IntroVC, uno spettacolo segue viene attivato (tramite prepareForSegue) che mostra un terzo schermo (UIView) che tecnicamente non è una scheda. Mi riferirò a questo come il SelectVC d'ora in poi.

NOTA: tutte queste schermate sono anche Incorpora (ded) in un controller di navigazione.

Le SelectVC mostra una foto, e c'è un UIButton che l'utente può premere che innesca uno spettacolo segue e distendersi segue, a spingere l'immagine nel FeedVC. Il motivo per cui ho creato un seguito di Unwind è perché senza di esso l'immagine si sposterà nello FeedVC (seconda scheda) ma la prima scheda verrebbe comunque evidenziata.

Ho risolto questo problema con Unwind seguito, ma ho notato che ho un problema in cui dopo una selezione, quando premo la prima scheda (Intro VC) la barra di navigazione ha un pulsante Indietro, e più volte uso il pulsante SelectVC per spingere le immagini, più volte devo premere Indietro nello IntroVC. Sono molto confuso su come risolvere questo problema. È evidente che non sto collegando correttamente il flusso e sembra che lo IntroVC venga generato più volte?

ottengo il seguente messaggio nella console quando vado attraverso le segues in Simulator:

Nested pop animation can result in corrupted navigation bar 

Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted. 

Qualsiasi aiuto sarebbe molto apprezzato!

Codice rilevante in basso.

IntroVC.swift

@IBAction func unwindToIntroView(segue: UIStoryboardSegue) { 
    self.tabBarController!.selectedIndex = 1 


override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if segue.identifier == "showFeedItem" { 
     let selectScreenVC = segue.destinationViewController as! SelectScreenViewController 
     let cell = sender as! UICollectionViewCell 
     if let indexPath = self.collectionView!.indexPathForCell(cell) { 
      self.navigationController?.popViewControllerAnimated(true) 
      selectScreenVC.currentVenue = venueItems[indexPath.row] 
     } 
} 

SelectVC.swift

@IBAction func pushSelection(sender: UIButton) { 
    var feedItem = FeedItem() 
    if let currentItem = currentItem { 
     feedItem.nName = currentItem.nName 
     feedItem.imageFile = currentItem.lgImg 
     feedItem.userName = PFUser.currentUser()!.username! 
     feedItem.saveInBackgroundWithBlock({ (success: Bool, error: NSError?) -> Void in 
      self.performSegueWithIdentifier("unwindToVenueView", sender: self) 
     }) 
    } 
} 

So che questo è stranamente strutturata, e se mi manca le informazioni che è necessario per comprendere appieno - per favore fatemelo sapere e Modificherò di conseguenza.

risposta

0

Credo che il problema si presenta in questa linea (prepareForSegue metodo)

self.navigationController?.popViewControllerAnimated(true) 

dal momento che si sta cercando di pop il controller della vista dalla pila prima di presentare SelectVC. Questo potrebbe essere la causa di una possibile barra di navigazione danneggiata (cosa succede se si apre il controller di visualizzazione radice?). È possibile provare il seguente metodo, invece:

self.navigationController?.popToRootViewControllerAnimated(true) 
+0

hey @flizana, ho provato il tuo suggerimento ma questo non ha funzionato purtroppo. Grazie per aver cercato di aiutare! – SamYoungNY

+0

Hai provato a inserire i punti di interruzione in ogni metodo chiamato per verificare quale riga sta generando l'eccezione? – flizana

0

io non sono sicuro di aver capito il motivo si chiama self.navigationController?.popViewControllerAnimated(true) all'interno prepareForSegue: di IntroVC.swift: in questo modo "pop" il ViewController fuori dallo stack anche prima di presentarlo (significa che in effetti si tenta di far uscire IntroVC dallo stack, non SelectVC).

Per prima cosa proverei, commenta quella riga in prepareForSegue: e guarda cosa succede.

Non riesco a provare in questo momento, ma non sarei sorpreso se chiamando self.performSegueWithIdentifier("unwindToVenueView", sender: self) in SelectVC.swift si innescherebbe automaticamente il pop di se stesso, senza bisogno di chiamarlo manualmente. Se non è così, è possibile aggiungere popViewControllerAnimated (o forse popToRootViewControllerAnimated) a pushSelection: di SelectVC.swift.

Fammi sapere se funziona!

have a nice day,

@ cdf1982

+0

Ciao @ cdf1982 grazie per il vostro consiglio. Ho provato i tuoi suggerimenti ma sfortunatamente non hanno funzionato. C'è qualcosa che mi manca, ma non riesco a capire cosa. Ancora una volta, grazie per il tuo tempo! – SamYoungNY

+0

Non dirlo. Ultimo suggerimento: prova a commentare self.tabBarController! .selectedIndex = 1 nel metodo unwind: l'errore registrato si lamenta di uno stato imprevisto al termine della navigazione. Forse è lo svuotamento del VC che cambia troppo presto, e anche se non lo è, probabilmente vorrai aggiungere punti di interruzione al tuo codice e seguire l'esecuzione passo dopo passo per capire che cosa richiede questi due errori. In bocca al lupo! – cdf1982

1

Segue un'altra scheda con i dati

Questa soluzione utilizza un segue svolgimento di passare ad una nuova scheda e inviarla dati.

enter image description here

  • Verde è Tab 1
  • Blu è un discendente di Tab 1
  • giallo è Tab 2

Obiettivo: Vai dal blu al giallo e passare i dati al contemporaneamente.

Codice

Blue View Controller (Tab 1, discendente)

import UIKit 
class BlueViewController: UIViewController { 

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 

     // this is the data that we want to send 
     let myData = "Hello from Blue" 

     // Get a reference to the destination View Controller 
     // and set the data there. 
     if let yellowVC = segue.destination as? YellowViewController { 
      yellowVC.data = myData 
     } 
    } 
} 

giallo View Controller (Tab 2)

import UIKit 
class YellowViewController: UIViewController { 

    var data: String? 

    @IBOutlet weak var dataLabel: UILabel! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     updateUI() 
    } 

    @IBAction func comingFromBlueUnwindSegue(segue: UIStoryboardSegue) { 
     // This may get called before the UI views have been loaded if 
     // the user has not navigated to this tab before. So we need to make 
     // sure that the label has been initialized. If it hasn't then we 
     // will have our chance to call updateUI() in viewDidLoad(). 
     // We have to call it here too, though, becuase if the user has 
     // previously navigated to this tab, then viewDidLoad() won't get 
     // called again. 
     if dataLabel != nil { 
      updateUI() 
     } 
    } 

    func updateUI() { 
     // only update the label if the string data was previously set 
     guard let myString = data else {return} 
     dataLabel.text = myString 
    } 
} 

Interface Builder

Controllo trascinamento dal pulsante all'icona Esci nella parte superiore del controller Vista sorgente. Dal momento che abbiamo già aggiunto il codice di svolgimento alla Gestione destinazione, verrà visualizzato come opzione. Sceglilo.

enter image description here

Note

  • Grazie a this answer per me l'impostazione sulla strada giusta.
  • È anche possibile impostare la sequenza di svolgimento trascinando il controllo dall'icona Esci all'icona del View Controller. Quindi è possibile chiamare i passaggi a livello di programmazione. Vedi this answer per i dettagli.
  • Non c'era alcun codice speciale da mostrare per il controller di visualizzazione Tab 1.