Innym prostym sposobem na to jest umieszczenie UIImageView
pliku wewnątrz UIScrollView
. Jak tutaj opisuję , musisz ustawić contentSize widoku przewijania tak, aby był taki sam jak twój UIImageView's
rozmiar. Ustaw instancję kontrolera jako delegata widoku przewijania i zaimplementuj metody viewForZoomingInScrollView:
i scrollViewDidEndZooming:withView:atScale:
, aby umożliwić powiększanie przez szczypanie i przesuwanie obrazu. To właśnie robi rozwiązanie Bena, tylko w nieco lżejszy sposób, ponieważ nie masz narzutu pełnego widoku internetowego.
Jednym z problemów, które możesz napotkać, jest to, że skalowanie w widoku przewijania ma postać przekształceń zastosowanych do obrazu. Może to prowadzić do rozmycia przy dużych współczynnikach powiększenia. Aby uzyskać coś, co można przerysować, możesz postępować zgodnie z moimi sugestiami , aby zapewnić wyraźniejszy obraz po zakończeniu gestu szczypania. Rozwiązanie hniels może zostać użyte w tym momencie do przeskalowania obrazu.
Jak opisali inni, najłatwiejszym rozwiązaniem jest umieszczenie UIImageView w UIScrollView. Zrobiłem to w pliku .xib Interface Builder.
W viewDidLoad ustaw następujące zmienne. Ustaw swój kontroler jako 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; }
Aby zwrócić obraz, który chcesz powiększyć, musisz zaimplementować następującą metodę.
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { return self.imageView; }
W wersjach starszych niż iOS9 może być również konieczne dodanie tej pustej metody delegata:
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale { }
Dokumentacja Jabłko robi dobrą robotę opisując jak to zrobić:
źródło
scrollViewDidEndZooming :
metody implementacji .Rozwiązanie Shefali dla UIImageView działa świetnie, ale wymaga niewielkiej modyfikacji:
- (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; } }
(Wadą rozwiązania Shefali było to, że nie skalowało się w sposób ciągły podczas szczypania. Ponadto podczas rozpoczynania nowego szczypania bieżąca skala obrazu została zresetowana.)
źródło
Poniższy kod pomaga powiększyć UIImageView bez użycia 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; } }
źródło
Pamiętaj, że NIGDY nie powiększasz pliku
UIImage
. ZAWSZE.Zamiast tego powiększasz i pomniejszasz widok,
view
który wyświetla plikUIImage
.W tym konkretnym przypadku możesz zdecydować się na utworzenie
UIView
niestandardowego rysunku z niestandardowym rysunkiem do wyświetlania obrazu,UIImageView
który wyświetla obraz za Ciebie lubUIWebView
będzie wymagał dodatkowego kodu HTML, aby go wykonać.We wszystkich przypadkach trzeba wdrożyć
touchesBegan
,touchesMoved
i tym podobne, aby określić co użytkownik próbuje zrobić (zoom, pan, itp).źródło
Oto rozwiązanie, którego użyłem wcześniej, które nie wymaga korzystania z 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; }
Artykuł można znaleźć na stronie wsparcia Apple pod adresem : http://discussions.apple.com/message.jspa?messageID=7276709#7276709
źródło
Odpowiedzi Shafali i JRV rozszerzyły się o przesuwanie i szczypanie, aby powiększyć:
#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; } }
źródło
Najprostszym sposobem, aby to zrobić, jeśli chcesz tylko powiększać szczypanie, jest umieszczenie obrazu wewnątrz
UIWebView
(napisz niewielką ilość kodu otoki html, odwołaj się do obrazu i w zasadzie gotowe). Im więcej complcated sposobem, aby to zrobić jest użycietouchesBegan
,touchesMoved
oraztouchesEnded
śledzić palców użytkownika i dostosowanie widoku na przekształcać własność odpowiednio.źródło
Pamiętaj, że nie chcesz powiększać / pomniejszać UIImage. Zamiast tego spróbuj powiększyć / pomniejszyć widok, który zawiera kontroler widoku UIImage.
Zrobiłem rozwiązanie tego problemu. Spójrz na mój kod:
@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() }
Uwaga: nie zapomnij podłączyć PinchGestureRecognizer.
źródło