iOS ScrollView 需要对 y 位置或高度进行约束
iOS ScrollView needs constraint for y position or height
-ViewController
--View
---ScrollView (Top,Bottom,Leading,Trailing spaces to superview set to 0)
----ContentView (Top,Bottom,Leading,Trailing spaces to superview set to 0, Width equals with View (ViewController's child))
-----Label1
-----etc...
如果我为我的内容视图设置一个特定的高度限制(例如 1000),ScrollView 工作正常,但我得到一个 1000 的静态 ContentView,这不是我的目标,因为我的 contentView 有动态内容,所以它应该是内容需要的高度。
如果我删除 ContentView 的高度限制,Xcode 表示:
Missing Constraints:
ScrollView need constraints for: Y position or height
ScrollView 实际上固定在顶部和底部,所以我不知道为什么 Xcode 想要 ScrollView 的高度限制...
当我希望 ContentView 高度成为内容所需的高度时,正确的方法是什么?
它会起作用
-ViewController
--View
---ScrollView (Top,Bottom,Leading,Trailing spaces to superview set to 0)
----ContentView (Top,Leading,Trailing spaces to ScorllView set to 0 | Height to dynamic (1000))
-----Label1
-----etc...
对你的 ContentView 做同样的事情,你自己计算你的内容
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
[self adjustHeightOfTableview];
}
- (void)adjustHeightOfTableview
{
CGFloat height = tblMainMenu.contentSize.height;
CGFloat maxHeight = tblMainMenu.superview.frame.size.height - tblMainMenu.frame.origin.y;
// if the height of the content is greater than the maxHeight of
// total space on the screen, limit the height to the size of the
// superview.
if (height > maxHeight)
height = maxHeight;
// now set the height constraint accordingly
self.tableViewHeightConstraint.constant = height;
[UIView animateWithDuration:0.1 animations:^{
[self.view setNeedsUpdateConstraints];
}];
}
编辑 1
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *OptName_length = @" Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam";
NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:17.0]};
CGRect rect = [OptName_length boundingRectWithSize:CGSizeMake(tableView.bounds.size.width-150.0, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil];
CGSize requiredSize = rect.size;
return requiredSize.height +5.0f;
}
编辑 2
检查站点,这将帮助您...
uitableviewcell-dynamic-height-with-autolayout-conclusion
使用滚动视图的内容视图设置标签左上右下边距约束,并将 UILable 的行数设置为 0。它将根据内容的大小扩展内容视图
每当使用带有自动布局的 ScrollView 时,请始终遵循以下步骤,
ScrollView constraints: leadingSpace, topSpace, TrailingSpace, bottomSpace to superView and sure when you control drag to add constraints, add it by press alt so that the constraint would be set without margin.
将滚动视图中的 UIView 添加为容器视图并设置其约束:
无需按 alt 按钮即可将 leadingSpace、topSpace、trailingSpace、bottomSpace 设置为 ScrollView,并将 equalWidth 设置为 ScrollView。
无论你在这个容器视图中添加什么视图,都必须有从上到下的约束,即所有视图都应该有垂直约束,这样 containerView 可以根据其中的内容计算自己需要的高度。
如果约束设置正确,scrollView 将根据其内部组件自动设置其内容大小,您无需手动设置内容大小,并且 scrollView 仅当组件位于容器内时才会滚动视图不适合内部,否则它不会滚动。如果你想让它滚动,那么你需要检查 Storyboard 中的 Bounces Vertically 属性 以获得反弹效果。
注意: 当你对scrollView内部的组件设置约束时,你会看到约束警告,直到你将约束从顶部组件设置到底部一,始终记住,您的顶部组件应该对 superView 具有顶部约束(垂直约束),而底部的组件应该对超级视图具有底部 space 约束。当这个满足时,所有警告最终都会消失。
ScrollView 约束:
ContainerView 约束:
Bharat Modi 的回答几乎解决了这个问题,但我(Xcode 8.3.2,iOS 10 SDK)还必须将内容视图的高度和宽度与 UIScrollView 的高度和宽度相匹配。
这会将内容大小固定到可见区域,但这让 IB 很高兴。然后(我认为)这只是正确计算内容大小并以编程方式设置它的问题。无论如何我都必须这样做,因为如果你有动态内容,你只能在 运行 时间这样做。
如果您有导航栏,您可能还需要调整视图控制器的 "Adjust scroll view insets" 设置。
这是我的:
请注意,这可能只是我设置的一个特点,因为官方建议 (https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithScrollViews.html) 也没有提到需要这样做。
我尝试仅使用滚动视图、内容视图和另一个固定宽度和高度的虚拟视图来模拟内容,但似乎没有什么能让 IB 满意。
(抱歉,我没有足够的代表将其作为对原始答案的评论)。
更新:
所以实际上我最终做的是在 IB 中将我的内容视图设置为固定高度,并在代码中为该高度限制创建一个出口。然后在视图加载其所有动态内容后,我只更新高度约束,如下所示:
self.uiContentViewHeightConstraint.constant = mapViewBottomY + 15
一切正常。这里的关键基本上是当滚动视图中有一个视图时——该视图定义滚动视图的内容大小。正如人们之前提到的,为了让 IB 满意,必须在构建时完全定义内容视图的大小。您可以在 运行 时间通过插座自由操纵这些值 - 这既简单又安全。
在 IB 中以固定大小设置内容视图的一个优点是,由于您已经固定了内容大小,现在可以使用相对偏移照常定义内容视图内的视图。
- Select 你的视图控制器
- 取消选中 'Adjust Scroll View Insets'
确保滚动视图中内容视图中最底部的元素将底部 space 约束设置为 0,并确保内容视图中的所有元素都设置了高度。
这会使内容视图根据其中的元素调整大小,并且您没有固定高度的滚动 view/content 视图,您的滚动视图将根据 phone 的屏幕尺寸调整大小。
如果您有 UIScrollView with UITextView inside 抱怨:
“ScrollView 需要对 y 位置或高度进行约束”。或“UIScrollView 可滚动内容大小歧义”
只需在 IB 的 UITextView 上取消选中默认的“启用滚动”。就像魔术一样工作:)
Xcode 11
几个小时以来,我一直在关注几个教程,其中 none 似乎有效。 Xcode 11 似乎有一些更新改变了滚动视图与自动布局的工作方式。
- 向视图添加
UIScrollView
并添加顶部、底部、前导和尾随约束。
- 在滚动视图中添加一个
UIView
。我们将其称为内容视图。
- 将内容视图的顶部、底部、前导和尾部约束添加到滚动
查看内容布局指南。将约束设置为 0。
- 在内容视图和滚动视图的框架布局指南之间添加等宽约束。 (不是滚动视图或主视图!)
- 暂时向内容视图添加高度限制,以便您可以添加内容。确保所有内容都有顶部、底部、前导和尾随约束。
删除内容视图的高度限制。
-ViewController
--View
---ScrollView (Top,Bottom,Leading,Trailing spaces to superview set to 0)
----ContentView (Top,Bottom,Leading,Trailing spaces to superview set to 0, Width equals with View (ViewController's child))
-----Label1
-----etc...
如果我为我的内容视图设置一个特定的高度限制(例如 1000),ScrollView 工作正常,但我得到一个 1000 的静态 ContentView,这不是我的目标,因为我的 contentView 有动态内容,所以它应该是内容需要的高度。
如果我删除 ContentView 的高度限制,Xcode 表示:
Missing Constraints:
ScrollView need constraints for: Y position or height
ScrollView 实际上固定在顶部和底部,所以我不知道为什么 Xcode 想要 ScrollView 的高度限制...
当我希望 ContentView 高度成为内容所需的高度时,正确的方法是什么?
它会起作用
-ViewController
--View
---ScrollView (Top,Bottom,Leading,Trailing spaces to superview set to 0)
----ContentView (Top,Leading,Trailing spaces to ScorllView set to 0 | Height to dynamic (1000))
-----Label1
-----etc...
对你的 ContentView 做同样的事情,你自己计算你的内容
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
[self adjustHeightOfTableview];
}
- (void)adjustHeightOfTableview
{
CGFloat height = tblMainMenu.contentSize.height;
CGFloat maxHeight = tblMainMenu.superview.frame.size.height - tblMainMenu.frame.origin.y;
// if the height of the content is greater than the maxHeight of
// total space on the screen, limit the height to the size of the
// superview.
if (height > maxHeight)
height = maxHeight;
// now set the height constraint accordingly
self.tableViewHeightConstraint.constant = height;
[UIView animateWithDuration:0.1 animations:^{
[self.view setNeedsUpdateConstraints];
}];
}
编辑 1
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *OptName_length = @" Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam";
NSDictionary *attributes = @{NSFontAttributeName: [UIFont systemFontOfSize:17.0]};
CGRect rect = [OptName_length boundingRectWithSize:CGSizeMake(tableView.bounds.size.width-150.0, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil];
CGSize requiredSize = rect.size;
return requiredSize.height +5.0f;
}
编辑 2
检查站点,这将帮助您... uitableviewcell-dynamic-height-with-autolayout-conclusion
使用滚动视图的内容视图设置标签左上右下边距约束,并将 UILable 的行数设置为 0。它将根据内容的大小扩展内容视图
每当使用带有自动布局的 ScrollView 时,请始终遵循以下步骤,
ScrollView constraints: leadingSpace, topSpace, TrailingSpace, bottomSpace to superView and sure when you control drag to add constraints, add it by press alt so that the constraint would be set without margin.
将滚动视图中的 UIView 添加为容器视图并设置其约束: 无需按 alt 按钮即可将 leadingSpace、topSpace、trailingSpace、bottomSpace 设置为 ScrollView,并将 equalWidth 设置为 ScrollView。
无论你在这个容器视图中添加什么视图,都必须有从上到下的约束,即所有视图都应该有垂直约束,这样 containerView 可以根据其中的内容计算自己需要的高度。
如果约束设置正确,scrollView 将根据其内部组件自动设置其内容大小,您无需手动设置内容大小,并且 scrollView 仅当组件位于容器内时才会滚动视图不适合内部,否则它不会滚动。如果你想让它滚动,那么你需要检查 Storyboard 中的 Bounces Vertically 属性 以获得反弹效果。
注意: 当你对scrollView内部的组件设置约束时,你会看到约束警告,直到你将约束从顶部组件设置到底部一,始终记住,您的顶部组件应该对 superView 具有顶部约束(垂直约束),而底部的组件应该对超级视图具有底部 space 约束。当这个满足时,所有警告最终都会消失。
ScrollView 约束:
ContainerView 约束:
Bharat Modi 的回答几乎解决了这个问题,但我(Xcode 8.3.2,iOS 10 SDK)还必须将内容视图的高度和宽度与 UIScrollView 的高度和宽度相匹配。
这会将内容大小固定到可见区域,但这让 IB 很高兴。然后(我认为)这只是正确计算内容大小并以编程方式设置它的问题。无论如何我都必须这样做,因为如果你有动态内容,你只能在 运行 时间这样做。
如果您有导航栏,您可能还需要调整视图控制器的 "Adjust scroll view insets" 设置。
这是我的:
请注意,这可能只是我设置的一个特点,因为官方建议 (https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithScrollViews.html) 也没有提到需要这样做。
我尝试仅使用滚动视图、内容视图和另一个固定宽度和高度的虚拟视图来模拟内容,但似乎没有什么能让 IB 满意。
(抱歉,我没有足够的代表将其作为对原始答案的评论)。
更新:
所以实际上我最终做的是在 IB 中将我的内容视图设置为固定高度,并在代码中为该高度限制创建一个出口。然后在视图加载其所有动态内容后,我只更新高度约束,如下所示:
self.uiContentViewHeightConstraint.constant = mapViewBottomY + 15
一切正常。这里的关键基本上是当滚动视图中有一个视图时——该视图定义滚动视图的内容大小。正如人们之前提到的,为了让 IB 满意,必须在构建时完全定义内容视图的大小。您可以在 运行 时间通过插座自由操纵这些值 - 这既简单又安全。
在 IB 中以固定大小设置内容视图的一个优点是,由于您已经固定了内容大小,现在可以使用相对偏移照常定义内容视图内的视图。
- Select 你的视图控制器
- 取消选中 'Adjust Scroll View Insets'
确保滚动视图中内容视图中最底部的元素将底部 space 约束设置为 0,并确保内容视图中的所有元素都设置了高度。
这会使内容视图根据其中的元素调整大小,并且您没有固定高度的滚动 view/content 视图,您的滚动视图将根据 phone 的屏幕尺寸调整大小。
如果您有 UIScrollView with UITextView inside 抱怨:
“ScrollView 需要对 y 位置或高度进行约束”。或“UIScrollView 可滚动内容大小歧义”
只需在 IB 的 UITextView 上取消选中默认的“启用滚动”。就像魔术一样工作:)
Xcode 11
几个小时以来,我一直在关注几个教程,其中 none 似乎有效。 Xcode 11 似乎有一些更新改变了滚动视图与自动布局的工作方式。
- 向视图添加
UIScrollView
并添加顶部、底部、前导和尾随约束。 - 在滚动视图中添加一个
UIView
。我们将其称为内容视图。 - 将内容视图的顶部、底部、前导和尾部约束添加到滚动 查看内容布局指南。将约束设置为 0。
- 在内容视图和滚动视图的框架布局指南之间添加等宽约束。 (不是滚动视图或主视图!)
- 暂时向内容视图添加高度限制,以便您可以添加内容。确保所有内容都有顶部、底部、前导和尾随约束。
删除内容视图的高度限制。