web-dev-qa-db-fra.com

iOS 7.1 UITapGesture ne fonctionne pas avec UIPickerView

Nous utilisons une UIPickerView pour permettre à un utilisateur de choisir parmi une liste d'options. Nous ajoutons UIPickerView en tant que sous-vue d’un conteneur UIView. Nous ajoutons ensuite un UITapGestureRecognizer au conteneur UIView. La UITapGestureRecognizer est utilisée pour fermer le sélecteur via la suppression de sa super vue. 

Dans iOS 7.0 et les versions précédentes, cela fonctionnait comme prévu. Cependant, dans iOS 7.1, cette configuration ne fonctionne plus car UITapGestureRecognizer ne reconnaît pas le tap et n'appelle pas le sélecteur spécifié dans l'action (en supprimant la vue Sélecteur et la vue Conteneur). le code est en dessous 

   - (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.nameList=[[NSMutableArray alloc] initWithObjects:@"A",@"B",@"C", nil];
    UIPickerView *myPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 200, 320, 200)];
    myPickerView.delegate = self;
    myPickerView.showsSelectionIndicator = YES;
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapInListPickerView:)];
    [singleTap setNumberOfTapsRequired:1];
    [singleTap setNumberOfTouchesRequired:1];
    [myPickerView addGestureRecognizer:singleTap];
    [self.view addSubview:myPickerView];
}

-(void)tapInListPickerView:(UIGestureRecognizer *)sender

{
    NSLog(@"Taped in pikcer view");
}

Si d'autres informations sont nécessaires ou s'il existe une méthode plus recommandée, veuillez me le faire savoir.

34
Anupam

J'ai eu le même problème et j'ai finalement eu une révélation: P 

C’était comme si les reconnaissances de geste simultanées sur uiPickerView ne fonctionnaient pas.

donc j'utilise le délégué aux gestes

<
UIGestureRecognizerDelegate>

avec

 // add tap gesture
    UITapGestureRecognizer* gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pickerViewTapGestureRecognized:)];
    [picker addGestureRecognizer:gestureRecognizer];
    gestureRecognizer.delegate = self;

avec 

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    // return
    return true;
}

et puis ça marche!

À plus

87
ZDidier

 

Essayez ce sol:

Définissez gestureRecognizer sur true pour la détecter dans toutes les versions d'ios

Étape 1: Ajouter UIGestureRecognizerDelegate

Étape 2: / Ajoutez le code suivant dans votre fichier de classe

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    // return
    return true;
}
2
svmrajesh

J'ai réussi à presque à restaurer la fonctionnalité d'origine en sous-classant UIPickerView et à remplacer l'implémentation hitTest. La nouvelle implémentation permet d'abord à toutes les lignes du sélecteur de réclamer l'événement tactile avant que je ne permette enfin au sélecteur de le réclamer.

Je dis presque car il y a un autre changement à UIPickerView où les vues visibles dans le sélecteur peuvent ne plus exister. Ainsi, l'utilisateur peut taper une image visible d'une ligne qui n'est pas centrée dans le sélecteur, ce qui peut faire défiler le sélecteur au lieu de sélectionner cette ligne, car elle n'existe plus vraiment.

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if (self.hidden) {
        return nil;
    }
    else {
        if (event.type == UIEventTypeTouches) {
            for (int component = 0; component < self.numberOfComponents; component++) {
                for (int row = 0; row < [self numberOfRowsInComponent:component]; row++) {
                    UIView *view = [self viewForRow:row forComponent:0];
                    if (view) {
                        view = [view hitTest:[self convertPoint:point toView:view] withEvent:event];
                        if (view) {
                            return view;
                        }
                    }
                }
            }
        }
        return [super hitTest:point withEvent:event];
    }
}
2
Doug Gerecht

La réponse acceptée est très utile, merci! Je sous-classais déjà UIPickerView. Donc, après ZDidier, j’ai créé une sous-classe UIGestureRecognizerDelegate et ai ensuite remplacé addGestureRecognizer comme ceci:

- (void)addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
{
    gestureRecognizer.delegate = self;
    [super addGestureRecognizer:gestureRecognizer];
}

Cela a réglé le problème pour moi.

1
John

Méthode rapide pour les paresseux: 

conforme au protocole UIGestureRecognizerDelegate 

et 

override func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}
0
Matthieu Riegler