Центральное содержимое UIScrollView при меньшем
У меня есть UIImageView
внутри UIScrollView
который я использую для масштабирования и прокрутки. Если изображение / содержимое прокрутки больше, чем просмотр прокрутки, все работает нормально. Однако, когда изображение становится меньше, чем вид прокрутки, он прикрепляется к верхнему левому углу прокрутки. Я хотел бы сосредоточить его, как приложение «Фотографии».
Любые идеи или примеры сохранения содержимого UIScrollView
центре, когда он меньше?
Я работаю с iPhone 3.0.
- Ошибка UICollectionView Assertion
- Msgstr "wait_fences: не удалось получить ответ: 10004003"?
- Как программно предотвратить переключение Mac на hibernate?
- Как установить плагин Xcode для автоматического форматирования кода
- UIScrollView не прокручивается после обновления до iOS7 / xcode 5
Следующий код почти работает. Изображение будет возвращено в верхний левый угол, если я уберу его после достижения минимального уровня масштабирования.
- (void)loadView { [super loadView]; // set up main scroll view imageScrollView = [[UIScrollView alloc] initWithFrame:[[self view] bounds]]; [imageScrollView setBackgroundColor:[UIColor blackColor]]; [imageScrollView setDelegate:self]; [imageScrollView setBouncesZoom:YES]; [[self view] addSubview:imageScrollView]; UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"WeCanDoIt.png"]]; [imageView setTag:ZOOM_VIEW_TAG]; [imageScrollView setContentSize:[imageView frame].size]; [imageScrollView addSubview:imageView]; CGSize imageSize = imageView.image.size; [imageView release]; CGSize maxSize = imageScrollView.frame.size; CGFloat widthRatio = maxSize.width / imageSize.width; CGFloat heightRatio = maxSize.height / imageSize.height; CGFloat initialZoom = (widthRatio > heightRatio) ? heightRatio : widthRatio; [imageScrollView setMinimumZoomScale:initialZoom]; [imageScrollView setZoomScale:1]; float topInset = (maxSize.height - imageSize.height) / 2.0; float sideInset = (maxSize.width - imageSize.width) / 2.0; if (topInset < 0.0) topInset = 0.0; if (sideInset < 0.0) sideInset = 0.0; [imageScrollView setContentInset:UIEdgeInsetsMake(topInset, sideInset, -topInset, -sideInset)]; } - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { return [imageScrollView viewWithTag:ZOOM_VIEW_TAG]; } /************************************** NOTE **************************************/ /* The following delegate method works around a known bug in zoomToRect:animated: */ /* In the next release after 3.0 this workaround will no longer be necessary */ /**********************************************************************************/ - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale { [scrollView setZoomScale:scale+0.01 animated:NO]; [scrollView setZoomScale:scale animated:NO]; // END Bug workaround CGSize maxSize = imageScrollView.frame.size; CGSize viewSize = view.frame.size; float topInset = (maxSize.height - viewSize.height) / 2.0; float sideInset = (maxSize.width - viewSize.width) / 2.0; if (topInset < 0.0) topInset = 0.0; if (sideInset < 0.0) sideInset = 0.0; [imageScrollView setContentInset:UIEdgeInsetsMake(topInset, sideInset, -topInset, -sideInset)]; }
- Можно ли перепроектировать мое приложение iPhone?
- захват себя в этом блоке, вероятно, приведет к циклу сохранения
- Как правильно представить popover из UITableViewCell с помощью UIPopoverArrowDirectionRight или UIPopoverArrowDirectionLeft
- Как изменить определенный цвет в изображении?
- Скрытые особенности Xcode
- Ошибка: протокол недоступен, сброс backtrace
- COMET (серверный клик для клиента) на iPhone
- Как resize изображения программно в объективе-c в iphone
У меня очень простое решение! Все, что вам нужно, – это обновить центр вашего подвью (просмотр изображения) при масштабировании ScrollViewDelegate. Если увеличенное изображение меньше прокрутки, настройте subview.center else center (0,0).
- (void)scrollViewDidZoom:(UIScrollView *)scrollView { UIView *subView = [scrollView.subviews objectAtIndex:0]; CGFloat offsetX = MAX((scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5, 0.0); CGFloat offsetY = MAX((scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5, 0.0); subView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX, scrollView.contentSize.height * 0.5 + offsetY); }
@ Ответ EvelynCordner был тем, который работал лучше всего в моем приложении. Код намного меньше, чем другие.
Вот версия Swift, если кому-то это нужно:
func scrollViewDidZoom(_ scrollView: UIScrollView) { let offsetX = max((scrollView.bounds.width - scrollView.contentSize.width) * 0.5, 0) let offsetY = max((scrollView.bounds.height - scrollView.contentSize.height) * 0.5, 0) scrollView.contentInset = UIEdgeInsetsMake(offsetY, offsetX, 0, 0) }
Хорошо, я боролся с этим в течение последних двух дней, и, наконец, пришел к довольно надежному (до сих пор …) решению. Я думал, что должен поделиться им и сохранить другие боли. 🙂 Если вы найдете проблему с этим решением, пожалуйста, кричите!
Я в основном пережил то, что у всех остальных: поиск в StackOverflow, форумах разработчиков Apple, рассмотрел код для трех20, ScrollingMadness, ScrollTestSuite и т. Д. Я попытался расширить рамку UIImageView, играя с смещением и / или вставками UIScrollView из ViewController и т. д., но ничего не работало отлично (как выяснили все остальные).
После сна, я попробовал пару альтернативных ракурсов:
- Подclassификация UIImageView, поэтому она изменяет свой собственный размер динамически – это совсем не сработало.
- Подclassифицируйте UIScrollView, чтобы он динамически менял свой собственный контентОфис, – это тот, который кажется мне победителем.
С помощью этого подclassа метода UIScrollView я переопределяю мутатор contentOffset, поэтому он не устанавливает {0,0}, когда изображение масштабируется меньше, чем область просмотра, вместо этого оно устанавливает смещение таким образом, чтобы изображение сохранялось в центре просмотра в окне просмотра. Пока это работает. Я проверил его с широкими, высокими, крошечными и крупными изображениями, и у него нет «работы, но прижимаются при минимальном масштабировании».
Я загрузил пример проекта в github, который использует это решение, вы можете найти его здесь: http://github.com/nyoron/NYOBetterZoom
Этот код должен работать в большинстве версий iOS (и был протестирован для работы над 3.1 вверх).
Он основан на коде Apple WWDC для фотоальбома.
Добавьте ниже в свой подclass UIScrollView и замените tileContainerView на представление, содержащее ваше изображение или fragmentы:
- (void)layoutSubviews { [super layoutSubviews]; // center the image as it becomes smaller than the size of the screen CGSize boundsSize = self.bounds.size; CGRect frameToCenter = tileContainerView.frame; // center horizontally if (frameToCenter.size.width < boundsSize.width) frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2; else frameToCenter.origin.x = 0; // center vertically if (frameToCenter.size.height < boundsSize.height) frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2; else frameToCenter.origin.y = 0; tileContainerView.frame = frameToCenter; }
В настоящее время я подclassифицирую UIScrollView
и переопределяя setContentOffset:
для настройки смещения на основе contentSize
. Он работает как с щепоткой, так и с программным масштабированием.
@implementation HPCenteringScrollView - (void)setContentOffset:(CGPoint)contentOffset { const CGSize contentSize = self.contentSize; const CGSize scrollViewSize = self.bounds.size; if (contentSize.width < scrollViewSize.width) { contentOffset.x = -(scrollViewSize.width - contentSize.width) / 2.0; } if (contentSize.height < scrollViewSize.height) { contentOffset.y = -(scrollViewSize.height - contentSize.height) / 2.0; } [super setContentOffset:contentOffset]; } @end
Помимо короткого и сладкого, этот код обеспечивает гораздо более плавное масштабирование, чем решение @Erdemus. Вы можете увидеть его в действии в демонстрации RMGallery .
Для решения, более подходящего для просмотра прокрутки, использующего автозапуск, используйте вставки содержимого прокрутки, а не обновлять кадры подсмотра вашего прокрутки.
- (void)scrollViewDidZoom:(UIScrollView *)scrollView { CGFloat offsetX = MAX((scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5, 0.0); CGFloat offsetY = MAX((scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5, 0.0); self.scrollView.contentInset = UIEdgeInsetsMake(offsetY, offsetX, 0.f, 0.f); }
Я провел день, борясь с этой проблемой, и закончил реализацию scrollViewDidEndZooming: withView: atScale: следующим образом:
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale { CGFloat screenWidth = [[UIScreen mainScreen] bounds].size.width; CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height; CGFloat viewWidth = view.frame.size.width; CGFloat viewHeight = view.frame.size.height; CGFloat x = 0; CGFloat y = 0; if(viewWidth < screenWidth) { x = screenWidth / 2; } if(viewHeight < screenHeight) { y = screenHeight / 2 ; } self.scrollView.contentInset = UIEdgeInsetsMake(y, x, y, x); }
Это гарантирует, что, когда изображение меньше экрана, все равно достаточно места вокруг него, чтобы вы могли расположить его в нужное место.
(предполагая, что ваш UIScrollView содержит UIImageView для хранения изображения)
По сути, это означает, что ширина или высота вашего изображения меньше, чем ширина / высота экрана, и если да, создайте вставку с половиной ширины / высоты экрана (возможно, вы можете сделать это больше, если хотите, чтобы изображение выйти из экрана).
Обратите внимание, что поскольку это метод UIScrollViewDelegate , не забудьте добавить его в объявление controllerа вашего вида, чтобы избежать возникновения проблемы с сборкой.
Apple выпустила видеоролики сессии WWDC 2010 года всем участникам программы разработки iphone. Одна из обсуждаемых тем – как они создали приложение для фотографий !!! Они создают очень похожее приложение шаг за шагом и сделали весь код доступным бесплатно.
Он также не использует private api. Я не могу указать какой-либо код здесь из-за соглашения о неразглашении, но вот ссылка на загрузку кода примера. Вам, вероятно, потребуется войти в систему, чтобы получить доступ.
И вот ссылка на страницу iTDC iTunes:
Хорошо, это решение работает для меня. У меня есть подclass UIScrollView
со ссылкой на отображаемый UIImageView
. Всякий раз, когда масштабируется UIScrollView
, изменяется свойство contentSize. В UIImageView
я масштабирую UIImageView
соответствующим образом, а также настраиваю его центральное положение.
-(void) setContentSize:(CGSize) size{ CGSize lSelfSize = self.frame.size; CGPoint mid; if(self.zoomScale >= self.minimumZoomScale){ CGSize lImageSize = cachedImageView.initialSize; float newHeight = lImageSize.height * self.zoomScale; if (newHeight < lSelfSize.height ) { newHeight = lSelfSize.height; } size.height = newHeight; float newWidth = lImageSize.width * self.zoomScale; if (newWidth < lSelfSize.width ) { newWidth = lSelfSize.width; } size.width = newWidth; mid = CGPointMake(size.width/2, size.height/2); } else { mid = CGPointMake(lSelfSize.width/2, lSelfSize.height/2); } cachedImageView.center = mid; [super setContentSize:size]; [self printLocations]; NSLog(@"zoom %f setting size %fx %f",self.zoomScale,size.width,size.height); }
Evertime Я установил изображение в UIScrollView
I, изменив его размер. UIScrollView
в scrollview также является настраиваемым classом, который я создал.
-(void) resetSize{ if (!scrollView){//scroll view is view containing imageview return; } CGSize lSize = scrollView.frame.size; CGSize lSelfSize = self.image.size; float lWidth = lSize.width/lSelfSize.width; float lHeight = lSize.height/lSelfSize.height; // choose minimum scale so image width fits screen float factor = (lWidth
С помощью этих двух методов я могу иметь представление, которое ведет себя так же, как приложение для фотографий.
Вы можете посмотреть свойство contentSize
UIScrollView (используя наблюдение за contentInset
или подобное) и автоматически настроить contentInset
всякий раз, когда изменяется размер contentSize
который меньше размера прокрутки.
Это элегантный способ UISCrollView
на содержимом UISCrollView
.
Добавьте одного наблюдателя в contentSize вашего UIScrollView
, поэтому этот метод будет вызываться каждый раз при изменении контента …
[myScrollView addObserver:delegate forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];
Теперь по вашему методу наблюдателя:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { // Correct Object Class. UIScrollView *pointer = object; // Calculate Center. CGFloat topCorrect = ([pointer bounds].size.height - [pointer viewWithTag:100].bounds.size.height * [pointer zoomScale]) / 2.0 ; topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect ); topCorrect = topCorrect - ( pointer.frame.origin.y - imageGallery.frame.origin.y ); // Apply Correct Center. pointer.center = CGPointMake(pointer.center.x, pointer.center.y + topCorrect ); }
-
Вы должны изменить
[pointer viewWithTag:100]
. Замените свой контентный просмотрUIView
.- Также измените
imageGallery
указывая на размер вашего windows.
- Также измените
Это будет корректировать центр контента каждый раз при изменении его размера.
ПРИМЕЧАНИЕ . Единственный способ, которым этот контент не очень хорошо работает, - это стандартная функция масштабирования UIScrollView
.
Это мое решение этой проблемы, которая отлично подходит для любого вида внутри scrollview.
-(void)scrollViewDidZoom:(__unused UIScrollView *)scrollView { CGFloat top; CGFloat left; CGFloat bottom; CGFloat right; if (_scrollView.contentSize.width < scrollView.bounds.size.width) { DDLogInfo(@"contentSize %@",NSStringFromCGSize(_scrollView.contentSize)); CGFloat width = (_scrollView.bounds.size.width-_scrollView.contentSize.width)/2.0; left = width; right = width; }else { left = kInset; right = kInset; } if (_scrollView.contentSize.height < scrollView.bounds.size.height) { CGFloat height = (_scrollView.bounds.size.height-_scrollView.contentSize.height)/2.0; top = height; bottom = height; }else { top = kInset; right = kInset; } _scrollView.contentInset = UIEdgeInsetsMake(top, left, bottom, right); if ([self.tiledScrollViewDelegate respondsToSelector:@selector(tiledScrollViewDidZoom:)]) { [self.tiledScrollViewDelegate tiledScrollViewDidZoom:self]; } }
Здесь есть много решений, но я бы рискнул поставить здесь свои. Это хорошо по двум причинам: это не пугает масштабирование, так же как и обновление frameworks просмотра изображений, а также уважает оригинальные вставки прокрутки (скажем, определенные в xib или раскадровке для изящной обработки полупрозрачных панелей инструментов и т. Д.), ,
Сначала определите небольшой помощник:
CGSize CGSizeWithAspectFit(CGSize containerSize, CGSize contentSize) { CGFloat containerAspect = containerSize.width / containerSize.height, contentAspect = contentSize.width / contentSize.height; CGFloat scale = containerAspect > contentAspect ? containerSize.height / contentSize.height : containerSize.width / contentSize.width; return CGSizeMake(contentSize.width * scale, contentSize.height * scale); }
Чтобы сохранить исходные вставки, заданное поле:
UIEdgeInsets originalScrollViewInsets;
И где-то в viewDidLoad залейте его:
originalScrollViewInsets = self.scrollView.contentInset;
Поместить UIImageView в UIScrollView (при условии, что сам UIImage находится в loadImage var):
CGSize containerSize = self.scrollView.bounds.size; containerSize.height -= originalScrollViewInsets.top + originalScrollViewInsets.bottom; containerSize.width -= originalScrollViewInsets.left + originalScrollViewInsets.right; CGSize contentSize = CGSizeWithAspectFit(containerSize, loadedImage.size); UIImageView *imageView = [[UIImageView alloc] initWithFrame:(CGRect) { CGPointZero, contentSize }]; imageView.autoresizingMask = UIViewAutoresizingNone; imageView.contentMode = UIViewContentModeScaleAspectFit; imageView.image = loadedImage; [self.scrollView addSubview:imageView]; self.scrollView.contentSize = contentSize; [self centerImageViewInScrollView];
scrollViewDidZoom: из UIScrollViewDelegate для этого прокрутки:
- (void)scrollViewDidZoom:(UIScrollView *)scrollView { if (scrollView == self.scrollView) { [self centerImageViewInScrollView]; } }
Наконец, центрируя себя:
- (void)centerImageViewInScrollView { CGFloat excessiveWidth = MAX(0.0, self.scrollView.bounds.size.width - self.scrollView.contentSize.width), excessiveHeight = MAX(0.0, self.scrollView.bounds.size.height - self.scrollView.contentSize.height), insetX = excessiveWidth / 2.0, insetY = excessiveHeight / 2.0; self.scrollView.contentInset = UIEdgeInsetsMake( MAX(insetY, originalScrollViewInsets.top), MAX(insetX, originalScrollViewInsets.left), MAX(insetY, originalScrollViewInsets.bottom), MAX(insetX, originalScrollViewInsets.right) ); }
Я еще не тестировал изменение ориентации (т.е. правильная реакция на изменение размера самого UIScrollView), но исправление для этого должно быть относительно простым.
Вы обнаружите, что решение, размещенное Erdemus, действительно работает, но … Есть случаи, когда метод scrollViewDidZoom не запускается, и ваше изображение застревает в верхнем левом углу. Простое решение заключается в явном вызове метода при первоначальном отображении изображения, например:
[self scrollViewDidZoom: scrollView];
Во многих случаях вы можете использовать этот метод дважды, но это более чистое решение, чем некоторые другие ответы в этом разделе.
Пример скроллера от Apple делает именно то, что вы ищете. Поместите это в свой подclass UIScrollView и измените _zoomView как ваш UIImageView.
-(void)layoutSubviews{ [super layoutSubviews]; // center the zoom view as it becomes smaller than the size of the screen CGSize boundsSize = self.bounds.size; CGRect frameToCenter = self.imageView.frame; // center horizontally if (frameToCenter.size.width < boundsSize.width){ frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2; }else{ frameToCenter.origin.x = 0; } // center vertically if (frameToCenter.size.height < boundsSize.height){ frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2; }else{ frameToCenter.origin.y = 0; } self.imageView.frame = frameToCenter; }
Пример кода Apple Scroller
Способ, которым я это сделал, – добавить дополнительный вид в иерархию:
UIScrollView -> UIView -> UIImageView
Дайте вашему UIView
те же пропорции, что и ваш UIScrollView
, и UIImageView
свой UIImageView
.
Чтобы stream анимации был приятным, установите
self.scrollview.bouncesZoom = NO;
и использовать эту функцию (нахождение центра с использованием метода при этом ответе )
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale { [UIView animateWithDuration:0.2 animations:^{ float offsetX = MAX((scrollView.bounds.size.width-scrollView.contentSize.width)/2, 0); float offsetY = MAX((scrollView.bounds.size.height-scrollView.contentSize.height)/2, 0); self.imageCoverView.center = CGPointMake(scrollView.contentSize.width*0.5+offsetX, scrollView.contentSize.height*0.5+offsetY); }]; }
Это создает эффект подпрыгивания, но не предполагает каких-либо внезапных движений заранее.
Только одобренный ответ в быстром, но без подclassа с использованием делегата
func centerScrollViewContents(scrollView: UIScrollView) { let contentSize = scrollView.contentSize let scrollViewSize = scrollView.frame.size; var contentOffset = scrollView.contentOffset; if (contentSize.width < scrollViewSize.width) { contentOffset.x = -(scrollViewSize.width - contentSize.width) / 2.0 } if (contentSize.height < scrollViewSize.height) { contentOffset.y = -(scrollViewSize.height - contentSize.height) / 2.0 } scrollView.setContentOffset(contentOffset, animated: false) } // UIScrollViewDelegate func scrollViewDidZoom(scrollView: UIScrollView) { centerScrollViewContents(scrollView) }
Если ваш внутренний imageView имеет начальную конкретную ширину (например, 300), и вы просто хотите центрировать его ширину только при масштабировании, меньшем, чем его начальная ширина, это также может помочь вам.
func scrollViewDidZoom(scrollView: UIScrollView){ if imageView.frame.size.width < 300{ imageView.center.x = self.view.frame.width/2 } }
Вот как я делаю эту работу. Это лучше, но все же не идеально. Попробуйте установить:
myScrollView.bouncesZoom = YES;
чтобы устранить проблему, когда представление не центрируется, когда в minZoomScale
.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGSize screenSize = [[self view] bounds].size;//[[UIScreen mainScreen] bounds].size;// CGSize photoSize = [yourImage size]; CGFloat topInset = (screenSize.height - photoSize.height * [myScrollView zoomScale]) / 2.0; CGFloat sideInset = (screenSize.width - photoSize.width * [myScrollView zoomScale]) / 2.0; if (topInset < 0.0) { topInset = 0.0; } if (sideInset < 0.0) { sideInset = 0.0; } [myScrollView setContentInset:UIEdgeInsetsMake(topInset, sideInset, -topInset, -sideInset)]; ApplicationDelegate *appDelegate = (ApplicationDelegate *)[[UIApplication sharedApplication] delegate]; CGFloat scrollViewHeight; //Used later to calculate the height of the scrollView if (appDelegate.navigationController.navigationBar.hidden == YES) //If the NavBar is Hidden, set scrollViewHeight to 480 { scrollViewHeight = 480; } if (appDelegate.navigationController.navigationBar.hidden == NO) //If the NavBar not Hidden, set scrollViewHeight to 360 { scrollViewHeight = 368; } imageView.frame = CGRectMake(0, 0, CGImageGetWidth(yourImage)* [myScrollView zoomScale], CGImageGetHeight(yourImage)* [myScrollView zoomScale]); [imageView setContentMode:UIViewContentModeCenter]; }
Also, I do the following to prevent the image from sticking a the side after zooming out.
- (void) scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale { myScrollView.frame = CGRectMake(0, 0, 320, 420); //put the correct parameters for your scroll view width and height above }
Okay, I think I’ve found a pretty good solution to this problem. The trick is to constantly readjust the imageView's
frame. I find this works much better than constantly adjusting the contentInsets
or contentOffSets
. I had to add a bit of extra code to accommodate both portrait and landscape images.
Вот код:
- (void) scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale { CGSize screenSize = [[self view] bounds].size; if (myScrollView.zoomScale <= initialZoom +0.01) //This resolves a problem with the code not working correctly when zooming all the way out. { imageView.frame = [[self view] bounds]; [myScrollView setZoomScale:myScrollView.zoomScale +0.01]; } if (myScrollView.zoomScale > initialZoom) { if (CGImageGetWidth(temporaryImage.CGImage) > CGImageGetHeight(temporaryImage.CGImage)) //If the image is wider than tall, do the following... { if (screenSize.height >= CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale]) //If the height of the screen is greater than the zoomed height of the image do the following... { imageView.frame = CGRectMake(0, 0, 320*(myScrollView.zoomScale), 368); } if (screenSize.height < CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale]) //If the height of the screen is less than the zoomed height of the image do the following... { imageView.frame = CGRectMake(0, 0, 320*(myScrollView.zoomScale), CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale]); } } if (CGImageGetWidth(temporaryImage.CGImage) < CGImageGetHeight(temporaryImage.CGImage)) //If the image is taller than wide, do the following... { CGFloat portraitHeight; if (CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale] < 368) { portraitHeight = 368;} else {portraitHeight = CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale];} if (screenSize.width >= CGImageGetWidth(temporaryImage.CGImage) * [myScrollView zoomScale]) //If the width of the screen is greater than the zoomed width of the image do the following... { imageView.frame = CGRectMake(0, 0, 320, portraitHeight); } if (screenSize.width < CGImageGetWidth (temporaryImage.CGImage) * [myScrollView zoomScale]) //If the width of the screen is less than the zoomed width of the image do the following... { imageView.frame = CGRectMake(0, 0, CGImageGetWidth(temporaryImage.CGImage) * [myScrollView zoomScale], portraitHeight); } } [myScrollView setZoomScale:myScrollView.zoomScale -0.01]; }
Just disable the pagination, so it’ll work fine:
scrollview.pagingEnabled = NO;
У меня была точно такая же проблема. Here is how I solved
This code should get called as the result of scrollView:DidScroll:
CGFloat imageHeight = self.imageView.frame.size.width * self.imageView.image.size.height / self.imageView.image.size.width; BOOL imageSmallerThanContent = (imageHeight < self.scrollview.frame.size.height) ? YES : NO; CGFloat topOffset = (self.imageView.frame.size.height - imageHeight) / 2; // If image is not large enough setup content offset in a way that image is centered and not vertically scrollable if (imageSmallerThanContent) { topOffset = topOffset - ((self.scrollview.frame.size.height - imageHeight)/2); } self.scrollview.contentInset = UIEdgeInsetsMake(topOffset * -1, 0, topOffset * -1, 0);
Although the question is a bit old yet the problem still exists. I solved it in Xcode 7 by making the vertical space constraint of the uppermost item (in this case the topLabel
) to the superViews (the scrollView
) top an IBOutlet
and then recalculating its constant every time the content changes depending on the height of the scrollView’s subviews ( topLabel
and bottomLabel
).
class MyViewController: UIViewController { @IBOutlet weak var scrollView: UIScrollView! @IBOutlet weak var topLabel: UILabel! @IBOutlet weak var bottomLabel: UILabel! @IBOutlet weak var toTopConstraint: NSLayoutConstraint! override func viewDidLayoutSubviews() { let heightOfScrollViewContents = (topLabel.frame.origin.y + topLabel.frame.size.height - bottomLabel.frame.origin.y) // In my case abs() delivers the perfect result, but you could also check if the heightOfScrollViewContents is greater than 0. toTopConstraint.constant = abs((scrollView.frame.height - heightOfScrollViewContents) / 2) } func refreshContents() { // Set the label's text … self.view.layoutIfNeeded() } }