Swift 在 UITapGestureRecognizer 的操作中使用参数

Using parameters in action of UITapGestureRecognizer in Swift

我正在尝试使用 UITapGestureRecognizer 的操作调用带参数的函数,但我想不出任何替代方法。

这是假设使用 indexPath 参数调用 doubleTap 函数的手势。

var gestureDoubleTap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "doubleTap(indexPath)")

这是应该调用的函数。

func doubleTap(indexPath: NSIndexPath) {
    NSLog("double tap")
    NSLog("%@", indexPath.row)
}

如何使用 indexPath 参数调用 doubleTap 函数?

感谢您提出的所有建议。

EDIT - 这是我的全部代码,它基本上是设置对象 'name' 所以我的第二个 viewController可以得到并使用

import UIKit
class viewController1: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {

    @IBOutlet weak var collectionView: UICollectionView!
    var imageArray:[String] = []
    var name : AnyObject? {
        get {
        return NSUserDefaults.standardUserDefaults().objectForKey("name")
        }
        set {
            NSUserDefaults.standardUserDefaults().setObject(newValue!, forKey: "name")
            NSUserDefaults.standardUserDefaults().synchronize()
        }
    }

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return imageArray.count
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        var cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as myViewCell

        //adding single and double tap gestures for each cell
        /////////////////////////////
        //ISSUE IS SENDING indexPath TO doubleTap FUNC
        var gestureDoubleTap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "doubleTap:")
        gestureDoubleTap.numberOfTapsRequired = 2
        cell.addGestureRecognizer(gestureDoubleTap)

        var gestureSingleTap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "singleTap")
        gestureSingleTap.numberOfTapsRequired = 1
        cell.addGestureRecognizer(gestureSingleTap)

        cell.imgView.image=UIImage(named: imageArray[indexPath.row])        
        return cell
    }

    //func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath){
    //
    //    name = imageArray[indexPath.row]
    //}

    override func viewDidLoad(){
        super.viewDidLoad()
        imageArray=["1.png","2.png","2.png","1.png","1.png","2.png","1.png","2.png","1.png","2.png","1.png","2.png","1.png","2.png","1.png","2.png"]

    }

    func doubleTap(sender: UITapGestureRecognizer) {
        var tapLocation = sender.locationInView(self.collectionView)

        var indexPath:NSIndexPath = self.collectionView.indexPathForItemAtPoint(tapLocation)!

        //var cell = self.collectionView.cellForItemAtIndexPath(indexPath)

        NSLog("double tap")
        NSLog("%@", indexPath)

        //NSLog("%@", cell!)
        //THIS IS THE GOAL----- set 'name' with the appropriate img      corresponding the cell
        //name = imageArray[indexPath]
        //self.performSegueWithIdentifier("segue", sender: nil)
    }

    func singleTap() {
        NSLog("single tap")
    }
}

您需要做的就是调用它,而无需在字符串文字中使用任何类型的参数。

var gestureDoubleTap = UITapGestureRecognizer(target: self, action: "doubleTap:")

: 告诉计算机您正在使用一个带有参数的函数,而该函数是在其他地方创建的。

希望这对您有所帮助:)

鉴于你有 NSIndexPath,我想你想从 UITableView 上的点击触摸点检索相应的 indexPath

UIGestureRecognizer 有一个(或没有)参数。当提供一个时,它会自行传递 - 但是,indexPath 不会 传递给所提到的函数。

假设我们有以下内容:

let aTap = UITapGestureRecognizer(target: self, action: "tapped:")

点击视图时对应的函数:

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!"
 }

更新:

这用于展示如何向视图添加手势识别器,通过它我们检索被点击两次的 cell (item) 的 indexPath

回调函数被触发,在回调函数中我们可以检查点击的cellitem)是否是我们感兴趣的

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(....)
        }
    }
}

另一个更新:

由于您似乎要添加需要双击所有单元格的手势识别器,这告诉我您对双击的任何单元格感兴趣;因此,我们不需要任何条件来检查细胞是否是我们感兴趣的细胞,因为它们都是。

所以:

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)
}

如苹果开发者文档中所述,动作参数应接收

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.

UIGestureRecognizer.h 中描述的有效操作方法签名是:

// -(void)handleGesture; // -(void)handleGesture:(UIGestureRecognizer*)gestureRecognizer;

所以基本上,除了 gestureRecognizer 之外,您 不能 能够将任何其他内容作为参数发送。

实现您所希望的最佳方式是获取您点击手势的超级视图,这将为您提供正确的 indexPath。试试这个:

   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)
    }

您可以根据您的层级增加或减少超级视图。

进一步了解 user2277872 的回复,我也发现它很有用,仅供可能不熟悉的其他人使用 - IBAction 函数可以 通过从 xib 拖动到 class 中的 prewritten 函数来连接 - 如果需要 no parameters(即没有前面提到的 : 字符)。

没有参数的例子

@IBAction private func somethingTapped() {
        ...
}