web-dev-qa-db-fra.com

UIButton touch est retardé dans UIScrollView

Je rencontre un petit problème dans mon application. 

J'ai essentiellement une série de UIButtons ajoutée en tant que sous-vues dans une UIScrollView qui fait partie d'une nib. Chaque fois que je tape sur un bouton, il s'écoule un délai notable avant que le bouton ne soit en surbrillance. Je dois essentiellement le maintenir pendant environ une demi-seconde avant que le bouton s'assombrisse et semble sélectionné.

Je suppose que ceci est dû au fait que la variable UIScrollView doit déterminer si le contact est un parchemin ou s'il s'agit d'un contact destiné à une sous-vue.

En tout cas, je suis un peu incertain sur la façon de procéder. Je veux simplement que le bouton apparaisse sélectionné dès que je le tape.

Toute aide est appréciée!

Modifier:

J'ai essayé de régler delaysContentTouches sur NO mais le défilement devient presque impossible car une majorité de mes scrollView est rempli avec UIButtons.

47
Jeff

Ok, j'ai résolu ce problème en sous-classant UIScrollView et en remplaçant touchesShouldCancelInContentView

Maintenant, ma UIButton qui a été marquée comme 99 se met correctement en surbrillance et mon scrollview défile!

myCustomScrollView.h :

@interface myCustomScrollView : UIScrollView  {

}

@end

et myCustomScrollView.m :

@implementation myCustomScrollView

    - (BOOL)touchesShouldCancelInContentView:(UIView *)view
    {
        NSLog(@"touchesShouldCancelInContentView");

        if (view.tag == 99)
            return NO;
        else 
            return YES;
    }
40
Jeff

La solution de Jeff ne fonctionnait pas vraiment pour moi, mais celle-ci ressemble: http://charlesharley.com/2013/programming/uibutton-in-uitableviewcell-has-no-highlight-state

En plus de remplacer touchesShouldCancelInContentView dans votre sous-classe de vue de défilement, vous devez toujours définir delaysContentTouches sur false. Enfin, vous devez renvoyer true au lieu de false pour vos boutons. Voici un exemple modifié du lien ci-dessus. Comme suggéré par les commentateurs, il vérifie spécifiquement toute sous-classe de UIControl plutôt que UIButton afin que ce comportement s'applique à tout type de contrôle.

Objectif c:

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.delaysContentTouches = false;
    }

    return self;
}

- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
    if ([view isKindOfClass:UIControl.class]) {
        return true;
    }

    return [super touchesShouldCancelInContentView:view];
}

Swift 4:

override func touchesShouldCancel(in view: UIView) -> Bool {
    if view is UIControl {
        return true
    }
    return super.touchesShouldCancel(in: view)
}
45
jlong64

Essayez de définir la propriété UIScrollView delaysContentTouches sur NO.

26
Vladimir

Dans Swift 3:

import UIKit

class ScrollViewWithButtons: UIScrollView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        myInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        myInit()
    }

    private func myInit() {
        self.delaysContentTouches = false
    }

    override func touchesShouldCancel(in view: UIView) -> Bool {
        if view is UIButton {
            return true
        }
        return super.touchesShouldCancel(in: view)
    }
}

Vous pouvez ensuite utiliser cette ScrollViewWithButtons dans IB ou dans le code.

1
Simon Reggiani

Solution de scénarimage: sélectionnez la vue de défilement, ouvrez l'inspecteur d'attributs et décochez la case Retarder les contacts de contenu

 enter image description here

1
José

Aucune des solutions existantes n'a fonctionné pour moi. Peut-être que ma situation est plus unique.

J'ai plusieurs UIButtonssans UIScrollView. Lorsque vous appuyez sur une UIButton, une nouvelle UIViewController est présentée à l'utilisateur. Si un bouton est enfoncé et maintenu suffisamment longtemps, il affichera son état enfoncé. Mon client se plaignait du fait que si vous appuyez trop rapidement, aucun état dépressif n'est affiché.

Ma solution: À l’intérieur de la méthode de tapotement UIButtons ', où je charge le nouveau UIViewController et le présente à l’écran, j’utilise

[self performSelector:@selector(loadNextScreenWithOptions:) 
           withObject:options 
           afterDelay:0.]

Ceci planifie le chargement de la prochaine UIViewController sur la prochaine boucle d'événements. Laisser le temps à la UIButton de se redessiner. La UIButton affiche maintenant son état déprimé avant de charger la prochaine UIViewController.

0
Brad Goss

Swift 3:

scrollView.delaysContentTouches = false
0
Oubaida AlQuraan