Erstens View and a View Controller are two different concepts. .superview
gibt Ihnen keinen View-Controller, und das Casting stört nur das Programm.
Während it is possible to find out the current View Controller, ist es sehr unidiomatic in Ihrem Anwendungsfall, weil man nicht sicher sein kann, dass View-Controller hat die signIn()
Funktion, und Sie können der „aktuelle View Controller“ nicht einmal sicher, der View-Controller der Ansicht ist.
iOS verwenden in der Regel die "delegate pattern" statt. In Ihrem Fall definieren Sie zunächst ein Protokoll für die signIn()
Funktion:
protocol SignInDelegate {
func signIn()
}
Dann muss die View eine Variable dieses Protokoll liefern. Diese Variable wird Delegat genannt. Wenn Sie sich anmelden möchten, rufen Sie einfach die signIn()
-Funktion des Teilnehmers an.
Die Variable sollte eine schwache Referenz zu avoid strong reference cycle sein. Das Protokoll auch needs to be class-bound, sonst wird sich der Compiler beschweren.
protocol SignInDelegate: class { // <-- needs :class for weak
func signIn()
}
class SignUIView: UIView {
weak var delegate: SignInDelegate? // <-- delegate
func signInUIButtonH(sender: UIButton) {
delegate?.signIn() // <-- call the delegate
}
}
Als nächstes passen wir das Protokoll an den View-Controller:
class SignInViewController: UIViewController, SignInDelegate { // <-- adapt the protocol
func signIn() { // <-- implement the function
print("sign in")
}
override func viewDidLoad() {
super.viewDidLoad()
signInView.delegate = self // <-- tell the subview we will be the delegate.
}
}
Wir in der Regel diese Delegierten aussetzen Builder-Schnittstelle, so dass wir einfach den Blick auf den View-Controller verbinden den Delegaten zuweisen .
Dies wird durch adding @IBOutlet
an den Delegaten Feld getan. Leider Xcode only recognizes AnyObject
/NSObject
for IBOutlet, die den ganzen Zweck der Verwendung des Delegiertenmusters für Typ-Sicherheit besiegt. Also müssen wir einen hässlichen Hack einführen, um es für IB zu umgehen. Das Protokoll benötigt nun auch @objc
, da das Auflösen dieser IB-Verbindungen die Laufzeit von Objective-C erfordert.
@objc protocol SignInDelegate { // <-- needs @objc for IB (:class is implied by @objc)
func signIn()
}
class SignUIView {
// Blame Xcode for this mess. See https://stackoverflow.com/a/42227800/224671
#if TARGET_INTERFACE_BUILDER
@IBOutlet weak var delegate: AnyObject?
#else
weak var delegate: SignInDelegate?
#endif
func signInUIButtonH(sender: UIButton) {
delegate?.signIn()
}
}
class SignInViewController: UIViewController, SignInDelegate { // <-- adapt the protocol
func signIn() { // <-- implement the function
print("sign in")
}
// Note: no need to set signInView.delegate manually.
}
Bitte den Code der Funktion der UIView, die 'signIn() 'aufruft, eingeben? Normalerweise verwenden Sie das Delegaten- oder Zielaktionsmuster, sodass Sie sich nicht darum kümmern müssen, wer Ihre Eltern sind. – kennytm
Ich sah eine Delegierte Lösungen, aber es war in C und ich habe nicht verstanden, wie es funktioniert. – Luis
Also möchten Sie UIView-Methode von Ihrem UIViewController Right aufrufen? –