方向更改后将UIScrollView重置为新的框架尺寸

时间:2013-07-20 18:54:35

标签: ios ios6 uiview uiscrollview uiimageview

我有一个ImageZoom类,它是UIView的子类,是UIScrollView的delgate。这很直接。该类包含一个包含UIImageView的UIScrollView。将类的实例添加到视图控制器时,图像将被缩放,以使其与视图齐平。有一种方法可以在双击时放大,在重复时缩小。除了我将方向改为景观之外,一切都很有效。我似乎无法弄清楚如何使缩放正确,以便图像现在与新方向齐平。这是一个文件链接:

http://www.2shared.com/file/bowDjzLr/imagescroll.html

ViewController.h

#import <UIKit/UIKit.h>
#import "ImageZoom.h"

@interface ViewController : UIViewController

@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic,strong) ImageZoom *imageZoom;
@property (nonatomic, strong) UIImage *image;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.image = [UIImage imageNamed:@"1.png"];
}

-(void)viewDidAppear:(BOOL)animated
{
    ImageZoom *imageZoom = [[ImageZoom alloc]initWithImage:self.image andFrame:self.view.bounds];
    self.imageZoom = imageZoom;
    [self.view addSubview:imageZoom];

}
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [self.imageZoom willAnimateToFrame:self.view.bounds];
}

@end

ImageZoom.h

#import <UIKit/UIKit.h>

@interface ImageZoom : UIView <UIScrollViewDelegate>

- (id)initWithImage:(UIImage *)image andFrame:(CGRect)frame;
-(void)willAnimateToFrame:(CGRect)frame;

@end

ImageZoom.m

#import "ImageZoom.h"

@interface ImageZoom ()

@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIScrollView *scrollView;
@property BOOL zoomed;

@end

@implementation ImageZoom

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        [self loadContent];
    }
    return self;
}
-(void)loadContent
{
    self.scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    self.scrollView.delegate = self;
    self.scrollView.contentSize = self.image.size;
    [self.scrollView addSubview:self.imageView];
    [self addSubview:self.scrollView];

    CGRect scrollViewFrame = self.scrollView.frame;
    CGFloat scaleWidth = scrollViewFrame.size.width / self.scrollView.contentSize.width;
    CGFloat scaleHeight = scrollViewFrame.size.height / self.scrollView.contentSize.height;
    CGFloat minScale = MIN(scaleWidth, scaleHeight);

    self.scrollView.minimumZoomScale = minScale;
    self.scrollView.maximumZoomScale = 1;
    self.scrollView.zoomScale = minScale;

    UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewDoubleTapped:)];
    doubleTapRecognizer.numberOfTapsRequired = 2;
    doubleTapRecognizer.numberOfTouchesRequired = 1;
    [self.scrollView addGestureRecognizer:doubleTapRecognizer];
}

-(void)willAnimateToFrame:(CGRect)frame
{
    self.scrollView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);

    CGRect scrollViewFrame = self.scrollView.frame;
    CGFloat scaleWidth = scrollViewFrame.size.width / self.scrollView.contentSize.width;
    CGFloat scaleHeight = scrollViewFrame.size.height / self.scrollView.contentSize.height;
    CGFloat minScale = MIN(scaleWidth, scaleHeight);

    self.scrollView.minimumZoomScale = minScale;
    self.scrollView.maximumZoomScale = 1;
    self.scrollView.zoomScale = minScale;

    CGPoint centerPoint = CGPointMake(CGRectGetMidX(self.scrollView.frame), CGRectGetMidY(self.scrollView.frame));
    [self view:self.imageView setCenter:centerPoint];
}


- (void)view:(UIView*)view setCenter:(CGPoint)centerPoint
{
    CGRect viewFrame = view.frame;

    CGPoint scrollViewContentOffset = self.scrollView.contentOffset;

    CGFloat x = centerPoint.x - viewFrame.size.width / 2.0;
    CGFloat y = centerPoint.y - viewFrame.size.height / 2.0;

    if(x < 0)
    {
        scrollViewContentOffset.x = -x;
        viewFrame.origin.x = 0.0;
    }
    else
    {
        viewFrame.origin.x = x;
    }
    if(y < 0)
    {
        scrollViewContentOffset.y = -y;
        viewFrame.origin.y = 0.0;
    }
    else
    {
        viewFrame.origin.y = y;
    }

    view.frame = viewFrame;
    self.scrollView.contentOffset = scrollViewContentOffset;
    self.zoomed = NO;
}

- (id)initWithImageView:(UIImageView *)imageView andFrame:(CGRect)frame
{
    self.image = imageView.image;
    self.imageView = imageView;
    return [self initWithFrame:frame];
}

- (id)initWithImage:(UIImage *)image andFrame:(CGRect)frame
{
    self.image = image;
    self.imageView = [[UIImageView alloc] initWithImage:self.image];
    return [self initWithFrame:frame];
}

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

- (void)scrollViewDidZoom:(UIScrollView *)sv
{
    UIView* zoomView = [sv.delegate viewForZoomingInScrollView:sv];
    CGRect zoomViewFrame = zoomView.frame;
    if(zoomViewFrame.size.width < sv.bounds.size.width)
    {
        zoomViewFrame.origin.x = (sv.bounds.size.width - zoomViewFrame.size.width) / 2.0;
    }
    else
    {
        zoomViewFrame.origin.x = 0.0;
    }
    if(zoomViewFrame.size.height < sv.bounds.size.height)
    {
        zoomViewFrame.origin.y = (sv.bounds.size.height - zoomViewFrame.size.height) / 2.0;
    }
    else
    {
        zoomViewFrame.origin.y = 0.0;
    }
    zoomView.frame = zoomViewFrame;
}

