Ginso
Ginso

Reputation: 51

swift call function passed by argument with selector

I want to write a function that creates views, adds them to a stackView and calls a callback function when one of the items clicked: Here is a simplified example:

func createSelection(callBack:(Int)->()) {
    for i in 0...5 {
        let view = UIView()
        // configure and fill view...
        stackView.addArrangedSubview(view)
        // add gesture recognizer
    }
}

My problem is, that I don't know how to call the callBack function when one of the views is clicked. I can't use the selector on it since it is not declared as a objc function. How would I do that?

Upvotes: 0

Views: 155

Answers (1)

EDUsta
EDUsta

Reputation: 1933

You can create a protocol for UIView, and use it with whichever view you'd like.

import UIKit

protocol Tappable {
    var callback: ((Int) -> ())? { get set }
    var callbackValue: Int? { get set }
    func setupTapGestureRecognizer()
}

class TappableView: UIView, Tappable {
    var callback: ((Int) -> ())?
    var callbackValue: Int?

    func setupTapGestureRecognizer() {
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapGestureAction))
        self.addGestureRecognizer(tapGestureRecognizer)
    }

    @objc func tapGestureAction() {
        print("tapped")
        guard let callback = callback, let callbackValue = callbackValue else { return }

        callback(callbackValue)
    }
}

func createSelection(callBack: @escaping (Int) -> ()) {
    for i in 0...5 {
        let view = TappableView()
        view.callback = callBack
        view.callbackValue = i
        view.setupTapGestureRecognizer()
        // Mocking tap action, remove this when you're done:
        view.tapGestureAction()
    }
}

createSelection { (value) in
    print("hi from callback, with value: \(value)")
}

The result in Playground:

tapped
hi from callback, with value: 0
tapped
hi from callback, with value: 1
tapped
hi from callback, with value: 2
tapped
hi from callback, with value: 3
tapped
hi from callback, with value: 4
tapped
hi from callback, with value: 5

Upvotes: 2

Related Questions