2014-11-06 6 views
8

Ich habe überall nach einer Antwort gesucht, und ich habe versucht, es zu implementieren, aber nichts funktioniert. Grundsätzlich muss ich in der Lage sein, Änderungen im Subview-Array einer VC-Ansicht zu beobachten. Wenn eine vorhandene Ansicht aus diesem Array entfernt wird, möchte ich darüber informiert werden und Code ausführen.Kann KVO Änderungen in einem UIView Subview Array beobachten?

Ist es möglich?

EDIT - Mehr Informationen

Ich versuche, eine Lösung für einen seltsamen Rand Fall Fehler zu machen, wo schnell auf dem UISearchBar eines UISearchDisplayController Klopfen (sehr custom) bewirkt, dass die sdController (oder besser gesagt der verwaltete SearchBar in navBar Wirkung) um aus der Ansicht zu verschwinden, aber der sdController ist NOCH AKTIV. Das bedeutet, dass die navBar am Ursprung -y verbleibt und die folgende Tabelle nicht scrollbar ist.

Mein ursprünglicher Gedanke war, zu einem Zustand zu kommen, wo der sdController aktiv war, aber die UISearchDisplayControllerContainerView war nicht in der View-Hierarchie. Ich habe versucht, dies in der VC-AnsichtDidLayoutSubviews zu testen, aber leider, wenn Sie auf eine Suchleiste tippen und die sdController-Animation initiieren, der SDController ist aktiv, und die UISearchDisplayControllerContainerView ist nicht in der View-Hierarchie :(.

+0

Schmutzige Tricks: Post Benachrichtigung über NSNotificationCenter wo Sie Subview entfernen und ihn fangen, wo Sie einige Code ausführen müssen. Oder benutze Delegierte. –

+2

Sie können KVO 'subviews' nicht. Das System sendet jedoch 'layoutSubviews' an eine Sicht, wenn es Subviews gewonnen oder verloren hat (wenn sich die Superview in der Onscreen-Ansichtshierarchie befindet). Vielleicht können Sie eine benutzerdefinierte UIView-Unterklasse als Superview verwenden und tun, was Sie in 'layoutSubviews' brauchen. Wenn das nicht ausreicht, bearbeiten Sie Ihre Frage, um weitere Details zu ** warum ** anzugeben, wenn Sie benachrichtigt werden, wenn die Unteransicht entfernt wird. Wir können Ihnen wahrscheinlich eine bessere Lösung geben. –

+0

@robmayoff danke für den Kommentar. Ich habe meine Frage aktualisiert. – Lizza

Antwort

3

Wie bei den meisten Immobilien in Apples Frameworks subviewsis not KVO compliant

Wenn Sie entweder die subview oder die Superview steuern Sie Änderungen an die Ansicht Hierarchie von Subclassing und überwiegenden beobachten können.

im Super Sie außer Kraft setzen müssen ...

- (void)willRemoveSubview:(UIView *)subview 

... oder, wenn Sie die subview steuern, würde außer Kraft setzen Sie ...

- (void)willMoveToSuperview 

Beide Methoden aufgerufen werden, bevor der Ansicht entfernt wird.

11

Sie können die Eigenschaft sublayers von CALayer, die KVO-konform ist, anstelle von UIView subviews beobachten.

+1

das funktioniert in der Tat. große Problemumgehung! – Denis

+0

Bitte geben Sie einen Link zur Dokumentation an, in der angegeben wird, dass Core Animation im Allgemeinen oder CALayers Subviews im Besonderen KVO-konform sind. Zu meinem Verständnis sind sie nicht. (Hinweis: KVC-Konformität bedeutet nicht KVO-Konformität). –

1

Swift 3.x

Verwendung benutzerdefinierte Ansicht iike

class ObervableView: UIView { 
    weak var delegate:ObservableViewDelegate? 

    override func didAddSubview(_ subview: UIView) { 
     super.didAddSubview(subview) 
     delegate?.observableView(self, didAddSubview: subview) 
    } 

    override func willRemoveSubview(_ subview: UIView) { 
     super.willRemoveSubview(subview) 
     delegate?.observableview(self, willRemoveSubview: subview) 
    } 

} 

protocol ObservableViewDelegate: class { 
    func observableView(_ view:UIView, didAddSubview:UIView) 
    func observableview(_ view:UIView, willRemoveSubview:UIView) 
} 

//Use 

class ProfileViewController1: UIViewController, ObservableViewDelegate { 
    @IBOutlet var headerview:ObervableView! //set custom class in storyboard or xib and make outlet connection 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     headerview.delegate = self 
    } 

    //Delegate methods 
    func observableView(_ view: UIView, didAddSubview: UIView) { 
     //do somthing 
    } 

    func observableview(_ view: UIView, willRemoveSubview: UIView) { 
     //do somthing 
    } 
}