- (void)scrollViewDoubleTapped:(UITapGestureRecognizer*)recognizer
{
    if(self.zoomed==NO)
    {
        CGPoint pointInView = [recognizer locationInView:self.imageView];
        CGSize scrollViewSize = self.scrollView.bounds.size;
        CGFloat w = scrollViewSize.width / self.scrollView.maximumZoomScale;
        CGFloat h = scrollViewSize.height / self.scrollView.maximumZoomScale;
        CGFloat x = pointInView.x - (w / 2.0);
        CGFloat y = pointInView.y - (h / 2.0);

        CGRect rectToZoomTo = CGRectMake(x, y, w, h);

        [self.scrollView zoomToRect:rectToZoomTo animated:YES];
        self.zoomed = YES;
    }
    else if(self.zoomed == YES)
    {
        CGRect rectToZoomTo = CGRectMake(0, 0, self.scrollView.contentSize.width, self.scrollView.contentSize.height);
        [self.scrollView zoomToRect:rectToZoomTo animated:YES];
        self.zoomed = NO;
    }
}

@end

它与viewController更改方向时调用的willAnimateToFrame方法有关。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

如果有人对此感兴趣,请使用它。我不得不对我的ImageZoom.m文件进行一些更改:

#import "ImageZoom.h"

@interface ImageZoom ()

@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIScrollView *scrollView;
@property BOOL zoomed;

@end

@implementation ImageZoom

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        [self loadContentWithFrame:frame];
    }
    return self;
}
-(void)loadContentWithFrame:(CGRect)frame
{
    self.scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(self.frame.origin.x, self.frame.origin.y, frame.size.width, frame.size.height)];
    self.scrollView.delegate = self;
    self.scrollView.contentSize = self.image.size;
    self.backgroundColor = [UIColor redColor];
    [self.scrollView addSubview:self.imageView];
    [self addSubview:self.scrollView];

    CGRect scrollViewFrame = self.scrollView.frame;
    CGFloat scaleWidth = scrollViewFrame.size.width / self.scrollView.contentSize.width;
    CGFloat scaleHeight = scrollViewFrame.size.height / self.scrollView.contentSize.height;
    CGFloat minScale = MIN(scaleWidth, scaleHeight);

    self.scrollView.minimumZoomScale = minScale;
    self.scrollView.maximumZoomScale = 1;
    self.scrollView.zoomScale = minScale;

    UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewDoubleTapped:)];
    doubleTapRecognizer.numberOfTapsRequired = 2;
    doubleTapRecognizer.numberOfTouchesRequired = 1;
    [self.scrollView addGestureRecognizer:doubleTapRecognizer];

    self.zoomed = NO;
}

-(void)willAnimateToFrame:(CGRect)frame
{
    self.frame = frame;
    [self loadContentWithFrame:frame];
}


- (id)initWithImageView:(UIImageView *)imageView andFrame:(CGRect)frame
{
    self.image = imageView.image;
    self.imageView = imageView;
    return [self initWithFrame:frame];
}

- (id)initWithImage:(UIImage *)image andFrame:(CGRect)frame
{
    self.image = image;
    self.imageView = [[UIImageView alloc] initWithImage:self.image];
    return [self initWithFrame:frame];
}

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

- (void)scrollViewDidZoom:(UIScrollView *)sv
{
    UIView* zoomView = [sv.delegate viewForZoomingInScrollView:sv];
    CGRect zoomViewFrame = zoomView.frame;
    if(zoomViewFrame.size.width < sv.bounds.size.width)
    {
        zoomViewFrame.origin.x = (sv.bounds.size.width - zoomViewFrame.size.width) / 2.0;
    }
    else
    {
        zoomViewFrame.origin.x = 0.0;
    }
    if(zoomViewFrame.size.height < sv.bounds.size.height)
    {
        zoomViewFrame.origin.y = (sv.bounds.size.height - zoomViewFrame.size.height) / 2.0;
    }
    else
    {
        zoomViewFrame.origin.y = 0.0;
    }
    zoomView.frame = zoomViewFrame;
}

- (void)scrollViewDoubleTapped:(UITapGestureRecognizer*)recognizer
{
    if(self.zoomed==NO)
    {
        CGPoint pointInView = [recognizer locationInView:self.imageView];
        CGSize scrollViewSize = self.scrollView.bounds.size;
        CGFloat w = scrollViewSize.width / self.scrollView.maximumZoomScale;
        CGFloat h = scrollViewSize.height / self.scrollView.maximumZoomScale;
        CGFloat x = pointInView.x - (w / 2.0);
        CGFloat y = pointInView.y - (h / 2.0);

        CGRect rectToZoomTo = CGRectMake(x, y, w, h);

        [self.scrollView zoomToRect:rectToZoomTo animated:YES];
        self.zoomed = YES;
    }
    else if(self.zoomed == YES)
    {
        CGRect rectToZoomTo = CGRectMake(0, 0, self.scrollView.contentSize.width, self.scrollView.contentSize.height);
        [self.scrollView zoomToRect:rectToZoomTo animated:YES];
        self.zoomed = NO;
    }
}

@end