2017-09-28 2 views
1

Ich versuche einige Animationen zwischen UIViewControllers zu testen und in diesem speziellen Fall habe ich eine UIViewController, die ein weiteres UIVC als Kindansicht hinzufügt.App stürzt beim Entfernen von Kind View Controller von seinem Elternteil ab

Alles funktioniert wie erwartet, die untergeordnete Ansicht wird hinzugefügt und dargestellt, dann auf der untergeordneten Ansicht habe ich eine UINavigationBar, die eine Schaltfläche zum Abbrechen (Kündigen) als ihre linke Leiste hat.

Wenn ich auf diese Schaltfläche klicke, fire ich eine Funktion, die versucht, diese vorgestellte untergeordnete Ansicht aus der Ansichtshierarchie (von der übergeordneten Ansicht) zu entfernen.

-Code von der übergeordneten Ansicht:

// ViewController -> Parent 

lazy var presentButton: UIButton = { 
    let b = UIButton(type: .custom) 
    b.setTitle("Present", for: .normal) 
    b.setTitleColor(.black, for: .normal) 
    b.addTarget(self, action: #selector(didTapPresentButton), for: .touchUpInside) 
    return b 
}() 

lazy var childViewController: PresentedViewController = { 
    let viewController = PresentedViewController() 
    return viewController 
}() 


@objc func didTapPresentButton() { 
    addViewControllerAsChildViewController(childViewController: childViewController)  
} 


func addViewControllerAsChildViewController(childViewController: UIViewController) { 
    self.addChildViewController(childViewController) 
    childViewController.view.frame = CGRect.zero 

    self.view.addSubview(childViewController.view) 

    let newFrame = view.bounds 
    UIView.animate(withDuration: 2) { 
     childViewController.view.frame = newFrame 
    } 
    childViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] 
    childViewController.didMove(toParentViewController: self) 
} 

Wie Sie oben sehen, wenn ich die vorliegende Schaltfläche klicken, wird es instanziiert das Kind Ansicht und animiert es in, so weit so gut.

Kinder anzeigen Code:

// ChildViewController -> Child (ofc) 

@objc func didTapCancel() { 
    self.willMove(toParentViewController: nil) 
    self.view.removeFromSuperview() 
    self.removeFromParentViewController() 
} 

nun auf das Kind Ansicht, wenn ich auf die Schaltfläche Abbrechen klicken, ich weiß, ich habe die removeFromParentViewController() aufrufen, um es richtig entfernt werden, aber die App stürzt ab, wenn ich tun, dass mit dem followingg Fehler:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[dismissLayerTest.ChildViewController name]: unrecognized selector sent to instance 0x7fea2f60a920' 

dann habe ich versucht, die self.removeFromParentViewController() Linie Stellung zu nehmen, und dadurch, funktioniert die App nicht abstürze, aber dann auf dem übergeordneten view-Controller kann ich sehen, dass die Sicht nach wie vor ist an sein Elternteil durch Drucken self.childViewControllers.count und es zeigt mir 1.

Können Sie sehen, wo das Problem liegt?

Danke

+1

Suchen Sie in Ihrem Code nach 'name', um den Fehler zu finden. –

+0

@YUNCHEN es gibt keine 'Name'-Eigenschaft oder Methodenaufruf mit dem:/ –

+0

Dieser Link kann hilfreich sein: https://stackoverflow.com/questions/46196201/how-to-transfer-data-between-parent-and -kind-view-controllers? answertab = aktiv # tab-top –

Antwort

0

Ich finde heraus, wo das Problem war.

Nach einigen Tests entdeckte ich, dass wir lazy Instanziierungen nicht verwenden sollten während parent-child View Controllers verwenden.

Da die ich instanziiert die childViewController als lazy, wenn ich es aus dem parentViewController der Fehler zu entfernen versucht, sagte unrecognized selector sent to instance so fand ich heraus, dass die Eigenschaft Zeiger-Selektor irgendwie auf dem parentViewController ausgeplant war, die wusste nicht, was es war Kind abweisen, weil es seine Referenz verloren hat.

Um es zu beheben, entfernte ich die Instanziierung lazy, so bleibt es immer im Bereich und jetzt kann ich das Kind erfolgreich aus dem übergeordneten Bereich entfernen.

var childViewController: ChildViewController = { 
    let viewController = ChildViewController() 
    return viewController 
}() 
Verwandte Themen