I am trying to call a function with parameters using the action of UITapGestureRecognizer
and I can\'t figure out any alternative.
This here is the gesture
The Best way to achieve what you wish is get the superview of your tap gesture, this will give you the correct indexPath. Try this:
func doubleTap(sender: UITapGestureRecognizer) {
let point = sender.view
let mainCell = point?.superview
let main = mainCell?.superview
let cell: myViewCell = main as! myViewCell
let indexPath = collectionView.indexPathForCell(cell)
}
You can increase or reduce the superview's depending on you hierarchy level.
All you need to do is call it without using any kind of parameters in your string literal.
var gestureDoubleTap = UITapGestureRecognizer(target: self, action: "doubleTap:")
The :
tells the computer that you're using a function with a parameter, and that is created somewhere else.
Hope this helps :)
Further to user2277872
's response that I also found useful, and just for anyone else who may not be familiar - IBAction
functions can also be connected by dragging from the xib to a prewritten function in the class - this is useful if no parameters are desired (i.e. without the :
character that was previously mentioned).
Example with no parameters
@IBAction private func somethingTapped() {
...
}
As described in apple developer documents, the action parameter should receive
action::- A selector that identifies the method implemented by the target to handle the gesture recognized by the receiver. The action selector must conform to the signature described in the class overview. NULL is not a valid value.
And Valid action method signatures described in UIGestureRecognizer.h are:
// -(void)handleGesture; // -(void)handleGesture:(UIGestureRecognizer*)gestureRecognizer;
So basically, you will not be able to send anything else as the parameter except the gestureRecognizer.
Given that you have NSIndexPath
, I suppose you would like to retrieve the corresponding indexPath
from the tap touch point on your UITableView
.
UIGestureRecognizer
has one (or no) parameter. When there is one provided, it passes itself - the indexPath
is, however, not passed to the function as mentioned.
Let's say we have the following:
let aTap = UITapGestureRecognizer(target: self, action: "tapped:")
and the corresponding function when the view is tapped on:
func tapped(sender: UITapGestureRecognizer)
{
//using sender, we can get the point in respect to the table view
let tapLocation = sender.locationInView(self.tableView)
//using the tapLocation, we retrieve the corresponding indexPath
let indexPath = self.tableView.indexPathForRowAtPoint(tapLocation)
//finally, we print out the value
print(indexPath)
//we could even get the cell from the index, too
let cell = self.tableView.cellForRowAtIndexPath(indexPath!)
cell.textLabel?.text = "Hello, Cell!"
}
Update:
This serves to show how to add a gesture recognizer to the view, through which we retrieve the indexPath
of the cell
(item
) that was tapped on twice.
The callback function is triggered, within which we could check whether or not the cell
(item
) that was tapped on is the one we are interested in.
override func viewDidLoad()
{
super.viewDidLoad()
let doubleTaps = UITapGestureRecognizer(target: self, action: "doubleTapTriggered:")
doubleTaps.numberOfTapsRequired = 2
self.view.addGestureRecognizer(doubleTaps)
}
func doubleTapTriggered(sender : UITapGestureRecognizer)
{
var tapLocation = sender.locationInView(self.collectionView)
var indexPath : NSIndexPath = self.collectionView.indexPathForItemAtPoint(tapLocation)!
if let cell = self.collectionView.cellForItemAtIndexPath(indexPath)
{
if(cell.tag == 100)
{
print("Hello, I am cell with tag 100")
}
else if(cell.tag == 99)
{
print("Hello, I am cell with tag 99")
//We could do something, then, with the cell that we are interested in.
//I.e., cell.contentView.addSubview(....)
}
}
}
Another Update:
Since it appears that you are adding gesture recognizer that requires double taps to all cells, which tells me that you are interested in any cell that was double-tapped on; and so, we would't need any condition to check whether or not the cells are the ones we are interested in, because they all are.
And so:
func doubleTapTriggered(sender : UITapGestureRecognizer)
{
var tapLocation = sender.locationInView(self.collectionView)
var indexPath : NSIndexPath = self.collectionView.indexPathForItemAtPoint(tapLocation)!
name = imageArray[indexPath]
self.performSegueWithIdentifier("segue", sender: nil)
}