web-dev-qa-db-fra.com

Événements tactiles sur UITableView?

J'ai UIViewControlleret UITableView comme enfant dans la vue, ce que je veux faire, c'est quand je touche une ligne, j'affiche une vue en bas. Je veux masquer cette vue si l'utilisateur touche n'importe où ailleurs, puis des lignes ou la vue inférieure.

Le problème est que lorsque je clique sur UITableView, il ne déclenche pas l'événement touchesEnded.

Maintenant, comment puis-je détecter toucher sur UITableView et le distinguer avec l'événement de sélection de ligne.

Merci.

28
Kapil Choubisa

Je faisais face au problème depuis longtemps et je n'ai trouvé aucune solution de travail. Enfin, je choisis d'aller avec une alternative. Je sais que techniquement, ce n'est pas la solution, mais cela peut aider quelqu'un à chercher la même chose à coup sûr.

Dans mon cas, je veux sélectionner une ligne qui affichera une option après que je touche n'importe où sur la table ou Afficher, je veux masquer ces options ou effectuer n'importe quelle tâche, sauf la ligne sélectionnée précédemment pour ce que j'ai fait ci-dessous:

  1. Définissez des événements tactiles pour la vue. Cela fera la tâche lorsque vous touchez n'importe où sur la vue à l'exception de la vue de table.

  2. DidSelectRowAtIndexPath de TableView fait ce qui suit

     - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
        if(indexPath.row != previousSelectedRow && previousSelectedRow != -1) {
            // hide options or whatever you want to do
            previousSelectedRow = -1;
        }
        else {
            // show your options or other things
            previousSelectedRow = indexPath.row;
        }
     }
    

Je sais que c'est un poste plus ancien et pas une bonne solution technique mais cela a fonctionné pour moi. Je poste cette réponse car cela peut aider quelqu'un à coup sûr.

Remarque: Le code écrit ici peut contenir des erreurs d'orthographe car il est directement saisi ici. :)

6
Kapil Choubisa

Plus besoin de sous-classer quoi que ce soit, vous pouvez ajouter un UITapGestureRecognizer au UITableView et absorber le geste ou non selon vos critères.

Dans votre viewDidLoad:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapOnTableView:)];
[self.myTableView addGestureRecognizer:tap];

Ensuite, implémentez votre action comme ceci pour les critères:

-(void) didTapOnTableView:(UIGestureRecognizer*) recognizer {
    CGPoint tapLocation = [recognizer locationInView:self.myTableView];
    NSIndexPath *indexPath = [self.myTableView indexPathForRowAtPoint:tapLocation];

    if (indexPath) { //we are in a tableview cell, let the gesture be handled by the view
        recognizer.cancelsTouchesInView = NO;
    } else { // anywhere else, do what is needed for your case
        [self.navigationController popViewControllerAnimated:YES];
    }
}

Et notez que si vous souhaitez simplement récupérer les clics n'importe où sur le tableau, mais pas sur les boutons des lignes de cellule, vous devez uniquement utiliser le premier fragment de code ci-dessus. Un exemple typique est lorsque vous avez un UITableView et qu'il existe également un UISearchBar. Vous souhaitez supprimer la barre de recherche lorsque l'utilisateur clique, fait défiler, etc. la vue de table. Exemple de code ...

-(void)viewDidLoad {
    [super viewDidLoad];
    etc ...

    [self _prepareTable];
}
-(void)_prepareTable {
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.tableView.allowsSelection = NO;
    etc...

    UITapGestureRecognizer *anyTouch =
        [[UITapGestureRecognizer alloc]
         initWithTarget:self action:@selector(tableTap)];
    [self.tableView addGestureRecognizer:anyTouch];
}
// Always drop the keyboard when the user taps on the table:
// This will correctly NOT affect any buttons in cell rows:
-(void)tableTap {
    [self.searchBar resignFirstResponder];
}
// You probably also want to drop the keyboard when the user is
// scrolling around looking at the table. If so:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [self.searchBar resignFirstResponder];
}
// Finally you may or may not want to drop the keyboard when
// a button in one cell row is clicked. If so:
-(void)clickedSomeCellButton... {
    [self.searchBar resignFirstResponder];
    ...
}

J'espère que cela aide quelqu'un.

51
David

Vous devez transmettre l'événement tactile au contrôleur de la vue. Sous-classe votre contrôle tableview, puis remplacez la méthode:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];  //let the tableview handle cell selection 
    [self.nextResponder touchesBegan:touches withEvent:event]; // give the controller a chance for handling touch events 
}

ensuite, vous pouvez faire ce que vous voulez dans les méthodes tactiles du contrôleur.

14
longway

Je suis juste tombé sur ce qui pourrait être une solution à votre problème. Utilisez ce code lorsque vous créez votre vue de table:

tableView.canCancelContentTouches = NO;

Sans définir cette valeur sur NO, les événements tactiles sont annulés dès qu'il y a même un léger mouvement vertical dans votre affichage de table (si vous mettez des instructions NSLog dans votre code, vous verrez que touchesCancelled est appelé dès que le tableau commence à défiler verticalement).

8
MusiGenesis

Essayez ces méthodes:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{

}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{

}

Utilisez scrollViewDidEndDragging comme alternative à touchesEnded. J'espère que cela aide.

3
ZevsVU

Pour recevoir des événements tactiles sur UITableView, utilisez:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
  //<my stuff>

  [super touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
   //<my stuff>

   [super touchesMoved:touches withEvent:event];
}

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
  //<my stuff>

  [super touchesEnded:touches withEvent:event];
}

- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
{
   //<my stuff>
   [super touchesCancelled:touches withEvent:event];
}

recevoir des événements tactiles dans UITableView

2
Ahmad Kayyali