84 votes

Comment faire un zoom avant/arrière sur un objet UIImage lorsque l'utilisateur pince l'écran ?

Je voudrais faire un zoom avant/arrière sur un objet UIImage lorsque l'utilisateur effectue l'action standard de pincement sur mon application. J'utilise actuellement une UIImageView pour afficher mon image, si ce détail peut m'aider.

J'essaie de trouver comment faire, mais sans succès pour l'instant.

Des indices ?

85voto

Brad Larson Points 122629

Une autre façon simple de procéder est de placer votre UIImageView dans un UIScrollView . Comme je le décris ici vous devez définir le ContentSize de la vue défilante de manière à ce qu'il soit identique à celui de l'affichage de l'image. UIImageView's taille. Définissez votre instance de contrôleur pour qu'elle soit le délégué de la vue de défilement et implémentez la fonction viewForZoomingInScrollView: y scrollViewDidEndZooming:withView:atScale: pour permettre le zoom par pincement et le panoramique de l'image. C'est effectivement ce que fait la solution de Ben, mais d'une manière un peu plus légère, puisque vous n'avez pas les frais généraux d'une vue Web complète.

Un problème que vous pouvez rencontrer est que la mise à l'échelle dans la vue défilante se fait sous la forme de transformations appliquées à l'image. Cela peut entraîner des flous à des facteurs de zoom élevés. Pour quelque chose qui peut être redessiné, vous pouvez suivre mes suggestions aquí pour obtenir un affichage plus net une fois le geste de pincement terminé. La solution de hniels pourrait être utilisée à ce moment-là pour redimensionner votre image.

2 votes

Assurez-vous de modifier maximumZoomScale et/ou minimumZoomScale :).

48voto

JRV Points 328

La solution de Shefali pour UIImageView fonctionne très bien, mais elle nécessite une petite modification :

- (void)pinch:(UIPinchGestureRecognizer *)gesture {
    if (gesture.state == UIGestureRecognizerStateEnded
        || gesture.state == UIGestureRecognizerStateChanged) {
        NSLog(@"gesture.scale = %f", gesture.scale);

        CGFloat currentScale = self.frame.size.width / self.bounds.size.width;
        CGFloat newScale = currentScale * gesture.scale;

        if (newScale < MINIMUM_SCALE) {
            newScale = MINIMUM_SCALE;
        }
        if (newScale > MAXIMUM_SCALE) {
            newScale = MAXIMUM_SCALE;
        }

        CGAffineTransform transform = CGAffineTransformMakeScale(newScale, newScale);
        self.transform = transform;
        gesture.scale = 1;
    }
}

