Comment puis-je savoir quand a été touché quelque chose en dehors de mon UITableViewCell?

StackOverflow https://stackoverflow.com/questions/2450127

Question

Tout comme href="https://stackoverflow.com/questions/1591738/resignfirstresponder-when-tapping-uitableview"> j'ai une sous-classe personnalisée de UITableViewCell qui a un UITextField. Son beau travail à l'exception du clavier pour ne disparaît pas lorsque l'utilisateur touche une cellule de vue autre table ou quelque chose en dehors de la table. J'essaie de trouver le meilleur endroit pour savoir quand quelque chose en dehors de la cellule est touchée, alors je pourrais appeler resignFirstResponder sur le champ de texte.

Si le UITableViewCell pourrait recevoir des événements tactiles pour des touches en dehors de son point de vue il pourrait juste resignFirstResponder lui-même, mais je ne vois aucune façon d'obtenir ces événements dans la cellule.

EDIT: J'ai essayé (ci-dessous) dans ma sous-classe UITableViewCell mais il ne fonctionne pas, je pense que touchesBegan: withEvent: ne soit pas appelé si l'événement a été assurée par un contrôle. Je pense que je dois attraper les événements avant qu'ils ne se fait descendre la chaîne de répondeur en quelque sorte.

La solution que je considère est d'ajouter un touchesBegan: withEvent: méthode au contrôleur de vue. Là, je pouvais envoyer un resignFirstResponder à toutes les cellules de Tableview qui sont visibles, sauf celui que le toucher était (le laisser utiliser l'événement tactile et de la manipuler lui-même).

Peut-être quelque chose comme ce code pseudo:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    CGPoint touchPoint = // TBD - may need translate to cell's coordinates

    for (UITableViewCell* aCell in [theTableView visibleCells]) {
        if (![aCell pointInside:touchPoint withEvent:event]) {
             [aCell resignFirstResponder];
        }
    }
}

Je ne suis pas sûr que ce soit la meilleure façon d'aller à ce sujet. Il ne semble pas y avoir de moyen pour le tableviewcell lui-même pour recevoir des notifications d'événements pour les événements en dehors de son point de vue.

EDIT2: Je pensais avoir une réponse (j'ai même posté comme une réponse) à l'aide hitTest: withEvent: mais cela ne fonctionne pas. Il ne va pas toujours appelé. : - (

Était-ce utile?

La solution

[Modifié: suppression précédente tentative qui ne fonctionne pas toujours, celui-ci ne]

OK, j'ai finalement une solution qui fonctionne pleinement. Je UITableView et l'emportaient sur sous-classé le hitTest: withEvent: méthode. Il s'invoqué pour toutes les touches partout dans la vue de la table, les seules autres touches possibles sont dans la barre de navigation ou le clavier et hitTest n'a pas besoin de connaître l'tableview de ceux.

Cela permet de maintenir une trace de la cellule active dans la vue de la table, et chaque fois que vous appuyez sur une autre cellule (ou non-cellulaire), il envoie un resignFirstResponder à la cellule va inactive, ce qui lui donne une chance de cacher son clavier (ou son datepicker).

-(UIView*) hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
    // check to see if the hit is in this table view
    if ([self pointInside:point withEvent:event]) {
        UITableViewCell* newCell = nil;

        // hit is in this table view, find out 
        // which cell it is in (if any)
        for (UITableViewCell* aCell in self.visibleCells) {
            if ([aCell pointInside:[self convertPoint:point toView:aCell] withEvent:nil]) {
                newCell = aCell;
                break;
            }
        }

        // if it touched a different cell, tell the previous cell to resign
        // this gives it a chance to hide the keyboard or date picker or whatever
        if (newCell != activeCell) {
            [activeCell resignFirstResponder];
            self.activeCell = newCell;   // may be nil
        }
    }

    // return the super's hitTest result
    return [super hitTest:point withEvent:event];   
}    

Dans mes sous-classes UITableViewCell qui ont un UITextField, j'ajouter le code suivant pour se débarrasser du clavier (ou sélecteur de date, qui glisse vers le haut comme le clavier):

-(BOOL)resignFirstResponder
{   
    [cTextField resignFirstResponder];  
    return [super resignFirstResponder];
}

Yay!

Autres conseils

Je pense que vous êtes sur la bonne voie, mais touchesBegan:withEvent: est une méthode de UIResponder, de sorte que vous auriez fait de passer outre dans une sous-classe UIView plutôt que dans votre sous-classe UIViewController. Vos options sont:

  • Si vous êtes déjà UITableViewCell le sous-classement, override touchesBegan:withEvent: il.
  • Si vous utilisez une norme UITableViewCell, mettre en œuvre tableView:didSelectRowAtIndexPath dans le délégué de votre UITableView.

C'est une très bonne solution, le mieux que je l'ai trouvé sur le net. Le seul petit problème que je l'ai découvert est que si vous passez d'une cellule avec un autre textfield, le clavier rejette et reparaît résultant dans une animation de type saccadé.

scroll top