Oui, un UIGestureRecognizer peut être ajouté à un UIImageView. Comme indiqué dans l'autre réponse, il est très important de ne pas oublier d'activer l'interaction de l'utilisateur sur la vue d'image en définissant sa userInteractionEnabled
propriété sur YES
. UIImageView hérite de UIView, dont la propriété d'interaction utilisateur est définie YES
par défaut, cependant, la propriété d'interaction utilisateur d'UIImageView est définie surNO
par défaut.
À partir de la documentation UIImageView:
Les nouveaux objets de vue d'image sont configurés pour ignorer les événements utilisateur par défaut. Si vous souhaitez gérer des événements dans une sous-classe personnalisée de UIImageView, vous devez explicitement modifier la valeur de la propriété userInteractionEnabled sur YES après l'initialisation de l'objet.
Quoi qu'il en soit, sur l'essentiel de la réponse. Voici un exemple de création d'un UIImageView
avec a UIPinchGestureRecognizer
, a UIRotationGestureRecognizer
et a UIPanGestureRecognizer
.
Tout d'abord, dans viewDidLoad
ou dans une autre méthode de votre choix, créez une vue d'image, donnez-lui une image, un cadre et activez son interaction avec l'utilisateur. Créez ensuite les trois gestes comme suit. Assurez-vous d'utiliser leur propriété de délégué (probablement définie sur self). Cela sera nécessaire pour utiliser plusieurs gestes en même temps.
- (void)viewDidLoad
{
[super viewDidLoad];
// set up the image view
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"someImage"]];
[imageView setBounds:CGRectMake(0.0, 0.0, 120.0, 120.0)];
[imageView setCenter:self.view.center];
[imageView setUserInteractionEnabled:YES]; // <--- This is very important
// create and configure the pinch gesture
UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGestureDetected:)];
[pinchGestureRecognizer setDelegate:self];
[imageView addGestureRecognizer:pinchGestureRecognizer];
// create and configure the rotation gesture
UIRotationGestureRecognizer *rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationGestureDetected:)];
[rotationGestureRecognizer setDelegate:self];
[imageView addGestureRecognizer:rotationGestureRecognizer];
// creat and configure the pan gesture
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureDetected:)];
[panGestureRecognizer setDelegate:self];
[imageView addGestureRecognizer:panGestureRecognizer];
[self.view addSubview:imageView]; // add the image view as a subview of the view controllers view
}
Voici les trois méthodes qui seront appelées lorsque les gestes de votre vue seront détectés. À l'intérieur, nous vérifierons l'état actuel du geste, et s'il est au début ou à la modification, UIGestureRecognizerState
nous lirons la propriété d'échelle / rotation / translation du geste, appliquerons ces données à une transformation affine, appliquerons la transformation affine à l'image vue, puis réinitialisez l'échelle / rotation / translation des gestes.
- (void)pinchGestureDetected:(UIPinchGestureRecognizer *)recognizer
{
UIGestureRecognizerState state = [recognizer state];
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
{
CGFloat scale = [recognizer scale];
[recognizer.view setTransform:CGAffineTransformScale(recognizer.view.transform, scale, scale)];
[recognizer setScale:1.0];
}
}
- (void)rotationGestureDetected:(UIRotationGestureRecognizer *)recognizer
{
UIGestureRecognizerState state = [recognizer state];
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
{
CGFloat rotation = [recognizer rotation];
[recognizer.view setTransform:CGAffineTransformRotate(recognizer.view.transform, rotation)];
[recognizer setRotation:0];
}
}
- (void)panGestureDetected:(UIPanGestureRecognizer *)recognizer
{
UIGestureRecognizerState state = [recognizer state];
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
{
CGPoint translation = [recognizer translationInView:recognizer.view];
[recognizer.view setTransform:CGAffineTransformTranslate(recognizer.view.transform, translation.x, translation.y)];
[recognizer setTranslation:CGPointZero inView:recognizer.view];
}
}
Enfin et surtout, vous devrez utiliser la méthode UIGestureRecognizerDelegategestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer
pour permettre aux gestes de fonctionner en même temps. Si ces trois gestes sont les trois seuls gestes auxquels cette classe est attribuée comme délégué, vous pouvez simplement revenir YES
comme indiqué ci-dessous. Toutefois, si vous avez des gestes supplémentaires auxquels cette classe est attribuée comme délégué, vous devrez peut-être ajouter une logique à cette méthode pour déterminer quel geste est lequel avant de leur permettre de tous travailler ensemble.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
N'oubliez pas de vous assurer que votre classe est conforme au protocole UIGestureRecognizerDelegate . Pour ce faire, assurez-vous que votre interface ressemble à ceci:
@interface MyClass : MySuperClass <UIGestureRecognizerDelegate>
Si vous préférez jouer vous-même avec le code d'un exemple de projet fonctionnel, l'exemple de projet que j'ai créé contenant ce code est disponible ici.