UIScrollView上でズームした時のUIImageViewをセンタリングorリサイズしたい
UIScrollViewの上にUIImageViewを乗せてピンチで縮小/拡大とダブルタップで最大倍率/最小倍率
というズームをしているのですが、画像の高さが小さい画像でズームすると
下の写真のように、何もない領域を表示できてしまいます。
試行錯誤してみましたが解決策がわからず質問させて頂きました。
解決策のご教授お願い致します。
画像
[自アプリズーム前]......(問題発生)[自アプリズーム後]......(目標)[デフォルト写真アプリズーム後]
現状
- AutoLayout使用なし
- view contentMode →scaleToFill
scrollView contentMode→scaleToFill
ImageView→AspectFit self.view.frame == self.scrollview.frame == self.mainImageView.frame;
三つとも同じフレームで被せています。※RMP~はナビゲーションバーを使ったカスタム画面移動のOSSです。
RMPZoomTransitionAnimator/GitHub
当該コード
< DetailViewController.h>
#import <UIKit/UIKit.h>
#import "RMPZoomTransitionAnimator.h"
@interface DetailViewController : UIViewController<RMPZoomTransitionAnimating, RMPZoomTransitionDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (nonatomic, weak) IBOutlet UIImageView *mainImageView;
@end
< DetailViewController.m>
#import "DetailViewController.h"
#define DEFAULT_ZOOM_SCALE 1.0
#define SCALE_RATE 3.0
@interface DetailViewController ()<UIScrollViewDelegate>
//zoom when doubleTap.
- (void)onDoubleTapOnPhoto:(id)sender;
@end
@implementation DetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.scrollView.minimumZoomScale = DEFAULT_ZOOM_SCALE;
self.scrollView.maximumZoomScale = SCALE_RATE;
self.scrollView.delegate = self;
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onDoubleTapOnPhoto:)];
doubleTap.numberOfTapsRequired = 2;
[self.view addGestureRecognizer:doubleTap];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)onDoubleTapOnPhoto:(id)sender
{
float zoom = self.scrollView.zoomScale;
CGPoint tapPoint = [sender locationInView:self.scrollView];
// Zoom=self.scrollView.zoom → Zoom=1.0
tapPoint.x /= zoom;
tapPoint.y /= zoom;
if (zoom >self.scrollView.minimumZoomScale)
{
// already max zoom : set zoom to default
[self.scrollView setZoomScale:DEFAULT_ZOOM_SCALE animated:YES];
} else
{
// zoom up
float newZoom = zoom * SCALE_RATE;
if (newZoom >= self.scrollView.maximumZoomScale)
{
newZoom = self.scrollView.maximumZoomScale;
}
CGRect newRect = [self zoomRectForScrollView:self.scrollView
withScale:newZoom
withCenter:tapPoint];
[self.scrollView zoomToRect:newRect animated:YES];
}
}
#pragma - scrollViewZooming
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.mainImageView;
}
- (CGRect)zoomRectForScrollView:(UIView *)scrollView withScale:(float)scale withCenter:(CGPoint)center {
CGRect zoomRect;
// The zoom rect is in the content view's coordinates.
// At a zoom scale of 1.0, it would be the size of the
// imageScrollView's bounds.
// As the zoom scale decreases, so more content is visible,
// the size of the rect grows.
zoomRect.size.height = scrollView.frame.size.height / scale;
zoomRect.size.width = scrollView.frame.size.width / scale;
// choose an origin so as to get the right center.
zoomRect.origin.x = center.x - (zoomRect.size.width / 2.0);
zoomRect.origin.y = center.y - (zoomRect.size.height / 2.0);
return zoomRect;
}
#pragma mark - <RMPZoomTransitionAnimating>
- (UIImageView *)transitionSourceImageView
{
UIImageView *imageView = [[UIImageView alloc] initWithImage:self.mainImageView.image];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.clipsToBounds = YES;
imageView.userInteractionEnabled = NO;
imageView.frame = self.mainImageView.frame;
return imageView;
}
- (UIColor *)transitionSourceBackgroundColor
{
return self.view.backgroundColor;
}
- (CGRect)transitionDestinationImageViewFrame
{
return self.mainImageView.frame;
}
#pragma mark - <RMPZoomTransitionDelegate>
- (void)zoomTransitionAnimator:(RMPZoomTransitionAnimator *)animator
didCompleteTransition:(BOOL)didComplete
animatingSourceImageView:(UIImageView *)imageView
{
self.mainImageView.image = imageView.image;
}
@end