Как увеличить / уменьшить объект UIImage, когда пользователь зажимает экран?
Я хотел бы увеличить / уменьшить масштаб объекта UIImage, когда пользователь выполняет стандартное действие Пинча в моем приложении. В настоящее время я использую UIImageView для отображения моего изображения, если эта деталь помогает в любом случае.
Я пытаюсь понять, как это сделать, но пока не повезло.
какие-то зацепки?
9 ответов:
еще один простой способ сделать это, чтобы разместить свой
UIImageView
внутриUIScrollView
. как я описываю здесь, вам нужно установить contentSize представления прокрутки, чтобы быть таким же, как вашUIImageView's
размер. Установите экземпляр контроллера в качестве делегата представления прокрутки и реализуйтеviewForZoomingInScrollView:
иscrollViewDidEndZooming:withView:atScale:
методы для обеспечения Пинч-масштабирования и панорамирования изображений. Это эффективно то, что делает решение Бена, только немного более легким способом, так как у вас нет накладных расходов полного веб-представление.одна из проблем, с которой вы можете столкнуться, заключается в том, что масштабирование в режиме прокрутки происходит в виде преобразований, применяемых к изображению. Это может привести к размытости при высоких коэффициентах масштабирования. Для чего-то, что можно перерисовать, вы можете следовать моим предложениям здесь для обеспечения более четкого отображения после завершения жеста щепотки. решение hniels может быть использовано в этот момент для масштабирования вашего изображения.
как описывали другие, самое простое решение-поместить ваш UIImageView в UIScrollView. Я сделал это в интерфейсном конструкторе .файл xib.
в viewDidLoad установите следующие переменные. Установите контроллер в качестве 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; }
вы должны реализовать следующий метод, чтобы вернуть изображение, которое вы хотите увеличить.
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { return self.imageView; }
в версиях, предшествующих iOS9, вам также может потребоваться добавить этот пустой делегат метод:
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale { }
The Документация Apple хорошо описывает, как это сделать:
решение Шефали для UIImageView отлично работает, но оно нуждается в небольшой модификации:
- (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; } }
(У решения Шефали был недостаток, что он не масштабировался непрерывно при защемлении. Кроме того, при запуске нового Пинча, текущий масштаб изображения был сброшен.)
ниже код помогает увеличить UIImageView без использования 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; } }
имейте в виду, что вы никогда не увеличиваете масштаб
UIImage
. КОГДА-ЛИБО.вместо этого вы увеличиваете и уменьшаете масштаб
view
Это показываетUIImage
.в данном конкретном случае, вы должны выбрать, чтобы создать пользовательский
UIView
с пользовательским рисунком для отображения изображения, aUIImageView
который отображает изображение для вас, илиUIWebView
который будет нуждаться в некоторых дополнительных HTML для резервного копирования.во всех случаях вам нужно будет реализовать
touchesBegan
,touchesMoved
, а как чтобы определить, что пользователь пытается сделать (масштабирование, панорамирование и т. д.).
вот решение, которое я использовал раньше, что не требует от вас использовать 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; }
статью можно найти в Службе поддержки Apple по адресу: http://discussions.apple.com/message.jspa?messageID=7276709#7276709
ответы Шафали и JRV расширились, чтобы включить панорамирование и щепотку для увеличения:
#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; } }
самый простой способ сделать это, если все, что вы хотите, это увеличить масштабирование, это поместить изображение внутри
UIWebView
(напишите небольшое количество кода html-оболочки, ссылайтесь на свое изображение, и вы в основном закончите). Более сложный способ сделать это-использоватьtouchesBegan
,touchesMoved
иtouchesEnded
чтобы отслеживать пальцы пользователя и соответствующим образом настраивать свойство преобразования вашего представления.
имейте в виду, что вы не хотите увеличивать/уменьшать UIImage. Вместо этого попробуйте увеличить/уменьшить вид, который содержит контроллер вида UIImage.
Я сделал решение этой проблемы. Взгляните на мой код:
@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() }
N. B.: Не забудьте подключить PinchGestureRecognizer.