Эффект Pinch To Zoom на UIImageView внутри scrollView?
Я использую раскадровку (iOS 6.0) для создания программы просмотра фотогалереи для своего приложения. Вот как мой imageViewController настроен в раскадровке:
Я позаботился о том, чтобы включить userInteraction и несколько касаний как в imageView, так и в scrollView. То, что я хочу сделать, это, в крайнем случае, я хочу увеличить в imageView (максимальный масштаб 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's 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
6 ответов
Я думаю, что лучшее решение в документации 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;
}
Первый шаг - убедиться, что в ваших представлениях реализованы правильные делегаты. Например, в файле.m
@interface myRootViewController () <.., UIGestureRecognizerDelegate, UIScrollViewDelegate, ...>
Из документации убедитесь, что это реализовано:
Класс UIScrollView может иметь делегата, который должен принимать протокол UIScrollViewDelegate. Чтобы масштабирование и панорамирование работали, делегат должен реализовать и viewForZoomingInScrollView: и scrollViewDidEndZooming: withView: atScale:; Кроме того, максимальный (максимум ZoomScale) и минимальный (минимум ZoomScale) масштаб масштабирования должны отличаться.
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.fullScreenView;
}
-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{}
Метод scrollViewDidEndZooming может пока оставаться пустым. Если вы уже сделали это или все еще не работаете, пожалуйста, опубликуйте больше своего кода, и тогда вам будет легче помочь более конкретно.
Вам нужно сделать то, что предложил Вади выше, но также установить setMinimumZoomScale отличным от setMaximumZoomScale. Они оба 1.0f по умолчанию.
После этого UIImageView
должно быть сжимаемым
Я создал полностью работающее демонстрационное приложение (похожее по своей природе на стандартную фотогалерею Facebook), которое демонстрирует масштабирование для просмотра изображений с масштабированием в виде прокрутки с помощью AutoLayout и раскадровок. Посмотреть мой проект здесь: http://rexstjohn.com/facebook-like-ios-photo-modal-gallery-swipe-gestures/.
Он также включает в себя асинхронную загрузку фотографий через MKNetworkKit и жесты на основе пролистывания через фотогалерею. Наслаждайтесь, и я надеюсь, что это сэкономит каждому время, пытаясь понять это, потому что это несколько раздражает.
Я создал класс для обработки масштабирования UIImageViews аналогично Instagram. Возможно, это то, что вы ищете, иначе вы можете посмотреть, как я этого добился. https://github.com/twomedia/TMImageZoom
Вот как Apple рекомендует делать то, что вы хотите. Я использовал код, предоставленный Apple, и он работал как шарм! Если вы хотите оптимизировать управление памятью, вы можете использовать iCarousel (сделанный nicklockwood), который имеет управление кешем для освобождения неиспользуемых представлений!