Ios 使用自动布局将动态大小的视图(高度)添加到UIScrollView
以下是我的详细视图视图结构(博客应用程序,我想查看整个文章,它在滚动视图中具有动态高度): 通常,要向UIView添加“单个post视图”,我只需实例化它,将其提供给我的post对象,然后添加一个约束,将单个PostView的宽度固定到superview,在这一点上可以很好地进行布局。但是,当我尝试将它添加到滚动视图时,它不会显示,也不会滚动Ios 使用自动布局将动态大小的视图(高度)添加到UIScrollView,ios,objective-c,uiscrollview,autolayout,Ios,Objective C,Uiscrollview,Autolayout,以下是我的详细视图视图结构(博客应用程序,我想查看整个文章,它在滚动视图中具有动态高度): 通常,要向UIView添加“单个post视图”,我只需实例化它,将其提供给我的post对象,然后添加一个约束,将单个PostView的宽度固定到superview,在这一点上可以很好地进行布局。但是,当我尝试将它添加到滚动视图时,它不会显示,也不会滚动 UIScrollView *scrollView = [[UIScrollView alloc] init]; [self.view addSubview
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]];
在自动布局中
scrollview
的帧由scrollview
的scrollview
和superview
之间的约束决定。
scrollview
的contentSize
由scrollview
和scrollview
的subview
之间的约束决定
您应该设置singlePostView
的大小<代码>滚动视图从中计算contentSize
。(需要明确添加尺寸约束)
在您使用AutoLayout呈现的结构中,
UIScrollView
的contentSize
由其子视图的intrinsicContentSize
驱动,这里是您的SinglePostView
问题是,SinglePostView
作为UIView
的一个子类,其intrinsicContentSize
在单独考虑时总是CGSizeZero
。您需要做的是使SinglePostView
的intrinsicContentSize
依赖于其子视图的intrinsicContentSize
然后,由于SinglePostView
的子视图是UILabel
,并且UILabel
的intrinsicContentSize
是显示其内容所需的最小大小,您的SinglePostView
的intrinsicContentSize
将等于其子视图intrinsicContentSize
的总和,即显示所有三个标签内容所需的总大小
下面是如何做到这一点
步骤1:删除所有自动设置的约束
首先,正如部分操作一样,您需要删除系统自动设置的所有约束
假设您的故事板或XIB中没有设置任何约束(或者您甚至没有这些约束之一),只需执行以下操作:
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
singlePost.translatesAutoresizingMaskIntoConstraints = NO;
titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
subtitleLabel.translatesAutoresizingMaskIntoConstraints = NO;
contentLabel.translatesAutoresizingMaskIntoConstraints = NO;
现在,您有了一个清晰的计划,可以开始设置自己的约束
步骤2:约束滚动视图
首先,让我们像您一样创建视图引用字典,以便AutoLayout使用:
NSDictionary *views = NSDictionaryOfVariableBindings(scrollView, singlePost, titleLabel, subtitleLabel, contentLabel);
然后,正如您已经做的那样,让我们将滚动视图约束为其superview的大小:
[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]];
步骤3:约束SinglePostView
以推送scrollView
的contentSize
为了明确这一步,您必须了解在UIScrollView
及其子视图之间设置的每个约束实际上会更改UIScrollView
的contentSize
,而不是其实际的边界。例如,如果将UIImageView
约束到其父级UIScrollView
的边框,然后将一个大小为UIScrollView
两倍的图像放在UIImageView
内,则图像不会缩小,它是UIImageView
,它将采用图像的大小,并在UIScrollView
中可滚动
下面是您必须在这里设置的内容:
[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
设置为与滚动视图的相同。这样,您可以防止滚动视图的contentSize.width
超出其界限.width
步骤4:约束您的ui标签
以“推”您的SinglePostView的边界
第四步也是最后一步,您现在需要在SinglePostView
的子视图上设置约束,以便它从中获得intrinsicContentSize
下面是您的操作方法(最简单的实现,没有边距,一个标签接一个标签):
这样你就完了
最后一个建议是,要做这类事情,您一定要研究UIStoryboard
。它更简单、更直观
希望这有帮助
注:如果你愿意,我可以花点时间,在Github上使用UIStoryboard
和可视格式语言
来推动一个项目。告诉我你是否需要一个
祝你好运。如果在屏幕上显示singlePostView之前我不知道它的高度怎么办?您是说我需要手动计算高度本身(使用NSString+图像高度方法)?这似乎与自动布局的用途完全相反,如果内容视图具有固有大小(如UIImageView),则无需这样做。但如果不是,我认为内容大小需要计算。我将进行更多测试,以找出更好的解决方案。如果你已经找到了,请告诉我谢谢你的精彩描述。第3步,确保contentsize的宽度有界是缺失的link@Msencenb如果在iPhone4S上scrollView的高度缩小(宽度相同),该怎么办?我的结构与此相同,在ScrollView上有五个大小相同的UIView。用户只能水平滚动。它在iphone5、iphone6和iphone6plus上都能完美工作。然而,在iPhone4上,当scrollView的高度缩小(由于内容拥抱和内容抵制而故意缩小)时,我的UIView就不适合了。我必须垂直向下滚动才能看到整个图片,但这不是我想要的。我已经
[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]];
[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]];
[singlePost addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[titleLabel]-0-|" options:0 metrics:0 views:views]];
[singlePost addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[subtitleLabel]-0-|" options:0 metrics:0 views:views]];
[singlePost addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[contentLabel]-0-|" options:0 metrics:0 views:views]];
[singlePost addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[titleLabel]-0-[subtitleLabel]-[contentLabel]-0-|" options:0 metrics:0 views:views]];