使用自动布局将动态大小的视图(高度)添加到UIScrollView

时间:2014-07-24 08:20:33

标签: ios objective-c uiscrollview autolayout

这是我的详细视图的视图结构(博客应用程序,我想查看在scrollview中具有动态高度的整个帖子):

UIView
  -UIScrollView
    -SinglePostView (custom view)
      -Title
      -Subtitle
      -Content

通常会添加一个'单个帖子视图'到UIView我只是实例化它,将它提供给我的Post对象,然后添加一个约束,将singlePostView的宽度固定到superview,此时事情很好地布局。但是,当我尝试将其添加到滚动视图时,它不会显示,也不会滚动。

UIScrollView *scrollView = [[UIScrollView alloc] init];
[self.view addSubview:scrollView];

NOBSinglePostView *singlePost = [[NOBSinglePostView alloc] initWithPost:self.post];
[scrollView addSubview:singlePost];
singlePost.translatesAutoresizingMaskIntoConstraints = NO;
scrollView.translatesAutoresizingMaskIntoConstraints  = NO;

NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(scrollView,singlePost);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[singlePost]|" options:0 metrics: 0 views:viewsDictionary]];

2 个答案:

答案 0 :(得分:10)

在您展示的结构中,使用自动布局,contentSize的{​​{1}}由其子视图的UIScrollView驱动,此处为intrinsicContentSize

问题是,SinglePostViewSinglePostView的子类,其UIView在单独考虑时始终为intrinsicContentSize。您需要做的是让CGSizeZero的{​​{1}}取决于其子视图的intrinsicContentSize

然后,因为SinglePostView的子视图是intrinsicContentSize,并且因为SinglePostView的{​​{1}}是显示其内容所需的最小尺寸,所以{ {1}} UILabels将等于其子视图UILabel的总和,即显示所有三个标签内容所需的总大小。

以下是如何做到的。

步骤1:删除所有自动设置的约束

首先,正如您所做的那样,您需要删除系统自动设置的所有约束。

假设您没有在故事板或XIB中设置任何约束(或者您甚至没有其中任何一个),请执行以下操作:

intrinsicContentSize

现在你有一个清晰的平板,你可以开始设置自己的约束。

第2步:约束SinglePostView

首先,让我们像你一样创建AutoLayout使用的视图引用字典:

intrinsicContentSize

然后,就像你已经做的那样,让我们​​将滚动视图限制为其超级视图的大小:

intrinsicContentSizes

第3步:限制scrollView.translatesAutoresizingMaskIntoConstraints = NO; singlePost.translatesAutoresizingMaskIntoConstraints = NO; titleLabel.translatesAutoresizingMaskIntoConstraints = NO; subtitleLabel.translatesAutoresizingMaskIntoConstraints = NO; contentLabel.translatesAutoresizingMaskIntoConstraints = NO; 推送scrollView的{​​{1}}

要明确此步骤,您必须了解NSDictionary *views = NSDictionaryOfVariableBindings(scrollView, singlePost, titleLabel, subtitleLabel, contentLabel); 与其[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[scrollView]-0-|" options:0 metrics:0 views:views]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[scrollView]-0-|" options:0 metrics:0 views:views]]; 之间设置的每个约束实际上都会更改SinglePostView的{​​{1}},而不是它的实际scrollView。例如,如果您将contentSize约束到其父UIScrollView的边框,然后将图片的大小设置为subviewscontentSize的两倍,那么您的图片就会赢得' t缩小,UIScrollView将占用其图像的大小,并在bounds内可滚动。

所以这是你必须在这里设置的:

UIImageView

前两个约束非常明显。然而,第三个是因为,为了让你的UIScrollView正确地显示它们的内容并且仍然可读,你可能希望它们是多行的,滚动是垂直的而不是水平的。这就是为什么您将UIScrollView的{​​{1}}设置为与UIImageView相同的原因。这样,您就可以阻止UIImageView的{​​{1}}超过其UIScrollView

第4步:限制[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[singlePost]-0-|" options:0 metrics:0 views:views]]; [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[singlePost]-0-|" options:0 metrics:0 views:views]]; [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:singlePost attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0.0f]]; “推”UILabels

的范围

第四步也是最后一步,您现在需要在SinglePostView的子视图上设置约束,以便从中获取width

这是你如何做到的(最简单的实现,没有边距,一个标签在另一个垂直之后):

scrollView

然后你应该完成。

最后一条建议,你一定要考虑scrollView来做这些事情。它更简单,更直观。

希望这有帮助,

P.S。:如果您愿意,我可以花一些时间在Github上同时使用contentSize.widthbounds.width推送项目。告诉我你是否需要一个。

祝你好运。

答案 1 :(得分:0)

自动布局中的

scrollview的框架由scrollview的{​​{1}}和superview之间的约束决定。 scrollview的{​​{1}}由contentSize的{​​{1}}和scrollview之间的约束决定。

您应该设置scrollview的大小。 subview从中计算scrollview。 (您需要明确添加大小约束)

singlePostView