2017-01-21 4 views
0

Aktuelle Xcode/Swift/iOS.Aktualisiert eingebettete untergeordnete VC von nicht übergeordneten VC

Ich habe eine Master-VC (namens StartVC), die eine Child VC (genannt TopBarVC) über und eingebettetes Segment enthält. Die untergeordnete VC enthält eine Schaltfläche, die beim Drücken modal zu einer dritten VC (CategoryPickerOverlayVC) wechselt (die Ansicht in dieser VC dient als Dropdown-Box zum Auswählen einer Kategorie).

@IBAction func CategoryFilterButtonPressed(_ sender: Any) { 

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

} 

Wenn eine Option aus der Dropdown-Liste ausgewählt, die sich aus drei Tasten bestehen, soll der Titel der gewählten Taste verwendet werden, um den Titeltext der Schaltfläche in den Kindern VC zu ersetzen.

In der Master-VC verwende ich prepareforsegue, um einen Verweis auf die Child VC in einer Variable - "topBarReference" - in dem Moment zu speichern, in dem das Embed-Segment stattfindet.

var topBarReference: TopBarVC? 


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

Dann im 3. VC, wenn ich auf einer der Schaltfläche Optionen in der Dropdown-Box klicken, wird der Button Titel über eine prepareforsegue geschickt auf die Schaltfläche im Kind VC (über „topBarReference“) zu aktualisieren .

 if segue.identifier == "unwindToStartVC"{ 

     let vc = segue.destination as! StartVC 

     vc.topBarReference?.filterButtonText = ((sender as! UIButton).titleLabel?.text)! 

    } 

Der 3. VC dann Abwicklungen zurück zum Master VC. Ich sollte hinzufügen, dass wenn die Schaltfläche in der Child VC geändert wird, eine Variable (FilterButtonText) in Child VC zuerst mit dem Titeltext festgelegt wird und diese Variable dann verwendet wird, um den Schaltfläche Titel Text über die ViewDidAppear-Methode von Child VC.

Wenn ich den Debugger benutze, merke ich auch, dass viewDidAppear in der Master-VC nach dem Abwickeln anscheinend nicht ausgeführt wird (Ich habe einen Diagnose-Print-to-Console in viewDidAppear platziert und nichts druckt nach dem Abwicklungs-Segment). Ich weiß, dies würde erklären, dass der Button nicht aktualisiert wird, aber ich habe keine Ahnung, warum viewDidAppear nicht läuft.

Ich habe auch versucht, ein Delegate-Protokoll und instanziateViewController (withString :) ohne Erfolg zu verwenden. Alle Methoden erzeugen das gleiche Ergebnis, dh die Schaltfläche in der Child-VC wird nicht aktualisiert. Es werden keine Fehler angezeigt. Alles andere passiert wie erwartet.

Irgendwelche Ideen, was ich falsch mache?

+0

Wenn beide in die StartVC "eingebettet" sind, wird die StartVC immer noch angezeigt, dann wurde die Ansicht angezeigt, wird nicht aufgerufen. Versuchen Sie, Benachrichtigungen zu verwenden. Lassen Sie Ihren StartVC auf eine bestimmte Benachrichtigung aufmerksam machen und senden Sie diese beim Abwickeln/wählen Sie eine Option aus dem Dropdown. Aktualisieren Sie innerhalb des Benachrichtigungshandlercodes den Titel der Schaltfläche. –

+0

Der 3. VC ist ein separater VC, nicht eingebettet. – Rossco

+0

"Ich habe keine Ahnung, warum viewDidAppear nicht läuft" Weil es nie verschwunden ist. Ich denke, das ist es, was @ShawnFrank dir auch gesagt hat. – matt

Antwort

0

Ok, so habe ich festgestellt, dass meine ursprüngliche Code feine Bar eine Zeile in der prepareforsegue des Kindes VC funktioniert.Wenn ich diese prepareforsegue von ändern:

 if segue.identifier == "unwindToStartVC"{ 

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

    } 

dazu:

 if segue.identifier == "unwindToStartVC"{ 

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

    } 

es funktioniert gut. Die Verwendung der .setTitle-Methode scheint einen Unterschied zu machen, obwohl ich mir nicht sicher bin, warum.

Dank Matt für die Idee, um es zu ändern. Matts Methode funktionierte, als ich es ausprobierte, obwohl ich, da ich mich vom Master-VC und nicht vom Child-VC abholte, den Code entsprechend anpassen musste, in Bezug darauf, wo ich ihn platzierte.

Da meine kleine "Entdeckung" der kleinsten Änderung des ursprünglichen Codes entspricht, werde ich dies als die Antwort markieren.

Danke an alle, die sich die Zeit genommen haben, zu antworten!

0

Meinst du sowas?

enter image description here

Wenn ja, war die Lösung, die ich verwenden, um sehr einfach: die dritte VC prepareForSegue verwendet eine Eigenschaft des eingebetteten VC zu setzen, und das eingebettete VC nimmt diese Eigenschaft in der unwind Methode auf.

In meiner Implementierung heißen die drei View-Controller ViewController, ChildViewController und ThirdViewController. Dies ist der gesamte Code (alles andere ist im Storyboard konfiguriert):

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 
    } 

}