【问题标题】:Matching subview's width to it's superview using autolayout使用自动布局将子视图的宽度与其父视图匹配
【发布时间】:2013-08-22 21:22:48
【问题描述】:

目标:

使用自动布局约束,让UIWebView 的宽度与其父视图相同,即UIScrollView

代码

NSLayoutConstraint *makeWidthTheSameAsScrollView =[NSLayoutConstraint
                                                       constraintWithItem:self.questionWebView
                                                       attribute:NSLayoutAttributeWidth
                                                       relatedBy:0
                                                       toItem:self.masterScrollView
                                                       attribute:NSLayoutAttributeWidth
                                                       multiplier:1.0
                                                       constant:0];

[self.view addConstraint:makeWidthTheSameAsScrollView];

 NSLog(@"The width of questionWebView *AFTER* adding the constrain is: %f", self.questionWebView.frame.size.width);
 NSLog(@"The width of scrollView *AFTER* adding the constrain is: %f", self.masterScrollView.frame.size.width);

当前结果

当我记录self.questionWebViewUIWebView)的宽度时,应用自动布局约束时它的宽度不会改变。

问题

  • 这是正确的方法吗?
  • 我做错了什么?

p.s 我知道在 UIScrollView 中放置 UIWebView 是违反 Apple 的建议的,但是我已经关闭了使用属性 self.questionWebView.userInteractionEnabled = NO; 滚动 UIWebView 的功能。目前使用 UIWebView 是我显示 HTML 表格的最佳策略。

【问题讨论】:

    标签: ios uiwebview uiscrollview autolayout


    【解决方案1】:

    根据要求改进 Rob 的回答。

    正如 Rob 已经提到的,UIScrollViews 在自动布局下具有特殊的行为。

    在这种情况下有趣的是,scrollView 的总宽度是通过使用其子视图的总宽度来确定的。因此,虽然 scrollView 已经向 webView 询问其宽度,但您是在告诉 webView 也向 scrollView 询问其宽度。这就是为什么它不起作用。一个人在问另一个人,没有人知道答案。您需要另一个参考视图用作 webView 的约束,然后 scrollView 也将能够成功询问其预期宽度。

    一个简单的方法可以做到这一点:创建另一个视图,containerView,并将 scrollView 作为子视图添加到其中。然后为containerView 设置适当的约束。假设您希望 scrollView 以 viewController 为中心,边缘有一些填充。为containerView 这样做:

    NSDictionary *dict = NSDictionaryOfVariableBindings(containerView);
    [self.view addConstraints:[NSLayoutConstraints constraintsWithVisualFormat:@"H|-(100)-[containerView]-(100)-|" options:0 metrics:0 views:dict];
    [self.view addConstraints:[NSLayoutConstraints constraintsWithVisualFormat:@"V|-(100)-[containerView]-(100)-|" options:0 metrics:0 views:dict];
    

    然后您可以继续将 webView 作为子视图添加到 scrollView 并设置其宽度:

    NSLayoutConstraint *makeWidthTheSameAsScrollView =[NSLayoutConstraint
                                                           constraintWithItem:self.questionWebView
                                                           attribute:NSLayoutAttributeWidth
                                                           relatedBy:0
                                                           toItem:containerView
                                                           attribute:NSLayoutAttributeWidth
                                                           multiplier:1.0
                                                           constant:0];
    
    [self.view addConstraint:makeWidthTheSameAsScrollView];
    

    这将使滚动视图与 webView 一样大和高,并且它们都将按预期放置(在 containerView 上设置约束)。

    【讨论】:

    【解决方案2】:

    滚动视图与自动布局的交互方式有点奇怪。请参阅TN2154(UIScrollView 和自动布局)。

    另见UIScrollView doesn't use autolayout constraints

    一般来说,您需要以“滚动视图的当前宽度”以外的方式获取包含视图的宽度,因为在自动布局中,滚动视图的宽度(即内容宽度)是根据其内容定义的。因此,您当前的请求是循环的。

    【讨论】:

    • 一个简单的策略是将滚动视图作为子视图添加到另一个视图(布局就像滚动视图一样)并设置自动布局以使用此视图的宽度来设置 webView 之一。
    • @AlohaSilver 谢谢,请将此作为单独的答案添加,我认为将其作为答案而不是评论很有用。
    猜你喜欢
    • 1970-01-01
    • 2013-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多