在iOS 6上使用自动布局将ImageView嵌入到ScrollView中

20

我正在尝试使用新的iOS 6 SDK和自动布局来创建非常简单的元素。 我有一个ImageView并将其嵌入ScrollView中。(一切都是使用Interface Builder构建的。).png文件已设置,imageView模式设置为“左上角”。

实现:

#import "ImaginariumViewController.h"

@interface ImaginariumViewController ()
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end

@implementation ImaginariumViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.scrollView.contentSize = self.imageView.image.size;
    self.imageView.frame =
    CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height);
}

@end

当我运行这个应用程序时,图片无法滚动。但是,如果关闭自动布局(使用struts和springs),则可以进行正常的滚动。我猜问题出在约束上。请问有人能帮助我吗?

2个回答

52

我刚刚在更新教程时遇到了同样的问题。我尝试了编程删除约束、咒骂和撞墙,但都没有用。

然而,大概五分钟前,我尝试了一些曾经解决过其他问题的方法,然后——哒哒!UIScrollView又可以工作了!解决方法是将设置UIScrollView contentSize属性的旧代码移动到viewDidAppear的实现中,而不是viewDidLoad:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    self.theScroller.contentSize=CGSizeMake(200.0,2000.0);
}

我希望这能帮助到其他遇到自动布局问题的人。


这个可行,谢谢!真奇怪苹果在iOS 6文档中没有提供关于这个的信息。可能问题是因为约束比-viewDidLoad被调用的时间晚(尽管它来自故事板,应该在awakeFeomNib上设置,比viewDidLoad更早被调用,据我所知)。 - Vitaly
2
尽管在scrollView中缩放imageView还存在另一个问题。 - Vitaly
这个代码按预期工作。但我想知道在更改viewDidAppear中的contentSize之前是否有一种设置UIScrollView(启用autoLayout)的contentSize的方法。当我将代码从viewDidAppear方法中移除时,我无法使其正常工作... - Yannick
你是否尝试将其放入“-(void)updateViewConstraints”中?这似乎可以提供一种处理视图加载后contentSize更改的方法。 - Tim Shadel
尝试了各种奇怪的自动调整掩码和其他可能的组合两个小时后,这就是解决方案。 - mszaro
显示剩余2条评论

27

一开始使用自动布局可能会非常令人困惑。实际上,你不需要在任何地方设置scrollview的contentSize。采用纯自动布局方法,scrollview将设置自己的内容大小。请参见iOS 6发布说明中有关自动布局和UIScrollView部分:

  

滚动视图的子视图上的约束必须产生一个填充大小,然后被解释为滚动视图的内容大小。(这不应该与用于自动布局的intrinsicContentSize方法混淆。)

请注意,这意味着scrollview的子视图上的约束必须设置明确的宽度和高度,并且不能使用基于scrollview某些方面变化的宽度。

第二个错误在于您将UIImageView的框架设置为图像的大小。使用自动布局也是不必要的。实际上,UIImageView 有一个intrinsicContentSize ,它是底层图像的大小。(要更改此设置,请使用高优先级设置宽度和高度的约束) 这意味着使用自动布局在滚动视图中放置图像并使其正确滚动的正确代码应该是以下内容:

** nothing at all!!! **

但是还有一些需要注意的问题,可能会导致您的图像似乎无法滚动,提示在之前链接的发布说明中:

请注意,通过创建视图与滚动视图子树之外的视图(例如滚动视图的父视图)之间的约束条件,可以使滚动视图的子视图浮现(而不是滚动)至其他滚动内容上方。

也就是说,如果您在接口构建器中设置约束,并将图像视图约束到层次结构中滚动视图上方的视图,则会影响视图的滚动效果。太疯狂了!

编码愉快...


谢谢。您关于将图像视图设置为高优先级宽度/高度的笔记帮助了我。 - bean
嘿@jackslash,我想知道你是否知道如何在视图和滚动视图的父视图之间创建约束(以此为例)。我已经尝试了一段时间,但是不知道该怎么做。 - Ants
@Ants 这对我来说听起来像是一个全新的问题!如果你创建了一个链接,请在这里分享给我看看。 - jackslash
这是我的问题(https://dev59.com/HG7Xa4cB1Zd3GeqPrZWs#14927581)。我用我今天开始开发的东西回答了它。 - Ants
2
这应该是被接受的答案。John的回答大多是一种hack,可能会破坏你的约束条件。 - Guillaume Algis
1
我发现以下教程很有帮助: https://dev59.com/umIk5IYBdhLWcg3wn_VF#19112639 这种方法与jackslash的方法相似(或者说是一样的)。 - MiuMiu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接