使用autolayout在UIScrollView中缩放UIImageView

Die*_*len 19 uiscrollview uiimageview autolayout ios6

我在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);
Run Code Online (Sandbox Code Playgroud)

但现在使用故事板中设置的约束.我发现这个问题在iOS 6上使用自动布局在ScrollView中嵌入ImageView,其他一些在SO中说明在viewDidLoad之后加载/强制执行约束,并且将我之前的代码片段移动到viewDidAppear会解决此问题,但缩放不能正常工作似乎在缩放到缩放手势后,scrollView和imageView的大小会重置为storyboard的约束.

我只是在猜测,但我认为可能有一些方法可以覆盖scrollView和imageView在可能有效的代码中的垂直和水平空间约束.

其他人有这个问题吗?

Ant*_*sov 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;
}
Run Code Online (Sandbox Code Playgroud)

然而,样本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
Run Code Online (Sandbox Code Playgroud)


Die*_*len 7

使用以下代码示例解决了我的问题.github存储库对应于Matt Neuburg的Programming iOS.

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

  • https://github.com/evgenyneu/ios-imagescroll检查一下.适合我. (12认同)
  • 我通过关闭translatesAutoresizingMaskIntoConstraints然后在viewWillLayoutSubviews中将帧的原点设置为0来解决我的问题.图像不居中,但至少在缩放时它不会从可滚动区域滑落. (2认同)

Mof*_*Mof 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;
}
Run Code Online (Sandbox Code Playgroud)