使用autolayout在UIScrollView中缩放UIImageView

时间:2013-01-23 02:02:16

标签: ios6 uiscrollview uiimageview autolayout

我在UIScrollView中嵌入了UIImageView,在iOS 6和autolayout之前我在控制器的viedDidLoad方法中使用了以下代码段来显示可滚动和可缩放的图像。

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

但现在使用故事板中设置的约束来代替。我在这里找到了这个问题Embed ImageView in ScrollView with Auto Layout on iOS 6和其他一些问题,说明在viewDidLoad之后加载/强制执行约束,并且将我之前的代码片段移动到viewDidAppear会修复此问题,但缩放不能正常工作,而且似乎在缩放到缩放手势后,scrollView和imageView的大小将重置为情节提要的约束。

我只是在猜测,但我想也许有一些方法可以在代码中覆盖scrollView和imageView的垂直和水平空间约束。

其他人有这个问题吗?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:7)

答案 2 :(得分: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;
}