2017-01-21 1 views
0

À jour Xcode/Swift/iOS.Impossible de mettre à jour le conteneur virtuel intégré d'un conteneur VC non parent

J'ai un VC principal (appelé StartVC) qui contient un VC enfant (appelé TopBarVC) via et segue intégré. Le VC enfant contient un bouton qui, lorsqu'il est pressé, se connecte modalement à un troisième VC (appelé CategoryPickerOverlayVC) (la vue dans ce VC sert de liste déroulante pour choisir une catégorie).

@IBAction func CategoryFilterButtonPressed(_ sender: Any) { 

    performSegue(withIdentifier: "toCategoryPickerOverlay", sender: self) 

} 

Lorsqu'une option est sélectionnée dans la zone de liste déroulante, qui est lui-même composé de trois boutons, le titre du bouton sélectionné doit être utilisé pour remplacer le texte du titre du bouton dans l'enfant VC.

Dans le VC principal, j'utilise prepareforsegue pour stocker une référence au VC enfant dans une variable - "topBarReference" - au moment où la séquence d'intégration a lieu.

var topBarReference: TopBarVC? 


    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {   
    if segue.identifier == "TopBarPane"{ 
     topBarReference = segue.destination as? TopBarVC 
    } 
} 

Ensuite, dans le 3ème VC, lorsque je clique sur l'une des options de bouton dans la liste déroulante, le titre du bouton est envoyé par un prepareforsegue mettre à jour le bouton dans le VC Enfant (via « topBarReference ») . Le troisième circuit virtuel se déroule ensuite en se rétrécissant vers le circuit maître principal. Je dois ajouter que lorsque le bouton dans le VC enfant est modifié, une variable (filterButtonText) dans Child VC est d'abord définie avec le texte du titre, puis cette variable est utilisée pour définir le texte du titre du bouton via la méthode viewDidAppear de Child VC. Lorsque j'utilise le débogueur, je remarque également que viewDidAppear dans le VC principal ne semble pas s'exécuter après le déroulement (j'ai placé un diagnostic-à-console dans viewDidAppear et rien ne s'imprime après la séquence de déroulement). Je me rends compte que cela expliquerait le bouton ne pas être mis à jour, mais je ne sais pas pourquoi viewDidAppear ne fonctionne pas.

J'ai également essayé d'utiliser un protocole délégué et instantiateViewController (withString :) en vain. Toutes les méthodes produisent le même résultat, à savoir que le bouton du CV enfant n'est pas mis à jour. Aucune erreur n'est affichée. Tout le reste se passe comme prévu.

Des idées sur ce que je fais mal?

+0

si les deux sont "incorporés" dans le StartVC, c'est-à-dire que le StartVC est toujours en train d'être vu, alors l'affichage n'a pas été appelé. Essayez d'utiliser des notifications. Demandez à startVC d'écouter une notification spécifique et de l'envoyer lorsque vous vous désengagez/sélectionnez une option dans la liste déroulante. À l'intérieur de votre code de gestionnaire de notification, mettez à jour le titre du bouton –

+0

Le troisième VC est un VC séparé, non incorporé. – Rossco

+0

"Je ne sais pas pourquoi viewDidAppear ne fonctionne pas" Parce qu'il n'a jamais disparu. Je pense que c'est ce que @ShawnFrank vous a dit aussi. – matt

Répondre

0

Ok, donc j'ai trouvé que mon code d'origine fonctionne très bien la barre d'une ligne dans la prepareforsegue de l'enfant VC.Si je change que prepareforsegue de:

 if segue.identifier == "unwindToStartVC"{ 

     let vc = segue.destination as! StartVC 
     vc.topBarReference?.CategoryFilterButton.titleLabel?.text = ((sender as! UIButton).titleLabel?.text)! 

    } 

à ceci:

 if segue.identifier == "unwindToStartVC"{ 

     let vc = segue.destination as! StartVC 
     vc.topBarReference?.CategoryFilterButton.setTitle((sender as! UIButton).titleLabel?.text, for: .normal) 

    } 

cela fonctionne très bien. L'utilisation de la méthode .setTitle semble faire une différence même si je ne suis pas sûr de savoir pourquoi.

Merci à Matt pour m'avoir donné l'idée de changer ça. La méthode de Matt a fonctionné quand je l'ai essayée, bien que, étant donné que je me détache du Master VC et non du Child VC, j'ai dû éditer le code en conséquence, en termes d'endroit où je l'ai placé. Comme ma petite «découverte» équivaut à la plus petite modification du code original, je vais marquer cela comme la réponse.

Merci à tous d'avoir pris le temps de répondre!

0

Voulez-vous dire quelque chose comme ça?

enter image description here

Si oui, la solution j'était très simple: le troisième VC utilise prepareForSegue pour définir une propriété du VC intégré et le VC intégré prend cette propriété dans la méthode unwind.

Dans mon implémentation, les trois contrôleurs de vue sont appelés ViewController, ChildViewController et ThirdViewController. Ceci est tout le code (tout le reste est configuré dans le story-board):

class ChildViewController: UIViewController { 

    @IBOutlet weak var theButton: UIButton! 
    var buttonTitle : String? 

    @IBAction func unwind(_:UIStoryboardSegue) { 
     self.theButton.setTitle(self.buttonTitle, for: .normal) 
    } 

} 
class ThirdViewController: UIViewController { 

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     (segue.destination as! ChildViewController).buttonTitle = (sender as! UIButton).currentTitle 
    } 

}