2012-06-17 12 views
15

Ho creato uno UITableView con un UITableViewCell personalizzato. La mia cella include uno UIImageView a sinistra e UITextView a destra.come distinguere quale parte di UITableViewCell è stata cliccata

All'interno di UITableViewController, ho impostato sia l'immagine che il testo in tableview cellForRowAtIndexPath.

Tutto si vede bene, ma ora ho bisogno di implementare didSelectRowAtIndex e ho bisogno di distinguere se è stato fatto clic su UIImageView o UITextView della cella.

Diciamo che il clic sull'immagine rappresenta l'azione di cancellazione e il resto dell'azione di modifica della cella.

risposta

48

Invece di aggiungere i riconoscitori di gesti a ogni singola cella, è possibile aggiungerne uno alla vista tabella e determinare quale cella è stata selezionata dal punto di contatto dell'utente, quindi determinare se l'utente ha toccato l'immagine o la cella.

Prima di tutto assicurarsi che il controller adotti il ​​protocollo UIGestureRecognizerDelegate.

@interface MyTableViewController() <UIGestureRecognizerDelegate> 
@end 

quindi aggiungere il UIGestureRecognizer alla UITableView quando i carichi di vista.

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; 
    singleTap.delegate = self; 
    singleTap.numberOfTapsRequired = 1; 
    singleTap.numberOfTouchesRequired = 1; 
    [self.tableView addGestureRecognizer:singleTap]; 
} 

Questo metodo delegato determina se il metodo handleTap: deve essere eseguito. Se riesce a trovare un indexPath da parte degli utenti, restituisce YES altrimenti restituisce NO.

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 
{ 
    UITableView *tableView = (UITableView *)gestureRecognizer.view; 
    CGPoint p = [gestureRecognizer locationInView:gestureRecognizer.view]; 
    if ([tableView indexPathForRowAtPoint:p]) { 
     return YES; 
    } 
    return NO; 
} 

Una volta che abbiamo determinato se l'utente ha fatto clic in una cella, il handleTap: metodo è chiamato, che decide poi se l'utente ha toccato l'immagine, o di qualsiasi altra parte della cellula.

- (void)handleTap:(UITapGestureRecognizer *)tap 
{ 
    if (UIGestureRecognizerStateEnded == tap.state) { 
     UITableView *tableView = (UITableView *)tap.view; 
     CGPoint p = [tap locationInView:tap.view]; 
     NSIndexPath* indexPath = [tableView indexPathForRowAtPoint:p]; 
     [tableView deselectRowAtIndexPath:indexPath animated:NO]; 
     UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
     CGPoint pointInCell = [tap locationInView:cell]; 
     if (CGRectContainsPoint(cell.imageView.frame, pointInCell)) { 
      // user tapped image 
     } else { 
      // user tapped cell 
     } 
    } 
} 
+0

Per coloro che non conoscono. Tutte le impostazioni di 'UITapGestureRecognizer' in' viewDidLoad' possono anche essere eseguite nel layout dell'interfaccia utente Xcode (aka IB). Dovrai cambiare il tipo di ritorno di 'handleTap:' a 'IBAction'. – ThomasW

1

una risposta molto astratto e generale è quello di effettuare le seguenti operazioni Per ogni UIImage e UILabel si aggiungono impostare la loro etichetta di essere il indexPath.row

//When creating the label and image add a recognizer to them 
label.tag = indexPath.row; 
imageView.tag = indexPath.row; 

Quindi aggiungere un UITapGestureRecognizer su ogni immagine ed etichetta, in questo modo

UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self 
                       action:@selector(handleTap:)]; 
    [label addGestureRecognizer:recognizer]; 
    [imageView addGestureRecognizer:recognizer]; 
} 

- (void) handleTap:(UITapGestureRecognizer*)recognizer 
{ 
    UIView *view = recognizer.view; 
    int row = view.tag; 
    if ([view isKindOfClass:[UILabel class]]) { 
     //Row is row 
     //and the label is pressed 
    } 

    if ([view isKindOfClass:[UIImageView class]]) { 
     //Row is row 
     //and the imageview is pressed 
    } 
} 
5

Si potrebbe sottoclasse UITableViewCell e sovrascrivere touchesEnded.

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 

    [super touchesEnded:touches withEvent:event]; 

    UITouch *touch = [touches anyObject]; 
    CGPoint location = [touch locationInView:self]; 

    UIView *hitView = [self hitTest:location withEvent:event]; 

    if (hitView == myImageView) ...; 
    if (hitView == myTextView) ...; 
} 

è necessario tenere qualche riferimento al vostro UIImageView e UITextView (dovrebbero probabilmente essere proprietà del vostro cellulare).

Ovviamente è possibile sostituire touchesBegan anziché touchesEnded, dipende dalla funzionalità che si desidera raggiungere.

0

si hanno due possibilità è quella di implementare: - 1 - aggiungere UITapGestureRecognizer nel vostro "UITableViewCell" e lo rendono punto per vedere l'immagine e pass "indexpath", come parametro di selezione e rendere il delegato passarlo a tableviewcell

UILabel *label = =[UILabel alloc]init]; 
label.userInteractionEnabled = YES; 
UITapGestureRecognizer *tapGesture = 
[[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelTap)]  autorelease]; 
[label addGestureRecognizer:tapGesture]; 


-(void)labelTap{ 
[delegate [email protected](labeltapped:)withobject:indexpath]; 
} 

2- Secondo modo è controllare il mittente di DidSelectRowAtIndexPath di tipo [imageview o etichetta]; ma preferisco il primo modo

1

Rendi l'immagine un UIButton. Quando viene attivata l'azione del pulsante, l'utente ha toccato l'immagine (la cella NON sarà selezionata). Se la cella è selezionata, si sa che l'utente ha toccato da qualche altra parte sulla riga (inclusa la visualizzazione del testo o l'etichetta).

Inoltre, imposta la proprietà del tag del pulsante su, ad es. l'indice di riga della cella in modo da poter sapere quale immagine della riga è stata selezionata.

+0

Ma come è, questo non gestisce colpi, se è quello che state cercando ... –

Problemi correlati