带iOS自动布局约束的UIScrollView:子视图的大小错误

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

  • UIScrollView中
    • 的UIView
      • 的UIButton

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

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

我也为每个对象设置了translatesAutoresizingMaskIntoConstraintsNO

问题是,button只获取默认的button大小。 它的父视图对象(UIView)只获取其子视图所需的大小。

在这里输入图像说明

红色:UIScrollView /黄色:UIView

我怎样才能强制这些意见像scrollView一样大?

当我使用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中设置视图,连接sockets并在代码中实例化视图,则滚动视图的行为与普通视图(垂直popup)的行为相同。 它的contentSize计算不正确。 更多在这里 。 但如何正确地做到这一点?

几点意见:

  1. 滚动视图中子视图的约束不像其他视图中的约束。 它们用于设置滚动视图的contentSize 。 (请参阅TN2154 。)这样,您就可以在滚动视图上添加一些内容,为其中的内容设置约束条件,并为您计算contentSize 。 这是非常酷的function,但这与你在这里要做的事情是对立的。

  2. 更糟的是,button将会,除非你设置一个明确的约束他们的宽度和高度的button,将根据他们的内容resize。

这两个观察的净效果是,你现有的约束条件是:“(a)将我的容器设置为我的button的大小;(b)让我的buttondynamic调整为文本的大小;(c)滚动视图的contentSize根据我的容器的大小(这是button的大小)。“

我不清楚业务问题是什么。 但是这里有一些约束条件可以达到我认为你的技术问题是:

 - (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]]; } 

坦率地说,我不明白你的用户界面的业务意图,因为这感觉就像自动布局的扭曲,以实现一个非常简单的用户界面。 我不知道为什么你有一个滚动视图,如果你有“屏幕大小”的内容(除非你是通过button分页)。 我不知道为什么你会有一个单一的项目的内容视图。 我不明白你为什么使用全屏button(我只是在当时的根视图上放一个轻按手势,并称它为一天)。

我假设你有充分的理由来做这些事情,但是备份可能是有意义的,询问你所期望的用户体验是什么,然后问题重新来看看是否有更有效的方法来达到预期的效果。