简体   繁体   English

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

[英]Autolayout confusion: Constraints for ScrollView with WebView and Header/Footer Views

To illustrate my problem, I created the following graphic: 为了说明我的问题,我创建了以下图形:

现在是3D

The black border around the red square is supposed to be the iPhone screen. 红色方块周围的黑色边框应该是iPhone屏幕。 Inside, we have in red a UIScrollView , which is taller than the screen. 在里面,我们有一个红色的UIScrollView ,它比屏幕更高。 It is, in fact, as tall as a UIWebView , displayed above in yellow. 事实上,它与UIWebView一样高,上面以黄色显示。 The UIWebView is a subview of the UIScrollView , with scrolling disabled. UIWebViewUIScrollView的子视图,禁用滚动。 Further more, we have two blue views, which I like to call the header and footer views. 此外,我们有两个蓝色视图,我喜欢称之为页眉和页脚视图。 They are also subviews of the UIScrollView , but outside of the scrollable bounds. 它们也是UIScrollView子视图,但在可滚动边界之外。

My problem now is : How do I configure the auto layout constraints for this? 我现在的问题是 :如何为此配置自动布局约束?

I have already managed to retrieved the UIWebView height using code from this answer and to then update the UIScrollView 's contentSize accordingly. 我已经设法使用此答案中的代码检索UIWebView高度,然后相应地更新UIScrollViewcontentSize However, this is not really a good solution, because the UIWebView 's width does not react to width changes of the UIScrollView . 但是,这不是一个很好的解决方案,因为UIWebView的宽度不会对UIScrollView宽度变化做出反应。

I also managed to setup the header view's layout constraints like so (using Masonary ): 我还设法设置了标题视图的布局约束(使用Masonary ):

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

However, setting up the footer view's layout like this didn't work: 但是,像这样设置页脚视图的布局不起作用:

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

I feel like this can't be too difficult and would appreciate some help from someone a bit more familiar with auto layout. 我觉得这不会太困难,并会感谢一些熟悉汽车布局的人的帮助。 Thanks! 谢谢!

In Visual Format Language (VFL), the constraints would be: 在可视格式语言(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]];

Or if you were going to replace the @"V:[footerView(100)]-(-100)-|" 或者如果你打算更换@"V:[footerView(100)]-(-100)-|" VFL with constraintWithItem calls, it would be: 使用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]];

I can't say why your Masonary implementation is not working, as I'm not familiar with it. 我不能说为什么你的Masonary实现不起作用,因为我不熟悉它。 But I'd try one of the above and make sure. 但我会尝试上面的一个并确保。

Frankly, you describe setting the height of the web view, and I wonder if you set the height constraint of the web view (good) or whether you just adjusted the frame.size.height value (bad). 坦率地说,您描述了设置Web视图的高度,我想知道您是否设置了Web视图的高度约束(好)或者您是否只调整了frame.size.height值(坏)。 But you haven't shared the details of how you set the web view's height, so I cannot comment further. 但是你还没有分享你如何设置网页视图高度的细节,所以我不能进一步评论。

Regardless, if you have constraint-based problems, there are two useful diagnostic techniques. 无论如何,如果您有基于约束的问题,有两种有用的诊断技术。 If it's still not working, I'd run the app on the simulator, pause it, and then at the (lldb) prompt enter: 如果它还没有工作,我会在模拟器上运行应用程序,暂停它,然后在(lldb)提示符处输入:

po [[UIWindow keyWindow] _autolayoutTrace]

You should see something like: 你应该看到类似的东西:

(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>

Make sure you don't have any warnings there. 确保那里没有任何警告。 If everything looks ok there, then I'd then use the following command at the (lldb) prompt: 如果一切看起来(lldb) ,那么我会在(lldb)提示符处使用以下命令:

po [[UIWindow keyWindow] recursiveDescription]

You should see something like: 你应该看到类似的东西:

(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>>

Take a look at your various resulting frame values and see what's going on. 查看各种结果frame值,看看发生了什么。 That can help you diagnose the solution. 这可以帮助您诊断解决方案。 You don't provide enough information for us to diagnose the problem (you tell us that the footer didn't work, but you don't tell us where your constraints ended up placing it). 您没有为我们提供足够的信息来诊断问题(您告诉我们页脚不起作用,但您没有告诉我们您的约束最终放在哪里)。 If you do the above commands, you can determine precisely where your constraint ended up placing your footer, and then figure out how to remedy the problem from there. 如果执行上述命令,则可以准确确定约束最终放置页脚的位置,然后找出如何从中解决问题。

Note, you'll see that my headerView and footerView are showing up in these two listings as HeaderView and FooterView classes instead of UIView . 注意,你会看到我的headerViewfooterView在这两个列表中显示为HeaderViewFooterView类而不是UIView When diagnosing constraint problems, it's useful if the key views have their own class, so I defined UIView subclasses with no implementation, but if I use those unique subclasses for my header and footer view, it makes it much easier to interpret the results of the above (lldb) commands. 在诊断约束问题时,如果关键视图有自己的类,那么我很有用,所以我定义了没有实现的UIView子类,但是如果我将这些唯一的子类用于我的页眉和页脚视图,那么它可以更容易地解释结果。上面(lldb)命令。

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM