考虑一个带有一个子视图的UIScrollView
。子视图是一个UIImageView
,具有以下尺寸约束:
- 它的高度必须等于
UIScrollView
的高度。 - 其宽度必须是按照
UIImageView
的高度比例缩放后的图像宽度。
预期UIImageView
的宽度将大于UIScrollView
的宽度,因此需要滚动。
图像可能在viewDidLoad
中设置(如果已缓存)或异步设置。
如何使用自动布局实现上述内容,并尽可能多地利用Interface Builder?
到目前为止我做了什么
基于这个答案,我将我的nib配置如下:
UIScrollView
固定到其父视图的边缘。UIImageView
固定到UIScrollView
的边缘。UIImageView
具有占位符内在大小(以避免可滚动内容大小歧义错误)
如预期的那样,结果是UIImageView
的大小与UIImage
的大小相同,并且UIScrollView
水平和垂直滚动(因为图像大于UIScrollView
)。
然后我尝试了一些没有效果的方法:
- 手动加载图像后设置
UIImageView
框架。 - 添加一个
UIImageView
的宽度约束并在加载图像后修改其值。这使图像变得更大(?!)。 - 在加载图像后设置
zoomScale
。没有可见的效果。
没有自动布局
以下代码完全符合我的要求,但没有使用自动布局或界面生成器。
- (void)viewDidLoad
{
{
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:scrollView];
self.scrollView = scrollView;
}
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height)];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.scrollView addSubview:imageView];
self.scrollView.contentSize = imageView.frame.size;
self.imageView = imageView;
}
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self layoutStripImageView];
}
- (void)layoutStripImageView
{ // Also called when the image finishes loading
UIImage *image = self.imageView.image;
if (! image) return;
const CGSize imageSize = image.size;
const CGFloat vh = self.scrollView.frame.size.height;
const CGFloat scale = vh / imageSize.height;
const CGFloat vw = imageSize.width * scale;
CGSize imageViewSize = CGSizeMake(vw, vh);
self.imageView.frame = CGRectMake(0, 0, imageViewSize.width, imageViewSize.height);
self.scrollView.contentSize = imageViewSize;
}
我很努力地尝试使用自动布局,但这并不容易。