bwc
bwc

Reputation: 1822

Multiple Parameters on an IBAction Function

I currently have a function that gathers a time from a database and returns it for other functions to use. It needs a parameter, which is stored in another part of the app, in order to gather the value from the database.

My problem comes when I want to call this function within an IBAction function.

Here is my code for the function:

func getDBValue(place: GMSPlace) -> Int {

    var expectedValue = 0

    databaseRef.child("values").child(place.placeID).observe(.value, with: { (snapshot) in
        let currentValue = snapshot.value as? [Int]

        if currentValue == nil {
            self.noValue()
            expectedValue = 0
        } else {
            let sumValue = currentValue?.reduce(0, +)

            let avgValue = sumValue! / (currentValue?.count)!

            print("The current value is \(String(describing: avgValue))")

            expectedValue = avgValue

            self.valueLabel.text = String(describing: avgValue)
        }

    })

    print("This is the expected WT: \(expectedWaitTime)")

    return expectedValue

}

And here is my code for my IBAction function that is having issues with multiple parameters:

@IBAction func addValuePressed(_ sender: Any, place: GMSPlace) {

    print("This is the place ID: \(place.placeID)")

    var expectedValue = getDBValue(place: place)

    expectedValue = expectedValue + 1

    print("The expectedValue is now: \(expectedValue)")

    self.valueLabel.text = String(describing: expectedValue)

}

This gives me a libc++abi.dylib: terminating with uncaught exception of type NSException (lldb) error. After some testing, it seems that the error is caused by the added parameter place: GMSPlace in my IBAction function. Any thoughts on how to fix this?

Upvotes: 3

Views: 2416

Answers (1)

Rob Napier
Rob Napier

Reputation: 299355

IBAction methods cannot have arbitrary signatures. You cannot add an extra parameter here. There's no way for the button to send you this (how does the button know what place is?) Generally this is handled either by there only being one UI element pointing to this action (so you know what button was pressed), or using a tag on the sender to identify it. Every view has a tag property that's just an integer. You can set that in Interface Builder or in code, and then you can read it to identify the sender.

Start by reading over Target Action in the docs that explains how this works on the various platforms. In general, the signature of an IBAction must be:

@IBAction func action(_ sender: Any)

However, on iOS, it may also be:

@IBAction func action(_ sender: Any, forEvent: UIEvent)

As Taylor M points out below, you can also have use this signature (though I can't remember right off hand if this works outside of iOS; I've only personally used it there).

@IBAction func action()

But that's it. There are no other allowed signatures.

Upvotes: 9

Related Questions