19

我在 UIScrollView 中嵌入了 UIImageView,在 iOS 6 和自动布局之前,我在控制器的 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 in ScrollView with Auto Layout on iOS 6和其他一些在 SO 中指出约束是在 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;
}

但是,缩小样本时会出现问题。图像未居中。这可以通过使用包含以下代码的自定义滚动视图类轻松解决:

@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 存储库对应于 Matt Neuburg 所著的 Programming iOS。

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 回答