NoKey NoKey - 1 year ago 97
iOS Question

How to call the same function on multiple classes?

I have an UIViewController with 4 UIButtons. A user can tap any of those UIButtons and an UIView pops up. I want to add an

didAppear()
and
didDisappear()
function on the classes which are holding the UIViews depending on the users action. How can I call
didDisappear()
without the use of an enum, for example:

func didDisappear(view: EnumViews){
switch view{
case view0: myClassWithView0.didDisappear()
case view1: myClassWithView1.didDisappear()
case view2: myClassWithView2.didDisappear()
case view3: myClassWithView3.didDisappear()
}
}


Now I get 4 times duplicate data. I know that function exists for my class with a UIView, but how to call it? I made a protocol:

protocol ViewProtocol{
func didAppear()
func didDisappear()
}


I made the classes which are holding the UIView's conform to that protocol. However I do not know how to use it, when I create the class I get the error:


'myClassWithUIView' cannot be constructed because it has no accessible
initializers


The classes are all in an array and I can identify which UIView needs to pop up from the sender.tag. Ideally, I want to have something like this:

@IBAction func bringNewUIView(_ sender: UIButton) {
let newView = myArrayOfClassesWithUIView[sender.tag]
newView.didAppear()
}

Answer Source

You've got many things going on here. I'll start with the easy one.

'myClassWithUIView' cannot be constructed because it has no accessible initializers

This just means you don't have an initializer for your class. So inside your myClassWithUIView implementation you need to have init. I can't really help you with building the init because I don't know how that class is structured, but I will assume this is something you know how to do anyway.

Your @IBAction seems fine. Once you have an array of your classes that seems like it should work. Edit your post if that is not the case.

Finally, for your didDisappear question, you can do something like this:

func didDisappear(view: EnumViews) {
  //Check to see if this view conforms to your ViewProtocol (that's not a good name, btw)
  if let myClass = view as? ViewProtocol {
    //Since it does conform to ViewProtocol you can call didDisappear on it
    myClass.didDisappear()
  }
}

Alternatively, if you already know that the didDisappear function is always passing in a view that conforms to ViewProtocol why not just change the argument and make that easier?

func didDisappear(view: ViewProtocol) {
  view.didDisappear()
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download