selector with argument gestureRecognizer - swift

Argument of '#selector' does not refer to an '#objc' method, property,
or initializer
Problem : Above Error when i try to pass argument with selector
code snippet:
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(labelPressed(i: 1)))
func labelPressed(i: Int){
print(i)
}

You cannot pass a parameter to a function like that. Actions - which this is, only pass the sender, which in this case is the gesture recognizer. What you want to do is get the UIView you attached the gesture to:
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(labelPressed())
func labelPressed(_ recognizer:UITapGestureRecognizer){
let viewTapped = recognizer.view
}
A few more notes:
(1) You may only attach a single view to a recognizer.
(2) You might want to use both the `tag` property along with the `hitTest()` method to know which subview was hit. For example:
let view1 = UIView()
let view2 = UIView()
// add code to place things, probably using auto layout
view1.tag = 1
view2.tag = 2
mainView.addSubview(view1)
mainView.addSubview(view2)
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(mainViewTapped())
func mainViewTapped(_ recognizer:UITapGestureRecognizer){
// get the CGPoint of the tap
let p = recognizer.location(in: self)
let viewTapped:UIView!
// there are many (better) ways to do this, but this works
for view in self.subviews as [UIView] {
if view.layer.hitTest(p) != nil {
viewTapped = view
}
}
// if viewTapped != nil, you have your subview
}

You just should declare function like this:
#objc func labelPressed(i: Int){ print(i) }

Update for Swift 3:
Using more modern syntax, you could declare your function like this:
#objc func labelTicked(withSender sender: AnyObject) {
and initialize your gesture recognizer like this, using #selector:
UITapGestureRecognizer(target: self, action: #selector(labelTicked(withSender:)))

Related

Pass UITextView tag as a parameters in UITapGestureRecognizer in swift 5

Is there any way to pass UITextView Tag in UITapGestureRecognizer #Selector method in swift 5?
like below code
if yes -> How?
if no -> Why?
let txtView1Tap = UITapGestureRecognizer(target: self, action: #selector(textViewTapped(_:),tag: txtView1.tag))
let txtView2Tap = UITapGestureRecognizer(target: self, action: #selector(textViewTapped(_:), tag: txtView2.tag))
txtView1.addGestureRecognizer(txtView1Tap)
txtView2.addGestureRecognizer(txtView1Tap)
No, because there is no API to do that.
But you can get the text view from the UITapGestureRecognizer with the view property
#obj func textViewTapped(_ sender : UITapGestureRecognizer) {
let textView = sender.view as! UITextView
if textView.tag == ...
}

Gesture recognizer is not working on UIView

I'm trying to get a few gesture recognisers to work on a UIView. The UIview is in this case a retrieved SVG image, the library that I use is SwiftSVG.
But the actual added image is a UIView, so I think that is not the problem?
override func viewDidLoad() {
super.viewDidLoad()
let svgURL = URL(string: "https://openclipart.org/download/181651/manhammock.svg")!
let hammock = UIView(SVGURL: svgURL) { (svgLayer) in
svgLayer.fillColor = UIColor(red:0.8, green:0.16, blue:0.32, alpha:1.00).cgColor
svgLayer.resizeToFit(self.v2imageview.bounds)
}
hammock.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
hammock.isUserInteractionEnabled = true;
hammock.addGestureRecognizer(tap)
self.view.addSubview(hammock)
}
// function which is triggered when handleTap is called
#objc func handleTap(_ sender: UITapGestureRecognizer) {
print("Hello World")
}
How can I make the recognizer work?
Thanks
You need to set a frame
hammock.frame = ///
or constraints

Add tap gesture recognizer from another file

Currently I have 2 classes: ViewController and class A. My objective is to add tap gesture recognizer to a UIView from class A. My ViewController:
class ViewController {
#IBOutlet var area: UIView!
func enterClassA() {
let classA = A(self.area)
//some processing
}
}
class A : UIGestureRecognizerDelegate {
private var currView: UIView!
init(newView: UIView) {
self.currView = newView
self.addTapGesture()
}
func addTapGesture() {
let tap = UITapGestureRecognizer(target: self.currView, action:#selector(tapDetected(_:)))
tap.delegate = self.currView as! UIGestureRecognizerdelegate? //***
self.currView.addGestureRecognizer(tap)
}
#objc func tapDetected(_ tapGesture: UIGesturerecognizer) {
print ("Tap detected!")
}
}
But now it's giving error: could not cast value of type 'UIView' to "UIGestureRecognizerDelegate". I tried modifying line *** to
tap.delegate = self
But it's still not working, showing error: unrecognized selector sent to instance. Deleting the line gives the same error. May I know if this is even doable or not (adding gesture recognizer from a different class)? If so then how should I approach it?
In this line
let tap = UITapGestureRecognizer(target: self.currView, action:#selector(tapDetected(_:)))
You say the gesture recognizer to search the tapDetected() function in the self.currView object. Try to change the target:
let tap = UITapGestureRecognizer(target: self, action:#selector(tapDetected(_:)))
And yes, it should be like that:
tap.delegate = self
Since your A class conforms to UIGestureRecognizerDelegate.

How to make a gestureRecogniser selector work in swift 3?

Below is the code I have been using to try and add a gesture recogniser to something. I am getting the yellow error: "No method declared with objective C selector dragging" and then the program is crashing when I go to pan on it. The code and way of using a selector seems to work in all tutorials but it's the problem here.
class GameViewController: UIViewController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let p = UIPanGestureRecognizer(target: self, action: #selector("dragging"))
p.delegate = self
characterGridView!.addGestureRecognizer(p)
}
func dragging(p: UIPanGestureRecognizer) {
print("works")
}
Your selector is incorrect.
Change
let p = UIPanGestureRecognizer(target: self, action: #selector("dragging"))
to
let p = UIPanGestureRecognizer(target: self, action: #selector(dragging(p:)))

Pass a function to a #selector

I get a function as function parameter and want to set this in a #selector.
But I get the error message:
Argument of '#selector' cannot refer to a property
I have the following function:
private func addGestureRecognizerToItem(selector: () -> ()) {
let labelGesture = UITapGestureRecognizer(target: self, action: #selector(selector))
let imageGesture = UITapGestureRecognizer(target: self, action: #selector(selector))
label.addGestureRecognizer(labelGesture)
imageView.addGestureRecognizer(imageGesture)
}
Any ideas how to handle this?
How about this?
class ViewController: UIViewController {
let label = UILabel()
let imageView = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
addGestureRecognizerToItem(#selector(test))
}
func test() {
}
private func addGestureRecognizerToItem(selector: Selector) {
let labelGesture = UITapGestureRecognizer(target: self, action: selector)
let imageGesture = UITapGestureRecognizer(target: self, action: selector)
label.addGestureRecognizer(labelGesture)
imageView.addGestureRecognizer(imageGesture)
}
}
It's not possible, rather you can call your desired function from the return of the first function whose data you want to pass to the other one.
And your scenario may change according to your requirement.