scrollView内にImageViewを配置する。

iPhoneアプリで、scrollView内に任意の縦横比のImageViewをセンタリングして配置するための実装を行ってみる。

scrollviewの生成

前提となる準備として view load時にscrollViewの生成,セットアップを行う。

- (void)viewDidLoad {
  NSLog(@"photo view contoller viewDidLoad");
  [super viewDidLoad];
  
  .... あれこれ ....

  CGRect rect = self.view.bounds;
  scrollView = [[UIScrollView alloc] initWithFrame:rect];
 
  scrollView.maximumZoomScale = 3.0;
  scrollView.minimumZoomScale = 1.0;
  scrollView.delegate = self;
  scrollView.scrollEnabled = YES;
  scrollView.userInteractionEnabled = YES;
  scrollView.bounces = NO;
  scrollView.multipleTouchEnabled = YES;
  [self.view addSubview:scrollView];
}

ImageViewを追加

ImageViewを追加する(Viewが表示されるタイミングなど)さいには、以下のようにセンタリングされるようview frameの開始座標を設定すればよい。

- (void)viewDidAppear:(BOOL)animated {

  [super viewDidAppear:animated];

  .... あれこれ .....

  CGSize size = self.imageView.image.size;
  CGRect viewRect = self.scrollView.bounds;
  CGRect rect;
  if(size.height / size.width > viewRect.size.height / viewRect.size.width ) {
    // 縦長
    float rate = viewRect.size.height / image.size.height;
    float width = size.width * rate;
   
    rect = CGRectMake((viewRect.size.width -  width) / 2,
                      0.0f,
                      width,
                      viewRect.size.height);
  }
  else { // 横長
    float rate = viewRect.size.width / image.size.width;
    float height = size.height * rate;
    rect = CGRectMake(0.0f,
                      (viewRect.size.height - height) / 2,
                      viewRect.size.width,
                      height);
  }
  imageView.frame = rect;
}

Zooming時の座標調整

Zooming時にもセンタリングされるようview frameの開始座標を調整してやる必要がある。
scrollViewのDelegate(UIScrollViewDelegateプロトコル)の- (void)scrollViewDidZoom:(UIScrollView *)scrollView
メソッドで行う。

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
  CGRect frame = imageView.frame;
  if( (self.scrollView.bounds.size.width -
       self.scrollView.contentSize.width) / 2 > 0) {
       frame.origin.x = (self.scrollView.bounds.size.width -
                      self.scrollView.contentSize.width) / 2;
  }
  else {
    frame.origin.x = 0.0f;
  }
  if((self.scrollView.bounds.size.height -
      self.scrollView.contentSize.height) / 2 > 0) {
       frame.origin.y = (self.scrollView.bounds.size.height -
                      self.scrollView.contentSize.height) / 2;
  }
  else {
    frame.origin.y = 0.0f;
  }
 
  imageView.frame = frame;

}

Zooming/ScrollされるViewの指定も忘れずに

もちろん、Delegate(UIScrollViewDelegateプロトコル)の- viewForZoomingInScrollView:メソッドでScrollView内に含めるimageViewの指定を行っておく必要がある。

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