Autolayout混淆:与WebView和页眉/页脚视图的ScrollView的约束

为了说明我的问题,我创build了以下graphics:

现在在3D

红色方块周围的黑色边框应该是iPhone屏幕。 在里面,我们用红色的UIScrollView ,比屏幕更高。 事实上,它与UIWebView一样高,以黄色显示。 UIWebViewUIScrollView的子视图,禁用滚动function。 此外,我们有两个蓝色的视图,我喜欢称之为页眉和页脚视图。 它们也是UIScrollView子视图,但在可滚动边界之外。

我现在的问题是 :如何configuration自动布局约束呢?

我已经设法使用这个答案的代码检索UIWebView高度,然后相应地更新UIScrollViewcontentSize 。 然而,这不是一个好的解决scheme,因为UIWebView的宽度不会对UIScrollView宽度变化做出反应。

我也成功设置了标题视图的布局约束(使用Masonary ):

 [headerView makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(@-100); make.left.equalTo(@0); make.width.equalTo(scrollView.width); make.height.equalTo(@100); }]; 

但是,像这样设置页脚视图的布局不起作用:

 [changeView makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(scrollView.bottom) make.left.equalTo(@0); make.width.equalTo(scrollView.width); make.height.equalTo(@100); }]; 

我觉得这不是太困难,并希望得到一些更熟悉自动布局的人的帮助。 谢谢!

在可视化格式语言(VFL)中,约束条件是:

 [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(-100)-[headerView(100)]" options:0 metrics:nil views:views]]; [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[footerView(100)]-(-100)-|" options:0 metrics:nil views:views]]; [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[headerView]|" options:0 metrics:nil views:views]]; [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[footerView]|" options:0 metrics:nil views:views]]; 

或者,如果您要replace@"V:[footerView(100)]-(-100)-|" 具有constraintWithItem调用的VFL,它将是:

 [footerView addConstraint:[NSLayoutConstraint constraintWithItem:footerView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:100.0]]; [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:footerView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:100.0]]; 

我不能说为什么你的Masonary实现不起作用,因为我不熟悉它。 但是我会尝试以上其中一个,并确保。

坦率地说,你描述了设置Web视图的高度,我想知道你设置的Web视图的高度约束(好),或者你是否调整了frame.size.height值(坏)。 但是你还没有分享如何设置网页视图高度的细节,所以我不能进一步评论。

无论如何,如果你有基于约束的问题,有两个有用的诊断技术。 如果它仍然不能工作,我会在模拟器上运行应用程序,暂停它,然后在(lldb)提示符处input:

 po [[UIWindow keyWindow] _autolayoutTrace] 

你应该看到像这样的东西:

 (lldb) po [[UIWindow keyWindow] _autolayoutTrace] $0 = 0x0715d6e0 *<UIWindow:0x758aae0> | *<UIView:0x71630f0> | | *<UIScrollView:0x716a370> | | | *<HeaderView:0x716b860> | | | *<FooterView:0x716bbb0> | | | *<UIWebView:0x716c2b0> | | | | <_UIWebViewScrollView:0x7176a30> | | | | | ... | | | | | <UIWebBrowserView:0x797fe00> | | | <UIImageView:0x75e1360> | | | <UIImageView:0x75e2a60> 

确保你没有任何警告。 如果一切看起来都不错,那么我会在(lldb)提示符下使用下面的命令:

 po [[UIWindow keyWindow] recursiveDescription] 

你应该看到像这样的东西:

 (lldb) po [[UIWindow keyWindow] recursiveDescription] $1 = 0x071c0ea0 <UIWindow: 0x758aae0; frame = (0 0; 320 568); autoresize = W+H; layer = <UIWindowLayer: 0x758b770>> | <UIView: 0x71630f0; frame = (0 20; 320 548); autoresize = RM+BM; layer = <CALayer: 0x7163180>> | | <UIScrollView: 0x716a370; frame = (0 0; 320 548); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x716b1d0>; layer = <CALayer: 0x716ad20>; contentOffset: {0, 16}> | | | <HeaderView: 0x716b860; frame = (0 -100; 320 100); layer = <CALayer: 0x716b910>> | | | <FooterView: 0x716bbb0; frame = (0 564; 320 100); layer = <CALayer: 0x716bee0>> | | | <UIWebView: 0x716c2b0; frame = (0 8; 320 548); layer = <CALayer: 0x716c360>> | | | | <_UIWebViewScrollView: 0x7176a30; frame = (0 0; 320 548); clipsToBounds = YES; autoresize = H; gestureRecognizers = <NSArray: 0x7177000>; layer = <CALayer: 0x7176c80>; contentOffset: {0, 0}> | | | | | ... | | | | | <UIWebBrowserView: 0x797fe00; frame = (0 0; 1024 1754); gestureRecognizers = <NSArray: 0x7173260>; layer = <UIWebLayer: 0x716d7f0>> | | | | | | ... | | | <UIImageView: 0x75e1360; frame = (1 540; 318 7); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x75e2980>> | | | <UIImageView: 0x75e2a60; frame = (312 32.5; 7 530.5); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x75e2b00>> 

看看你的各种结果frame值,看看发生了什么。 这可以帮助您诊断解决scheme。 您不能提供足够的信息来诊断问题(您告诉我们页脚没有工作,但是您不会告诉我们您的约束条件最终放在哪里)。 如果你执行上述命令,你可以精确地确定你的约束最终放置你的页脚,然后找出如何解决这个问题。

请注意,您将看到我的headerViewfooterView在这两个列表中显示为HeaderViewFooterView类而不是UIView 。 在诊断约束问题时,如果关键视图有它们自己的类,那么它是有用的,所以我定义了UIView子类而没有实现,但是如果我使用这些唯一的子类作为我的页眉和页脚视图,它将更容易解释结果以上(lldb)命令。

 @interface HeaderView : UIView @end @implementation HeaderView @end @interface FooterView : UIView @end @implementation FooterView @end