Не удается установить изображение в UIScrollView после увеличения
Я использую ImageScrollView
показать изображение. В начале я показываю только маленькое изображение. И когда пользователь пытается увеличить, я загружаю большое изображение. Сначала я хотел сделать это с помощью этого кода:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollViewCalled
{
ImageScrollView *scroll = (ImageScrollView *)scrollViewCalled;
UIImageView *imageView = (UIImageView *)[scroll imageView];
return imageView;
}
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollViewCalled withView:(UIView *)view
{
ImageScrollView *scroll = (ImageScrollView *)scrollViewCalled;
if (scroll != scrollViewCalled || scroll.isImageBig)
{
return;
}
scroll.userInteractionEnabled = NO;
[self setBigImageInBackgroundForIndex:nil];
}
Но это работает странно: когда я пытаюсь увеличить, показывается большое изображение, но я вижу его максимальный масштаб и не могу прокрутить, чтобы увидеть оставшуюся часть изображения. Но когда я увеличиваю изображение еще раз, а не прокручиваю изображение, оно начинает работать должным образом, и я наконец могу прокрутить изображение. Но я должен увеличить 2 раза для этого.
Потом я попробовал scrollViewDidEndZooming
вместо scrollViewWillBeginZooming
:
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollViewCalled withView:(UIView *)view atScale:(float)scale
{
ImageScrollView *scroll = (ImageScrollView *)scrollViewCalled;
if (scroll != scrollViewCalled || scroll.isImageBig)
{
return;
}
scroll.userInteractionEnabled = NO;
[self setBigImageInBackgroundForIndex:nil];
}
И все стало идеально, кроме одного: уже слишком поздно. Я увеличиваю маленькое изображение, вижу увеличенный вариант, затем загружается большое изображение, и я вижу минимальное увеличение для большого изображения. Пользователю кажется, что изображение вернулось к своему обычному зуму. И только если я попытаюсь увеличить масштаб еще раз, я смогу увеличить масштаб идеально.
Заранее спасибо!
вот код для ImageScrollView:
ImageScrollView.h
#import <UIKit/UIKit.h>
@interface ImageScrollView : UIScrollView <UIScrollViewDelegate> {
UIView *imageView;
NSUInteger index;
}
@property (assign) NSUInteger index;
@property (retain, nonatomic) UIView *imageView;
@property (assign, nonatomic) BOOL isImageBig;
@property (assign, nonatomic) BOOL hasImage;
- (void)displayImage:(UIImage *)image;
- (void)displayTiledImageNamed:(NSString *)imageName size:(CGSize)imageSize;
- (void)setMaxMinZoomScalesForCurrentBounds;
- (CGPoint)pointToCenterAfterRotation;
- (CGFloat)scaleToRestoreAfterRotation;
- (void)restoreCenterPoint:(CGPoint)oldCenter scale:(CGFloat)oldScale;
@end
ImageScrollView.m
#import "ImageScrollView.h"
#import "TilingView.h"
@implementation ImageScrollView
@synthesize index;
@synthesize imageView;
@synthesize isImageBig, hasImage;
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
self.showsVerticalScrollIndicator = NO;
self.showsHorizontalScrollIndicator = NO;
self.bouncesZoom = YES;
self.decelerationRate = UIScrollViewDecelerationRateFast;
self.delegate = self;
}
return self;
}
- (void)dealloc
{
[imageView release];
[super dealloc];
}
#pragma mark -
#pragma mark Override layoutSubviews to center content
- (void)layoutSubviews
{
[super layoutSubviews];
// center the image as it becomes smaller than the size of the screen
CGSize boundsSize = self.bounds.size;
CGRect frameToCenter = 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;
imageView.frame = frameToCenter;
if ([imageView isKindOfClass:[TilingView class]]) {
// to handle the interaction between CATiledLayer and high resolution screens, we need to manually set the
// tiling view's contentScaleFactor to 1.0. (If we omitted this, it would be 2.0 on high resolution screens,
// which would cause the CATiledLayer to ask us for tiles of the wrong scales.)
imageView.contentScaleFactor = 1.0;
}
}
#pragma mark -
#pragma mark UIScrollView delegate methods
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return imageView;
}
#pragma mark -
#pragma mark Configure scrollView to display new image (tiled or not)
- (void)displayImage:(UIImage *)image
{
// clear the previous imageView
[imageView removeFromSuperview];
[imageView release];
imageView = nil;
// reset our zoomScale to 1.0 before doing any further calculations
self.zoomScale = 1.0;
self.imageView = [[[UIImageView alloc] initWithImage:image] autorelease];
[self addSubview:imageView];
self.contentSize = [image size];
[self setMaxMinZoomScalesForCurrentBounds];
self.zoomScale = self.minimumZoomScale;
// self.zoomScale = self.maximumZoomScale;
}
- (void)setMaxMinZoomScalesForCurrentBounds
{
CGSize boundsSize = self.bounds.size;
CGSize imageSize = imageView.bounds.size;
// calculate min/max zoomscale
CGFloat xScale = boundsSize.width / imageSize.width; // the scale needed to perfectly fit the image width-wise
CGFloat yScale = boundsSize.height / imageSize.height; // the scale needed to perfectly fit the image height-wise
CGFloat minScale = MIN(xScale, yScale); // use minimum of these to allow the image to become fully visible
// on high resolution screens we have double the pixel density, so we will be seeing every pixel if we limit the
// maximum zoom scale to 0.5.
CGFloat maxScale = 1.0 / [[UIScreen mainScreen] scale];
// CGFloat maxScale = 4.0 / [[UIScreen mainScreen] scale];
// don't let minScale exceed maxScale. (If the image is smaller than the screen, we don't want to force it to be zoomed.)
if (minScale > maxScale) {
minScale = maxScale;
}
self.maximumZoomScale = maxScale;
self.minimumZoomScale = minScale;
}
@end
2 ответа
Вам не нужно делать так много на самом деле. Создайте ScrollView. Создайте изображение с большим изображением. Установите рамку imageview и рамку scrollview аналогично. Установите размер содержимого прокрутки с шириной и высотой изображений. Теперь из метода делегата scrollview сделайте следующее:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return imageView;
}
Добавьте этот метод:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return imageView;
}