19

iOS 6と自動レイアウトの前にUIScrollView内にUIImageViewを埋め込んでいますが、コントローラーのviedDidLoadメソッド内で次のスニペットを使用して、スクロール可能でズーム可能な画像を表示しました。

self.scrollView.contentSize = self.imageView.image.size;
self.imageView.frame = CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height);

ただし、ストーリーボードで設定された制約が代わりに使用されるようになりました。私はこの質問をiOS6の自動レイアウトでScrollViewに埋め込み、viewDidLoadの後に制約がロード/適用され、以前のスニペットをviewDidAppearに移動するとこの問題は修正されるが、ズームが正しく機能しないことを示す他のいくつかの質問を見つけましたそして、scrollViewとimageViewのサイズは、ピンチしてズームするジェスチャの後、ストーリーボードの制約にリセットされているようです。

推測しているだけですが、コード内でscrollViewとimageViewの垂直方向と水平方向のスペースの制約をオーバーライドする方法があると思います。

この問題を抱えている人は他にいますか?

4

3 に答える 3

14

最良の解決策は、コメントでZsoltによって提案されました。

http://github.com/evgenyneu/ios-imagescrollこれをチェックしてください。私にとっては完璧に機能します。

このリポジトリで提案されている解決策は、画像を表示する前に最小および現在のズームレベルを調整することです。

@interface MyViewController () <UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end


@implementation MyViewController

- (void)viewDidLoad
{
  [super viewDidLoad];
  self.scrollView.delegate = self;

  [self initZoom];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
  [self initZoom];
}

// Zoom to show as much image as possible
- (void) initZoom {
  float minZoom = MIN(self.view.bounds.size.width / self.imageView.image.size.width,
                      self.view.bounds.size.height / self.imageView.image.size.height);
  if (minZoom > 1) return;

  self.scrollView.minimumZoomScale = minZoom;

  self.scrollView.zoomScale = minZoom;
}

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

ただし、サンプルのconatinsはズームアウトで問題が発生します。画像が中央に配置されていません。これは、次のコードを含むカスタムスクロールビュークラスを使用することで簡単に修正できます。

@interface MyScrollView : UIScrollView
@end

@implementation MyScrollView

-(void)layoutSubviews
{
  [super layoutSubviews];
  UIView* v = [self.delegate viewForZoomingInScrollView:self];
  CGFloat svw = self.bounds.size.width;
  CGFloat svh = self.bounds.size.height;
  CGFloat vw = v.frame.size.width;
  CGFloat vh = v.frame.size.height;
  CGRect f = v.frame;
  if (vw < svw)
    f.origin.x = (svw - vw) / 2.0;
  else
    f.origin.x = 0;
  if (vh < svh)
    f.origin.y = (svh - vh) / 2.0;
  else
    f.origin.y = 0;
  v.frame = f;
}

@end
于 2013-09-23T09:25:09.120 に答える
7

次のコードサンプルを使用して問題を解決しました。githubリポジトリは、MattNeuburgによる「ProgrammingiOS」という本に対応しています。

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/11c6c57743b04e6e722b635b87be69fa41a5abaf/ch20p573scrollViewAutoLayout/ch20p573scrollViewAutoLayout/ViewController.m

于 2013-01-27T22:26:55.057 に答える
5

Zsoltの提案とリンクにも同意します。

ただし、幅/高さの制約を更新して、任意のサイズの画像を処理できるようにします。

- (void) initZoom
{
  for (NSLayoutConstraint *constraint in self.photoImageView.constraints)
  {
    if (constraint.firstAttribute == NSLayoutAttributeWidth)
      constraint.constant = self.photoImageView.image.size.width;
    else if (constraint.firstAttribute == NSLayoutAttributeHeight)
      constraint.constant = self.photoImageView.image.size.height;
  }

  float minZoom = MIN(self.scrollView.bounds.size.width / self.photoImageView.image.size.width,
                      self.scrollView.bounds.size.height / self.photoImageView.image.size.height);
  if (minZoom > 1) return;

  self.scrollView.minimumZoomScale = minZoom;

  self.scrollView.zoomScale = minZoom;
}
于 2013-11-21T00:52:15.483 に答える