Un autre moyen simple de le faire est de placer votre UIImageView
fichier dans un fichier UIScrollView
. Comme je le décris ici , vous devez définir le contentSize de la vue de défilement pour qu'il soit identique à votre UIImageView's
taille. Définissez votre instance de contrôleur comme délégué de la vue de défilement et implémentez les méthodes viewForZoomingInScrollView:
et 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 de manière légèrement plus légère, car vous n'avez pas la surcharge d'une vue Web complète.
Un problème que vous pouvez rencontrer est que la mise à l'échelle dans la vue de défilement se présente sous la forme de transformations appliquées à l'image. Cela peut entraîner un flou à des facteurs de zoom élevés. Pour quelque chose qui peut être redessiné, vous pouvez suivre mes suggestions ici pour fournir un affichage plus net une fois le geste de pincement terminé. La solution de hniels pourrait être utilisée à ce stade pour redimensionner votre image.
Comme d'autres l'ont décrit, la solution la plus simple consiste à placer votre UIImageView dans un UIScrollView. Je l'ai fait dans le fichier .xib d'Interface Builder.
Dans viewDidLoad, définissez les variables suivantes. Définissez votre contrôleur comme UIScrollViewDelegate.
- (void)viewDidLoad { [super viewDidLoad]; self.scrollView.minimumZoomScale = 0.5; self.scrollView.maximumZoomScale = 6.0; self.scrollView.contentSize = self.imageView.frame.size; self.scrollView.delegate = self; }
Vous devez implémenter la méthode suivante pour renvoyer l'imageView que vous souhaitez agrandir.
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { return self.imageView; }
Dans les versions antérieures à iOS9, vous devrez peut-être également ajouter cette méthode de délégué vide:
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale { }
La documentation Apple décrit bien comment procéder:
la source
scrollViewDidEndZooming :
méthode de mise en œuvre .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 être mise à l'échelle en continu pendant le pincement. De plus, lors du démarrage d'un nouveau pincement, l'échelle d'image actuelle était réinitialisée.)
la source
Le code ci-dessous permet de zoomer 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; } }
la source
Gardez à l'esprit que vous ne zoomez JAMAIS sur un fichier
UIImage
. DÉJÀ.Au lieu de cela, vous effectuez un zoom avant et arrière sur le
view
qui affiche leUIImage
.Dans ce cas particulier, vous devez choisir de créer un
UIView
dessin personnalisé avec un dessin personnalisé pour afficher l'image, unUIImageView
qui affiche l'image pour vous, ou unUIWebView
qui aura besoin de HTML supplémentaire pour le sauvegarder.Dans tous les cas, vous devrez implémenter
touchesBegan
,touchesMoved
etc. pour déterminer ce que l'utilisateur essaie de faire (zoom, panoramique, etc.).la source
Voici une solution que j'ai déjà utilisée et qui ne vous oblige pas à utiliser 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; }
Cet article est disponible sur l'assistance Apple à l' adresse : http://discussions.apple.com/message.jspa?messageID=7276709#7276709
la source
Les réponses de Shafali et JRV ont été étendues pour inclure le panoramique et le pincement pour zoomer:
#define MINIMUM_SCALE 0.5 #define MAXIMUM_SCALE 6.0 @property CGPoint translation; - (void)pan:(UIPanGestureRecognizer *)gesture { static CGPoint currentTranslation; static CGFloat currentScale = 0; if (gesture.state == UIGestureRecognizerStateBegan) { currentTranslation = _translation; currentScale = self.view.frame.size.width / self.view.bounds.size.width; } if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged) { CGPoint translation = [gesture translationInView:self.view]; _translation.x = translation.x + currentTranslation.x; _translation.y = translation.y + currentTranslation.y; CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x , _translation.y); CGAffineTransform transform2 = CGAffineTransformMakeScale(currentScale, currentScale); CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2); self.view.transform = transform; } } - (void)pinch:(UIPinchGestureRecognizer *)gesture { if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged) { // NSLog(@"gesture.scale = %f", gesture.scale); CGFloat currentScale = self.view.frame.size.width / self.view.bounds.size.width; CGFloat newScale = currentScale * gesture.scale; if (newScale < MINIMUM_SCALE) { newScale = MINIMUM_SCALE; } if (newScale > MAXIMUM_SCALE) { newScale = MAXIMUM_SCALE; } CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x, _translation.y); CGAffineTransform transform2 = CGAffineTransformMakeScale(newScale, newScale); CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2); self.view.transform = transform; gesture.scale = 1; } }
la source
Le moyen le plus simple de le faire, si tout ce que vous voulez est un zoom par pincement, est de placer votre image dans un
UIWebView
(écrivez une petite quantité de code html, référencez votre image et vous avez pratiquement terminé). Plus complcated façon de le faire est d'utilisertouchesBegan
,touchesMoved
ettouchesEnded
de garder une trace des doigts de l'utilisateur, et d' ajuster votre vue de transformer la propriété appropriée.la source
Gardez à l'esprit que vous ne souhaitez pas effectuer un zoom avant / arrière sur UIImage. Essayez plutôt de zoomer / dézoomer la vue qui contient le contrôleur de vue UIImage.
J'ai fait une solution à ce problème. Jetez un œil à mon code:
@IBAction func scaleImage(sender: UIPinchGestureRecognizer) { self.view.transform = CGAffineTransformScale(self.view.transform, sender.scale, sender.scale) sender.scale = 1 } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. view.backgroundColor = UIColor.blackColor() }
NB: N'oubliez pas de brancher le PinchGestureRecognizer.
la source