I have a child UIView class instantiated in an UIViewController, the UIViewController has a function called sigIn(){}. I need to call this function from within UIView.
I tried somehow using the self.superview and casting it into a UIViewController but this did not work. I found a method where you use a listener to detect the trigger but I think this is not a good solution. Is there anther simple way of accessing functions in the paren view form the subview ?
class SignUIView: UIView {
func signInUIButtonH(sender: UIButton) {
("Call parent signIn() function")
}
(init etc. ...)
}
Firstly, View and a View Controller are two different concepts.
.superviewwill not give you a View Controller, and casting it will only crash the program.While it is possible to find out the current View Controller, it is very unidiomatic in your use case because you cannot be sure that View Controller has the
signIn()function, and you can't even ensure the "current View Controller" is the View Controller of the view.iOS typically use the "delegate pattern" instead. In your case, first you define a protocol for the
signIn()function:Then, the View needs to provide a variable of this protocol. This variable is called the delegate. Whenever we want to sign in, just call the delegate's
signIn()function.The variable should be a weak reference to avoid strong reference cycle. The protocol also needs to be class-bound, otherwise the compiler will complain.
Next we adapt the protocol to the View Controller:
We usually expose this delegate to Interface Builder so we could simply connect the View to the View Controller to assign the delegate.
This is done by adding
@IBOutletto the delegate field. Unfortunately, Xcode only recognizesAnyObject/NSObjectfor IBOutlet which defeats the whole purpose of using the delegate pattern for type-safety. So we need to introduce some ugly hack to workaround it for IB. The protocol now also needs@objcbecause resolving these IB connections requires the Objective-C runtime.