2014-06-10 7 views
16

Ho un controller di visualizzazione con UITableView. L'altezza della vista tabella è statica e == altezza dello schermo. Il numero di righe nella tabella può cambiare e a volte potrebbe essere una situazione in cui il numero di righe è inferiore al numero di righe che possono essere visibili, quindi appare un'area libera nella parte inferiore della tabella. Posso rilevare toccarlo senza il riconoscimento dei gesti? Esistono metodi delegati di UITableView?Come rilevare toccare una parte chiara di UITableView?

+0

Per didSelectRowAtIndexPath uso selezionato oppure puoi anche usare tapgesture. –

+0

@VictorIppolitov Cosa ne pensi di creare una sub-classe UITableView, assegnarla alla tua vista tabella, e sovrascrivere i tocchi Inizia sulla nuova sottoclasse? –

risposta

37

Sì, ci sono metodi delegato, come ad esempio:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 

Tuttavia, questo sarà solo dirvi se un rubinetto si verifica su una riga esistente. Se si desidera catturare i tocchi sullo spazio vuoto sotto le righe (o sull'intestazione di una sezione) sarà necessario utilizzare un riconoscitore di gesti. Si può fare qualcosa di simile:

// in viewDidLoad or somewhere similar 
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tableTapped:)]; 
[self.tableView addGestureRecognizer:tap]; 
//......... 

- (void)tableTapped:(UITapGestureRecognizer *)tap 
{ 
    CGPoint location = [tap locationInView:self.tableView]; 
    NSIndexPath *path = [self.tableView indexPathForRowAtPoint:location]; 

    if(path) 
    { 
     // tap was on existing row, so pass it to the delegate method 
     [self tableView:self.tableView didSelectRowAtIndexPath:path]; 
    } 
    else 
    { 
     // handle tap on empty space below existing rows however you want 
    } 
} 

EDIT: per un approccio alternativo, in considerazione Connor Neville's approach dalla sua risposta su questo post e aggiungere il sistema di riconoscimento gesto di sfondo della tabella.

+0

Stai cercando di afferrare un gesto su un'area che non acquisisce automaticamente i gesti tramite il delegato, quindi AFAIK non consente di individuare facilmente un rilevatore di gesti. – Stonz2

+0

Ora un evento non può gestire "tableTapped". Ho aggiunto UIGestureRecognizerDelegate ma non funziona. –

+0

@VictorIppolitov potrebbe essere necessario cambiare il nome della variabile da 'self.tableView' a qualunque sia il nome della variabile di istanza/classe per la tabella. – Stonz2

-4

Non è necessario il riconoscimento dei gesti. Si dovrebbe impliment <UITableViewDelegate> nella vostra ViewController.h e quindi aggiungere questo metodo per il vostro ViewController.m:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 

dove indexPath è indice della riga/colonna cliccato.

+1

Questo non fornirà alcuna informazione sui tocchi sul 'tableView' che si trovano nello spazio vuoto sotto le righe esistenti, che è ciò che chiede il richiedente. – Stonz2

14

Grazie a @ Stonz2, versione rapida:

Swift 4

let tap = UITapGestureRecognizer(target: self, action: #selector(tableTapped)) 
self.tableView.addGestureRecognizer(tap) 

@objc func tableTapped(tap:UITapGestureRecognizer) { 
    let location = tap.location(in: self.tableView) 
    let path = self.tableView.indexPathForRow(at: location) 
    if let indexPathForRow = path { 
     self.tableView(self.tableView, didSelectRowAt: indexPathForRow) 
    } else { 
     // handle tap on empty space below existing rows however you want 
    } 
} 

Swift 3

let tap = UITapGestureRecognizer(target: self, action: #selector(tableTapped)) 
self.tableView.addGestureRecognizer(tap) 

func tableTapped(tap:UITapGestureRecognizer) { 
    let location = tap.location(in: self.tableView) 
    let path = self.tableView.indexPathForRow(at: location) 
    if let indexPathForRow = path { 
     self.tableView(self.tableView, didSelectRowAt: indexPathForRow) 
    } else { 
     // handle tap on empty space below existing rows however you want 
    } 
} 

Swift 2:

let tap = UITapGestureRecognizer(target: self, action: #selector(tableTapped)) 
self.tableView.addGestureRecognizer(tap) 


func tableTapped(tap:UITapGestureRecognizer) { 
    let location = tap.locationInView(self.tableView) 
    let path = self.tableView.indexPathForRowAtPoint(location) 
    if let indexPathForRow = path { 
     self.tableView(self.tableView, didSelectRowAtIndexPath: indexPathForRow) 
    } else { 
     // handle tap on empty space below existing rows however you want 
    } 
} 
22

Tutte le risposte fornite, inclusa la risposta accettata, aggiungerea tableView; mentre questo funzionerà, ho scoperto che questo riconoscitore di gesti può interferire con i tocchi di riga e innescare didSelectRowAtIndexPath in un modo alquanto imprevedibile/non deterministico.

Se si desidera rilevare i rubinetti nel "spazio vuoto", così come nelle righe, consiglio vivamente l'aggiunta di una vista di sfondo al vostro tavolo, e aggiungi il sistema di riconoscimento gesto c'è:

let tap = UITapGestureRecognizer(target: self, action: #selector(tableTapped)) 
self.tableView.backgroundView = UIView() 
self.tableView.backgroundView?.addGestureRecognizer(tap) 
+5

** Questa è la migliore risposta **: conserva anche il risponditore della selezione 'tableView' in modo da poter vedere anche la selezione delle tue righe. –

+0

Grazie per aver condiviso. –

Problemi correlati