2015-08-19 16 views
16

Sto tentando di chiamare una funzione con parametri utilizzando l'azione di UITapGestureRecognizer e non riesco a trovare alcuna alternativa.Utilizzo dei parametri in azione di UITapGestureRecognizer in Swift

Questo è il gesto che si suppone chiamino la funzione doubleTap con il parametro indexPath.

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

Questa qui è la funzione che è supponiamo di essere chiamato.

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

Come posso chiamare la funzione doubleTap con il parametro indexPath?

Grazie per tutti i suggerimenti.

EDIT - questo è tutto il mio codice, è fondamentalmente allestendo il 'nome' oggetto in modo mio secondo viewController può ottenere e usarlo

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

risposta

38

Dato che avete NSIndexPath, suppongo che si desidera recuperare il corrispondente indexPath dal punto di filettatura tocco sul tuo UITableView.

UIGestureRecognizer ha un parametro (o nessun). Quando ce n'è uno fornito, passa da solo - lo indexPath è, tuttavia, non passato alla funzione come menzionato.

diciamo che abbiamo la seguente:

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

e la funzione corrispondente quando la vista è sfruttato su:

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

Aggiornamento:

questo serve a dimostrare come aggiungere un riconoscimento di gesture alla vista, attraverso il quale si recupera lo indexPath del (item) che è stato toccato due volte.

La funzione di richiamata è attivata, all'interno della quale è possibile verificare se lo cell (item) che è stato toccato è quello che ci interessa.

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

Un altro aggiornamento:

Poiché sembra che si sta aggiungendo gesto riconoscitore che richiede doppi rubinetti a tutte le cellule, che mi dice che siete interessati a qualsiasi cella che era a doppio sfruttato sopra; e così, non avremmo bisogno di alcuna condizione per verificare se le cellule siano o meno quelle a cui siamo interessati, perché sono tutte.

E così:

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

Ok, questo ha senso, tranne che sto usando UICollectionView, sto indovinando la sua stessa procedura e posso ottenere il tapLocation e indexPath di UICollectionCell? – Cherryholme

+0

Non riesco a ottenere un intero da indexPath. quando stampo indexPath ottengo "0xc000000000000016> {length = 2, path = 0 - 0}" nella mia console. come faccio a ottenere lo 0 da questo indexPath? indexPath.row non funziona, si dice che non è un membro di indexPath – Cherryholme

+0

Se aggiungo il riconoscimento di gesture alla vista di qualsiasi tocco o doppio tocco attiverà il gesto, ne ho bisogno in modo che ogni cella abbia la propria funzione quando viene toccato o toccato due volte – Cherryholme

0

Tutto quello che dovete fare è chiamare senza usare alcun tipo di parametro nella stringa letterale.

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

Il : dice al computer che si sta utilizzando una funzione con un parametro, e che viene creato da qualche altra parte.

Spero che questo aiuti :)

+0

okay, per me è un po 'sensato, ma in che modo DoubleTap func riceve effettivamente la variabile indexPath? – Cherryholme

+0

Sarà chiamato attraverso la tua azione. La funzione che viene chiamata gestisce tutte le informazioni sui parametri – user2277872

0

Come descritto nei documenti di Apple Developer, il parametro di azione dovrebbe ricevere

azione :: - Un selettore che identifica il metodo attuato dal target gestire il gesto riconosciuto dal ricevitore. Il selettore di azioni deve essere conforme alla firma descritta nella panoramica della classe. NULL non è un valore valido.

e valida azione firme dei metodi descritti in UIGestureRecognizer.h sono:

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

Quindi, in pratica, voi non essere in grado di inviare qualsiasi altra cosa come il parametro tranne il gestureRecognizer.

3

Il modo migliore per ottenere ciò che desideri è ottenere il superview del tuo gesto di tocco, questo ti darà il giusto indexPath. Prova questo:

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

È possibile aumentare o ridurre le panoramiche a seconda del livello della gerarchia.

+3

In realtà, questo non è assolutamente il modo migliore. Soprattutto in considerazione della domanda e delle risposte esistenti. – SmokeDispenser