193 votes

UIButton: Rendre la zone de frappe plus grande que la zone de frappe par défaut

J'ai une question concernant UIButton et sa zone touchée. J'utilise le bouton Info Dark dans le générateur d'interface, mais je trouve que la zone de frappe n'est pas assez grande pour les doigts de certaines personnes.

Existe-t-il un moyen d'augmenter la zone de frappe d'un bouton par programmation ou dans Interface Builder sans modifier la taille du graphique InfoButton?

137voto

Chase Points 7520

Depuis que je suis en utilisant une image de fond, aucune de ces solutions a bien fonctionné pour moi. Voici une solution qui ne prend du plaisir objective-c la magie et offre une goutte dans une solution avec un minimum de code.

Tout d'abord, ajoutez un catégorie d' UIButton qui remplace le test de collision et ajoute également une propriété pour l'expansion de la frapper cadre de test.

UIButton+Extensions.h

@interface UIButton (Extensions)

@property(nonatomic, assign) UIEdgeInsets hitTestEdgeInsets;

@end

UIButton+Extensions.m

#import "UIButton+Extensions.h"
#import <objc/runtime.h>

@implementation UIButton (Extensions)

@dynamic hitTestEdgeInsets;

static const NSString *KEY_HIT_TEST_EDGE_INSETS = @"HitTestEdgeInsets";

-(void)setHitTestEdgeInsets:(UIEdgeInsets)hitTestEdgeInsets {
    NSValue *value = [NSValue value:&hitTestEdgeInsets withObjCType:@encode(UIEdgeInsets)];
    objc_setAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(UIEdgeInsets)hitTestEdgeInsets {
    NSValue *value = objc_getAssociatedObject(self, &KEY_HIT_TEST_EDGE_INSETS);
    if(value) {
        UIEdgeInsets edgeInsets; [value getValue:&edgeInsets]; return edgeInsets;
    }else {
        return UIEdgeInsetsZero;
    }
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    if(UIEdgeInsetsEqualToEdgeInsets(self.hitTestEdgeInsets, UIEdgeInsetsZero) ||       !self.enabled || self.hidden) {
        return [super pointInside:point withEvent:event];
    }

    CGRect relativeFrame = self.bounds;
    CGRect hitFrame = UIEdgeInsetsInsetRect(relativeFrame, self.hitTestEdgeInsets);

    return CGRectContainsPoint(hitFrame, point);
}

@end

Une fois cette classe est ajouté, tout ce que vous devez faire est de régler le bord des encarts de votre bouton. Notez que j'ai choisi d'ajouter des encarts donc, si vous voulez faire de la zone frappée par le plus grand, vous devez utiliser des nombres négatifs.

    [button setHitTestEdgeInsets:UIEdgeInsetsMake(-10, -10, -10, -10)];

Remarque: n'oubliez pas d'importer de la catégorie (#import "UIButton+Extensions.h") dans vos classes.

78voto

Samuel Goodwin Points 1060

Définissez simplement les valeurs d'encart de bord d'image dans le générateur d'interface.

51voto

jlajlar Points 341

Vous pouvez également sous-classer UIButton ou UIView personnalisé et remplacer

 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
 

Dans la méthode, vous pouvez avoir quelque chose comme

 CGFloat margin = 5.0;
CGRect area = CGRectInset(self.bounds, -margin, -margin);
return CGRectContainsPoint(area, point);
 

19voto

Kyle Points 1238

Je recommande de placer un UIButton avec le type Personnalisé centré sur votre bouton info. Redimensionner le bouton personnalisé à la taille que vous voulez le frapper de la zone. À partir de là, vous avez deux options:

  1. Cochez la case " Afficher le toucher de la surbrillance l'option du bouton personnalisé. La lueur blanche apparaît sur le bouton info, mais dans la plupart des cas, les utilisateurs doigt couvre ce et tout ce qu'ils vont voir, c'est la lueur autour de l'extérieur.

  2. Configurer un IBOutlet pour la touche info et deux IBActions pour le bouton personnalisé pour un "Touch Down" et une pour la "Touche Jusqu'à l'Intérieur". Puis dans Xcode faire de l'événement touchdown ensemble de la propriété en surbrillance le bouton info pour OUI et le touchupinside événement définissez la propriété sélectionnée ou PAS.

19voto

Maurizio Points 2933

Ne définissez pas la propriété backgroundImage avec votre image, définissez la propriété imageView . Assurez-vous également d'avoir imageView.contentMode défini sur UIViewContentModeCenter .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X