Эффект Pinch To Zoom для UIImageView внутри scrollView?

Я использую раскадровку (iOS 6.0), чтобы создать просмотрщик фотогалерей для своего приложения. Вот как мой imageViewController настроен в раскадровке:

enter image description here

Я обязательно включил userInteraction и несколько касаний как для imageView, так и для scrollView. То, что я хочу сделать, - это то, что я хочу изменить масштаб изображения (максимальный масштаб 3) и иметь возможность передвигаться. Это то, что я имею в настоящее время, хотя, несмотря на то, что жест щепотки обнаружен, масштаб не изменяется.

- (IBAction)imagePinched:(id)sender {

if (pinchRecognizer.state == UIGestureRecognizerStateEnded || pinchRecognizer.state == UIGestureRecognizerStateChanged) {

    NSLog(@"gesture.scale = %f", pinchRecognizer.scale);

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

    if (newScale < 1) {
        newScale = 1;
    }
    if (newScale > 3) {
        newScale = 3;
    }

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

}

В большинстве вопросов и учебников в Интернете речь идет о программном создании представлений и выполнении этого, но чем меньше код, тем лучше (на моих глазах). Какой лучший способ заставить это работать с раскадрой? Спасибо заранее!


ОБНОВЛЕНО:

Вот мой полный код файла .m:

- (void)viewDidLoad
{
    [super viewDidLoad];

    //Assign an image to this controller imageView
    fullScreenView.image = [UIImage imageNamed:imageString];

    //Allows single and double tap to work
    [singleTapRecognizer requireGestureRecognizerToFail: doubleTapRecognizer];
}

- (IBAction)imageTapped:(id)sender {

    NSLog(@"Image Tapped.");

    //On tap, fade out viewController like the twitter.app
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (IBAction)imageDoubleTapped:(id)sender {

    NSLog(@"Image Double Tapped.");

    //On double tap zoom into imageView to fill in the screen.
    [fullScreenView setContentMode:UIViewContentModeScaleAspectFill];
}

- (IBAction)imagePinched:(id)sender {

    if (pinchRecognizer.state == UIGestureRecognizerStateEnded || pinchRecognizer.state == UIGestureRecognizerStateChanged) {

        NSLog(@"gesture.scale = %f", pinchRecognizer.scale);

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

        if (newScale < 1) {
            newScale = 1;
        }
        if (newScale > 3) {
            newScale = 3;
        }

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

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return self.fullScreenView;
}


-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Ответы

Ответ 1

Я думаю, что лучшее решение в документации Apple

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView

{

    return self.imageView;

}
- (void)viewDidLoad {

    [super viewDidLoad];

    self.scrollView.minimumZoomScale=0.5;

    self.scrollView.maximumZoomScale=6.0;

    self.scrollView.contentSize=CGSizeMake(1280, 960);

    self.scrollView.delegate=self;

}

Проверить документацию Apple

Ответ 2

Первый шаг - убедиться, что ваши представления имеют правильные делегаты. Например, в .m файле

@interface myRootViewController () <.., UIGestureRecognizerDelegate, UIScrollViewDelegate, ...>

Из документации убедитесь, что это реализовано:

Класс UIScrollView может иметь делегат, который должен принять протокол UIScrollViewDelegate. Для масштабирования и панорамирования для работы делегат должен реализовать как viewForZoomingInScrollView:, так и scrollViewDidEndZooming: withView: atScale:; кроме того, максимальная (максимальная шкала ZoomScale) и минимальная шкала (minimumZoomScale) должны быть разными.

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
  return self.fullScreenView;
}


-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{}

Теперь метод scrollViewDidEndZooming может оставаться пустым. Если вы уже это сделали или все еще не работаете, отправьте больше своего кода, а затем более легко помочь более конкретно.

Ответ 3

Вам нужно сделать то, что предложил Вади, но также установил, что setMinimumZoomScale отличается от setMaximumZoomScale. По умолчанию они равны 1.0f.

После этого UIImageView должен быть закреплен

Ответ 4

Вот как Apple рекомендует делать то, что вы хотите сделать. Я использовал код, предоставленный Apple, и он работал как шарм! Если вы хотите оптимизировать управление памятью, вы можете использовать iCarousel (сделанные nicklockwood), которые имеют управление кешем для неиспользуемых просмотров dealloc!

Ответ 5

Я создал полностью действующее демо-приложение (подобное по своей природе в фотогалерее по умолчанию в Facebook), которое демонстрирует щепотку, чтобы увеличить изображение Image View, вложенное в прокрутку с помощью AutoLayout и раскадровки. Просмотрите мой проект здесь: http://rexstjohn.com/facebook-like-ios-photo-modal-gallery-swipe-gestures/.

Он также включает в себя асинхронную загрузку фотографий через MKNetworkKit и запись на основе жестов через фотогалерею. Наслаждайтесь, и я надеюсь, что это спасет все время, пытаясь понять это, потому что это несколько раздражает.

Ответ 6

Я создал класс для обработки масштабирования UIImageViews, аналогичного Instagram. Мог бы быть тем, что вы ищете, иначе вы можете посмотреть, как я его достиг. https://github.com/twomedia/TMImageZoom