David Seek
David Seek

Reputation: 17132

How to set a function as function argument in Swift 3

Q: Is it possible to pass a function as function argument in Swift 3?

To refactor my code, I want to have a global function. At the end of this function, there is a custom button that has an action argument.

let deleteButton = MIAlertController.Button(title: "cancel", 
                                            type: .cancel, 
                                            config: getDestructiveButtonConfig(),
                                            action: {
                                                print("completed")
                                            })

What I would like to do is something like, setting up a global function with a function as argument.

MyGlobalStuff.swift
...
func getButton(_ myFunc: func, _ title: String) {
    let deleteButton = MIAlertController.Button(title: title, 
                                            type: .cancel, 
                                            config: getDestructiveButtonConfig(),
                                            action: {
                                                myFunc // call here the function pass by argument
                                            })
}

Called by getButton(..) with the passed function within the same Class.

MyViewController.swift
...
getButton(myPrintFunc, "cancel")

func myPrintFunc() {
        print("completed")
}

Is something like that possible? Help is very appreciated.

Upvotes: 3

Views: 16278

Answers (3)

Luca Angeletti
Luca Angeletti

Reputation: 59496

Yes you can pass a function/closure as parameter of another function.

This is the syntax

func doSomething(closure: () -> ()) {
    closure()
}

here the function doSomething receives as parameter a closure with no params and no return type.

You can call doSomething with this syntax

doSomething(closure: { _ in print("Hello world") })

Or using the trailing closure syntax

doSomething { 
    print("Hello world")
}

Upvotes: 14

user28434'mstep
user28434'mstep

Reputation: 6600

Assuming

typealias Func = () -> Void    

You can do:

func getButton(_ title: String, _ myFunc: Func) {
    let deleteButton = MIAlertController.Button(title: title, 
                                                type: .cancel, 
                                                config: getDestructiveButtonConfig(),
                                                action: {
                                                    myFunc()
                                                })
}

Or even:

func getButton(_ title: String, _ myFunc: Func) {
    let deleteButton = MIAlertController.Button(title: title, 
                                                type: .cancel, 
                                                config: getDestructiveButtonConfig(),
                                                action: myFunc
                                                )
}

Also, if you haven't noticed, I moved closure to the end of parameter list. This way it will allow advanced magic like:

getButton("X") { … }

instead of

getButton({ … }, "X")

Upvotes: 10

Luke
Luke

Reputation: 5076

Functions are first class in swift so you can pass them like so:

func getButton(_ myFunc: () -> Void, _ title: String) {

You need to specify the signature of the function in the type, i.e. parameter types and return type

Upvotes: 6

Related Questions