Reputation: 51
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
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