Reputation: 682
I am setting up swipe recognition in my SKScene, and I found that hard coding all the recognizers takes time and isn't really neat, so I decided to use a for-loop, and a dictionary that contains UISwipeRecognizer
s as keys, and ()
functions as values. The problem is that it gives me the error in the title while trying to add the target using recognizer.addTarget(self, action: #selector(functionForRecognizer[recognizer]!))
Here is the code:
class xxxxx: SKScene {
let rightSwipeRecognizer = UISwipeGestureRecognizer()
let leftSwipeRecognizer = UISwipeGestureRecognizer()
let upSwipeRecognizer = UISwipeGestureRecognizer()
let downSwipeRecognizer = UISwipeGestureRecognizer()
var swipeRecognizers: [UISwipeGestureRecognizer] {
return [rightSwipeRecognizer, leftSwipeRecognizer, upSwipeRecognizer, downSwipeRecognizer]
}
var directionForRecognizer: [UISwipeGestureRecognizer : UISwipeGestureRecognizerDirection] {
return [
rightSwipeRecognizer : .right,
leftSwipeRecognizer : .left,
upSwipeRecognizer : .up,
downSwipeRecognizer : .down
]
}
func didSwipeRight() {}
func didSwipeLeft() {}
func didSwipeUp() {}
func didSwipeDown() {}
var functionForRecognizer: [UISwipeGestureRecognizer : ()] {
return [
rightSwipeRecognizer : didSwipeRight(),
leftSwipeRecognizer : didSwipeLeft(),
upSwipeRecognizer : didSwipeUp(),
downSwipeRecognizer : didSwipeDown()
]
}
func setupSwipeRecognizers() {
for recognizer in swipeRecognizers {
recognizer.addTarget(self, action: #selector(functionForRecognizer[recognizer]!))
recognizer.direction = directionForRecognizer[recognizer]!
self.view?.addGestureRecognizer(recognizer)
}
}
override func didMove(to view: SKView) {
super.didMove(to: view)
setupSwipeRecognizers()
}
}
Btw, i tried putting @objc
while declaring the functions, but it didn't work. Also, I tried exposing the class to NSObject, by removing inheritance from SKScene and conforming to NSObject, and still, it didn't work. Moreover, i cannot conform the class to a UIKit class, cz i need it as a SKScene, and even, i tried conforming it to a UIViewController (without SKScene, of course), but still didn't work,
Upvotes: 3
Views: 2700
Reputation: 6622
What you are trying to do isn't possible with Swift's #selector
. Instead, insert instances of the Selector
class directly into the dictionary.
You'll also need to annotate with @objc
@objc // This annotation isn't required in Swift 3, but will be in Swift 4
func didSwipeRight() {}
var functionForRecognizer: [UISwipeGestureRecognizer : Selector] {
return [
rightSwipeRecognizer : #selector(didSwipeRight)
]
}
recognizer.addTarget(self, action: functionForRecognizer[recognizer]))
For a detailed explanation of #selector
see this answer. Summary, #selector
is a compiler construct for Swift that ensures the exact selector/method exists, including the class it should exist on. It looks at the actual contents within its parentheses to see if it is a known method, and functionForRecognizer[recognizer]
is not a method name, it is a variable + subscript method call.
Upvotes: 4