(La solution de Shefali avait l'inconvénient de ne pas s'échelonner de façon continue lors du pincement. De plus, lors du démarrage d'un nouveau pincement, l'échelle de l'image actuelle était réinitialisée).

0 votes

Je veux que le geste panoramique soit activé après le geste de pincement, comment faire ?

0 votes

@Gajendra : Dans ce cas, je pense que vous devriez intégrer vos composants dans une vue défilante, qui prend en charge les deux types d'affichage.

0 votes

Mais je veux une fonctionnalité pour les gestes de tapotement et de pincement. J'ai également utilisé une grille (couches) sur Imageview. Puis-je savoir s'il est possible d'utiliser les gestes de pincement et d'effleurement dans la vue défilante ?

23voto

Shefali Soni Points 119

Le code ci-dessous permet de zoomer dans UIImageView sans utiliser UIScrollView :

-(void)HandlePinch:(UIPinchGestureRecognizer*)recognizer{
    if ([recognizer state] == UIGestureRecognizerStateEnded) {
        NSLog(@"======== Scale Applied ===========");
        if ([recognizer scale]<1.0f) {
            [recognizer setScale:1.0f];
        }
        CGAffineTransform transform = CGAffineTransformMakeScale([recognizer scale],  [recognizer scale]);
        imgView.transform = transform;
    }
}

0 votes

C'est la solution suprême :). Merci.

19voto

August Points 9726

Gardez à l'esprit que vous ne zoomez JAMAIS sur un UIImage . JAMAIS.

Au lieu de cela, vous faites un zoom avant et arrière sur le view qui affiche le UIImage .

Dans ce cas particulier, vous pouvez choisir de créer un fichier personnalisé UIView avec un dessin personnalisé pour afficher l'image, un UIImageView qui affiche l'image pour vous, ou un UIWebView qui devra être étayée par du HTML supplémentaire.

Dans tous les cas, vous devrez mettre en œuvre les éléments suivants touchesBegan , touchesMoved et autres pour déterminer ce que l'utilisateur essaie de faire (zoom, panoramique, etc.).

0 votes

+1 pour la clarification, je n'y avais jamais pensé de cette façon, merci mec.

0 votes

@August, pouvez-vous me fournir un exemple de zoom et de rotation de l'image sur les touchesBegan, touchesMoved ?

7voto

Niels Hansen Points 1297

Voici une solution que j'ai déjà utilisée et qui ne nécessite pas l'utilisation de UIWebView.

- (UIImage *)scaleAndRotateImage(UIImage *)image
{
    int kMaxResolution = 320; // Or whatever

    CGImageRef imgRef = image.CGImage;

    CGFloat width = CGImageGetWidth(imgRef);
    CGFloat height = CGImageGetHeight(imgRef);

    CGAffineTransform transform = CGAffineTransformIdentity;
    CGRect bounds = CGRectMake(0, 0, width, height);
    if (width > kMaxResolution || height > kMaxResolution) {
        CGFloat ratio = width/height;
        if (ratio > 1) {
            bounds.size.width = kMaxResolution;
            bounds.size.height = bounds.size.width / ratio;
        }
        else {
            bounds.size.height = kMaxResolution;
            bounds.size.width = bounds.size.height * ratio;
        }
    }

    CGFloat scaleRatio = bounds.size.width / width;
    CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef));
    CGFloat boundHeight;
    UIImageOrientation orient = image.imageOrientation;
    switch(orient) {

        case UIImageOrientationUp: //EXIF = 1
            transform = CGAffineTransformIdentity;
            break;

        case UIImageOrientationUpMirrored: //EXIF = 2
            transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            break;

        case UIImageOrientationDown: //EXIF = 3
            transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;

        case UIImageOrientationDownMirrored: //EXIF = 4
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.height);
            transform = CGAffineTransformScale(transform, 1.0, -1.0);
            break;

        case UIImageOrientationLeftMirrored: //EXIF = 5
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width);
            transform = CGAffineTransformScale(transform, -1.0, 1.0);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationLeft: //EXIF = 6
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(0.0, imageSize.width);
            transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0);
            break;

        case UIImageOrientationRightMirrored: //EXIF = 7
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeScale(-1.0, 1.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        case UIImageOrientationRight: //EXIF = 8
            boundHeight = bounds.size.height;
            bounds.size.height = bounds.size.width;
            bounds.size.width = boundHeight;
            transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0);
            transform = CGAffineTransformRotate(transform, M_PI / 2.0);
            break;

        default:
            [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"];

    }

    UIGraphicsBeginImageContext(bounds.size);

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) {
        CGContextScaleCTM(context, -scaleRatio, scaleRatio);
        CGContextTranslateCTM(context, -height, 0);
    }
    else {
        CGContextScaleCTM(context, scaleRatio, -scaleRatio);
        CGContextTranslateCTM(context, 0, -height);
    }

    CGContextConcatCTM(context, transform);

    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
    UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return imageCopy;
}

L'article peut être trouvé sur le site Apple Support à l'adresse suivante : http://discussions.apple.com/message.jspa?messageID=7276709#7276709

0 votes

-1 pour une page d'assistance hébergée en jsp. secoue le poing à la syntaxe par points

0 votes

Pouvez-vous me dire comment appeler cette méthode (au déplacement de la souris ou au toucher) ?

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