Ich hatte eine MyViewController.Swift
und ein MyViewController.xib
Präsentation des Layouts von MyViewController.
Ich habe verschiedene Methoden ausprobiert, um diesen Ansichtscontroller zu laden:
//1
let myVC = UINib(nibName: "MyViewController", bundle:
nil).instantiateWithOwner(nil, options: nil)[0] as? MyViewController
//2
let myVC = NSBundle.mainBundle().loadNibNamed("MyViewController", owner: self, options: nil)[0] as? MyViewController
//3
let myVC = MyViewController(nibName: "MyViewController", bundle: nil)
Die dritte ist die einzige erfolgreiche Initialisierung, aber die beiden vorherigen verursachen Fehler:
App wird aufgrund einer nicht erfassten Ausnahme "NSUnknownKeyException" beendet.
grund: '[setValue: forUndefinedKey:]: Diese Klasse ist nicht mit der Schlüsselwertcodierung für den Schlüssel XXX kompatibel.
Was ist los mit diesen Lademethoden?
Swift
let myViewController = MyViewController(nibName: "MyViewController", bundle: nil)
self.present(myViewController, animated: true, completion: nil)
oder Navigationscontroller einschieben
self.navigationController!.pushViewController(MyViewController(nibName: "MyViewController", bundle: nil), animated: true)
Beachten Sie die File's Owner
. In Ihrem Fall ist das File's Owner
muss MyViewController
sein, oder es ist sub-class
.
Und die folgenden Codes, wenn es in der Klasse Foo
ausgeführt wird.
// If `self` is an instance of `Foo` class.
// In this case, `File's Owner` will be a `Foo` instance due to `self` parameter.
let myVC = NSBundle.mainBundle().loadNibNamed("MyViewController", owner: self, options: nil)[0] as? MyViewController
Es weist self
als owner
zu. Also, die File's Owner
ist Foo
, nicht MyViewController
. Dann können für die Klasse Foo
diese IBOutlet
nicht mit Foo
verbunden werden. Es wird also eine Ausnahme ausgelöst.
extension UIViewController {
static func loadFromNib() -> Self {
func instantiateFromNib<T: UIViewController>() -> T {
return T.init(nibName: String(describing: T.self), bundle: nil)
}
return instantiateFromNib()
}
}
Verwenden Sie es wie folgt: -
let testVC = TestVC.loadFromNib()
Ich hatte das gleiche problem Die automatisch generierte xib enthielt eine UIView. Sie müssen die Ansicht löschen, dem xib einen neuen Ansichtscontroller hinzufügen, die Ansichtscontrollerklasse auf die gewünschte einstellen und dann die Ausgänge verbinden. Nach alledem können Sie die oben angegebenen Codes verwenden, um eine Instanz dieses Ansichtscontrollers zu erhalten:
if let menuVC = Bundle.main.loadNibNamed("MenuViewController", owner: nil, options: nil)?.first as? MenuViewController {
menuVC.profileType = profileType
vc.present(menuVC, animated: true, completion: nil)
}
Das Problem liegt nicht bei den Methoden ... Sie haben wahrscheinlich eine Steckdose (XXX) für eine gewisse Zeit angeschlossen und diese von der entsprechenden Steuerung entfernt ... Ich füge unten ein Beispiel hinzu ...
der obige Knopf ist jetzt mit dem Controller verbunden, aber wenn ich einen Kommentar hinterlasse
also versuchen Sie, eine Steckdose (xxx) zu finden, die im viewcontroller fehlt, sich aber in der xib-Datei befindet. Hoffentlich hilft es :)
@ AechoLiu Antwort ist großartig. Ich hatte die gleiche Frage und beantwortete sie mit dem folgenden Fix.
Problem:
let vc1 = NSViewController(nibName: YDNibIdentifier.myplainvc, bundle: nil)
Fix:
let vc1 = MyPlainViewController(nibName: YDNibIdentifier.myplainvc, bundle: nil)
Ich hatte versehentlich meine Nib-Datei in den falschen Clas (NSViewController) umgewandelt, obwohl sie in der .xib-Datei korrekt verbunden war.