2

I have a nested function like this and I want to call childFunc when user tap to my button, but it does not work

class MyClass {
    func parentFunc() {
        button.addTarget(self, action: #selector(parentFunc().childFunc), for: .touchUpInside)
        func childFunc() {
            print("User tapped")
        }
    }
}

It raise error like this:

Value of tuple type '()' has no member 'childFunc'

Is there any way to perform childFunc with #selector ?

Edit 1: I have use closure like this, But I think it's not a nice way because I have to make another function

class MyClass {
    myClosure: () -> () = {}
    func parentFunc() {
        button.addTarget(self, action: #selector(runChildFunc), for: .touchUpInside)
        func childFunc() {
            print("User tapped")
        }
        myClosesure = childFunc

    }
    func runChildFunc() {
        myClosure()
    }
}

2 Answers2

4

instead, you can try below code to achieve your goal

class MyClass {
    let button = UIButton()

   @objc public func parentFunc(_ sender : UIButton?) 
      {

        func childFunc() {
         print("User tapped")
        }

        if sender != nil && sender.tag == 100{
        childFunc()
        return
        }

        button.addTarget(self, action: #selector(parentFunc(_:)), for: .touchUpInside)
        button.tag = 100
       }
    }

In above code, Sender is optional so you can pass nil when you don't want to call child function like parentFunc(nil)

Govind Prajapati
  • 957
  • 7
  • 24
3

Is there any way to perform childFunc with #selector

No. The entire idea makes no sense. Keep in mind that the nested (inner) func does not really exist. It only comes into existence, momentarily, when the outer func runs. The running of the outer func brings the inner func into existence at the moment the definition is encountered, effectively storing it in a local variable, so that it is callable from subsequent code in scope inside the func. And like any local variable, when the outer func code ends, the inner func goes back out of existence. Also, because it is a local variable inside the func, it is scoped in such a way that it couldn't be called into from outside, even if such a notion made sense — just as a local variable inside a func cannot be seen from outside the func, even if that notion made sense.

The selector must point to a method of a class instance (where the class derives from NSObject). This is a Cocoa Objective-C architecture; you have to obey Objective-C rules.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • What you'd really like to do, perhaps, is hand the button a closure instead of using the target–action architecture. That's a great idea, and you can find lots of discussion on Stack Overflow about how to configure such a thing (such as here: http://stackoverflow.com/questions/25919472/adding-a-closure-as-target-to-a-uibutton), but it is not how the target–action architecture works. – matt Mar 24 '17 at 02:48
  • then Nguyen should use the closure pattern from your link. but then he has to use a different syntax – muescha Mar 24 '17 at 05:10