8

我正在尝试在代码中生成视图。这是我的视图对象的层次结构

  • UIScrollView
    • 界面视图
      • 用户界面按钮

ScrollView 应该与窗口大小相同。按钮应尽可能大。我正在使用 iOS 自动布局,所以我所有对象的约束字符串看起来像这样

H:|[object]|
V:|[object]|

我还为每个对象设置translatesAutoresizingMaskIntoConstraints了。NO

问题是按钮只获得默认的按钮大小。它的父视图对象 (UIView) 仅获得其子视图所需的大小。

在此处输入图像描述

红色:UIScrollView / 黄色:UIView

如何强制这些视图与滚动视图一样大?

当我使用 UIView 而不是 UIScrollView 时,一切都很好......

这是一些代码:

    - (void) viewDidLoad {

        [super viewDidLoad];

        // SCROLL VIEW
        UIScrollView* scrollView = [UIScrollView new];
        scrollView.backgroundColor=[UIColor redColor];
        scrollView.translatesAutoresizingMaskIntoConstraints = NO;

        //CONTAINER VIEW
        UIView *containerView = [UIView new];
        containerView.translatesAutoresizingMaskIntoConstraints = NO;
        containerView.backgroundColor = [UIColor yellowColor];
        [scrollView addSubview:containerView];

        // CONSTRAINTS SCROLL VIEW - CONTAINER VIEW
        [scrollView addConstraints:
         [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[containerView]|"
                                                 options:0 metrics:nil
                                                   views:@{@"containerView":containerView}]];
        [scrollView addConstraints:
         [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[containerView]|"
                                                 options:0 metrics:nil
                                                   views:@{@"containerView":containerView}]];

        // BUTTON
        UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        button.translatesAutoresizingMaskIntoConstraints = NO;
        [button setTitle:@"I'm way to small" forState:UIControlStateNormal];
        [containerView addSubview:button];

        // CONSTRAINTS CONTAINER VIEW - BUTTON
        [containerView addConstraints:
         [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[button]|"
                                                 options:0 metrics:nil
                                                   views:@{@"button":button}]];
        [containerView addConstraints:
         [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[button]|"
                                                 options:0 metrics:nil
                                                   views:@{@"button":button}]];
        self.view = scrollView;

    }

更新: 我真的不知道,为什么会这样。如果您在 IB 中设置视图,连接插座并在代码中实例化视图,则滚动视图的行为类似于普通视图(垂直反弹)。它的 contentSize 计算不正确。更多在这里。但是如何正确地做到这一点?

4

1 回答 1

24

几点观察:

  1. 滚动视图中子视图的约束不像其他视图中的约束那样起作用。它们用于设置contentSize滚动视图。(请参阅TN2154。)这样,您将一堆东西扔到滚动视图上,为其中的东西设置约束,然后contentSize为您计算。这是一个非常酷的功能,但它与您在这里尝试做的事情背道而驰。

  2. 更糟糕的是,除非您为按钮的宽度和高度设置显式约束,否则按钮将根据其内容调整大小。

这两个观察结果的最终结果是您现有的约束说“(a)将我的容器设置为我的按钮的大小;(b)让我的按钮动态调整自身的大小以适应文本的大小;以及(c)设置我的contentSize根据我容器的大小(即按钮的大小)滚动视图。”

我不清楚业务问题是什么。但是这里有一些限制可以实现我认为您的技术问题是:

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIView *view = self.view;

    UIScrollView *scrollView = [[UIScrollView alloc] init];
    scrollView.backgroundColor = [UIColor redColor]; // just so I can see it
    scrollView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addSubview:scrollView];

    UIView *containerView = [[UIView alloc] init];
    containerView.backgroundColor = [UIColor yellowColor]; // just so I can see it
    containerView.translatesAutoresizingMaskIntoConstraints = NO;
    [scrollView addSubview:containerView];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    button.translatesAutoresizingMaskIntoConstraints = NO;
    [button setTitle:@"I'm the right size" forState:UIControlStateNormal];
    [containerView addSubview:button];

    NSDictionary *views = NSDictionaryOfVariableBindings(scrollView, button, view, containerView);

    // set the scrollview to be the size of the root view

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:views]];

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|"
                                                                      options:0
                                                                      metrics:nil
                                                                        views:views]];

    // set the container to the size of the main view, and simultaneously
    // set the scrollview's contentSize to match the size of the container

    [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[containerView(==view)]|"
                                                                       options:0
                                                                       metrics:nil
                                                                         views:views]];

    [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[containerView(==view)]|"
                                                                       options:0
                                                                       metrics:nil
                                                                         views:views]];

    // set the button size to be the size of the container view

    [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[button(==containerView)]"
                                                                          options:0
                                                                          metrics:nil
                                                                            views:views]];

    [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[button(==containerView)]"
                                                                          options:0
                                                                          metrics:nil
                                                                            views:views]];

}

坦率地说,我不了解您的 UI 的商业意图,因为这感觉像是为了实现非常简单的 UI 而对自动布局进行了扭曲。如果您有“屏幕大小”的内容(除非您通过按钮分页),我不知道为什么您有滚动视图。我不知道为什么你会有一个包含单个项目的内容视图。我不明白你为什么要使用全屏按钮(当时我只是在根视图上放了一个点击手势,然后就结束了)。

我假设你有充分的理由来做这一切,但备份可能是有意义的,询问你想要的用户体验是什么,然后重新解决问题,看看是否有更有效的方法来达到预期的效果.

于 2013-05-09T21:14:48.463 回答