2009-02-01 1 views
71

Я хотел бы увеличить/уменьшить объект UIImage, когда пользователь выполнит стандартное действие пинча в моем приложении. В настоящее время я использую UIImageView для отображения моего изображения, если эта деталь помогает в любом случае.Как увеличить/уменьшить объект UIImage, когда пользователь зажимает экран?

Я пытаюсь выяснить, как это сделать, но пока такого не повезло.

Любые подсказки?

ответ

77

Другой простой способ сделать это, чтобы разместить ваш UIImageView в пределах UIScrollView. As I describe here, вам необходимо установить размер содержимого контента прокрутки таким же, как размер вашего UIImageView's. Установите экземпляр вашего контроллера как делегат прокрутки и выполните методы viewForZoomingInScrollView: и scrollViewDidEndZooming:withView:atScale:, чтобы обеспечить масштабирование и панорамирование изображений. Это эффективно то, что делает решение Бена, только немного более легким способом, поскольку у вас нет накладных расходов на полный веб-просмотр.

Одна проблема, с которой вы можете столкнуться, заключается в том, что масштабирование в представлении прокрутки происходит в виде преобразований, применяемых к изображению. Это может привести к размытости при высоких коэффициентах масштабирования. Для чего-то, что можно перерисовать, вы можете следовать моим предложениям here, чтобы обеспечить четкий дисплей после того, как жест щепотки закончен. В этот момент можно было бы использовать решение hniels для масштабирования изображения.

+2

Убедитесь, что вы изменили максимальное значение ZoomScale и/или minimumZoomScale :). –

2

Простейший способ сделать это, если все, что вам нужно, - увеличить масштаб изображения, - разместить свое изображение внутри UIWebView (напишите небольшое количество кода оболочки html, укажите свое изображение, и в основном вы делаете). Более сложный способ сделать это - использовать touchesBegan, touchesMoved и touchesEnded, чтобы отслеживать пальцы пользователя и соответствующим образом изменять свойство преобразования вашего представления.

+0

может предложить вам любой пример, связанный с вашим ответом. Как я могу масштабировать и поворачивать изображение с помощью touchhesBegan, касается методовMoved. Мой вопрос link => http://stackoverflow.com/questions/36833841/how-to-handle-multiple-touch-gesture-at-a-time?noredirect1_comment61239098_36833841 –

18

Имейте в виду, что вы НИКОГДА не увеличиваете масштаб на UIImage. КОГДА-ЛИБО.

Вместо этого вы увеличиваете и уменьшаете масштаб на view, который отображает UIImage.

В данном конкретном случае, вы chould решили создать собственный UIView с пользовательской графики для отображения изображения, а UIImageView, который отображает изображение для вас, или UIWebView который потребуется некоторый дополнительный HTML, чтобы поддержать его.

Во всех случаях вам необходимо реализовать touchesBegan, touchesMoved и т.п., чтобы определить, что пользователь пытается сделать (масштабирование, панорамирование и т. Д.).

+0

+1 для разъяснения, никогда не думал об этом так, привет, чувак – Elmo

+0

@ Август, может ли я предоставить мне какой-нибудь пример, который масштабирует и поворачивает изображение на прикосновенияхBegan, touchhesMoved? –

8

Вот решение, которое я использовал до этого, не требует использования 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

+0

-1 для страницы поддержки, поддерживаемой jsp. * встряхивает кулак в точечном синтаксисе * – esharp

+0

Можете ли, пожалуйста, предоставьте мне, как назвать этот метод (при перемещении мыши или касании)? –

22

Ниже кода помогает увеличить 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; 
    } 
} 
+0

Это высшее решение :). Спасибо. – sabiland

48

решение Shefali для 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; 
    } 
} 

(решение Shefali имело обратную сторону, что это непрерывно не увеличивалось при защемлении.Кроме того, при запуске нового пинча текущая шкала изображений была сброшена.)

+0

Я хочу, чтобы режим жесты был включен после того, как начался жест щепотки. Как это сделать? –

+0

@Gajendra: В этом случае, я думаю, вы должны использовать встроенные компоненты в виде прокрутки, который поддерживает оба из коробки. – JRV

+0

Но я хочу функциональность для жестов и жест нажатия. Я также использую сетку (слои) в Imageview. Могу ли я узнать, возможно ли использовать жест щепотки и жест нажатия, в виде прокрутки.? –

75

Как описано выше, самым простым решением является включение UIImageView в UIScrollView. Я сделал это в файле Interface Builder .xib.

В представленииDidLoad задайте следующие переменные. Установите ваш контроллер как 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 
{ 
} 

Apple Documentation делает хорошую работу описания того, как сделать это:

+2

Это нормально, чтобы удалить scrollViewDidEndZooming: withView: теперь, я тестировал с iOS9 Xcode7 – ElonChan

+0

Это работает для меня! Без применения метода scrollViewDidEndZooming:. –

4

Shafali и Ответы 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; 
    } 
} 
+0

, пожалуйста, избегайте упоминания другого ответа, поскольку они могут удалить их ответ в любое время. – manetsus

+0

спасибо, что он работал как шарм – aznelite89

0

Keep в виду, что вы не хотите увеличивать/уменьшать 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.

Смежные вопросы