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 时,请始终遵循以下步骤,

  1. 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.

  2. 将滚动视图中的 UIView 添加为容器视图并设置其约束: 无需按 alt 按钮即可将 leadingSpace、topSpace、trailingSpace、bottomSpace 设置为 ScrollView,并将 equalWidth 设置为 ScrollView。

  3. 无论你在这个容器视图中添加什么视图,都必须有从上到下的约束,即所有视图都应该有垂直约束,这样 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 中以固定大小设置内容视图的一个优点是,由于您已经固定了内容大小,现在可以使用相对偏移照常定义内容视图内的视图。

  1. Select 你的视图控制器
  2. 取消选中 'Adjust Scroll View Insets'

确保滚动视图中内容视图中最底部的元素将底部 space 约束设置为 0,并确保内容视图中的所有元素都设置了高度。

这会使内容视图根据其中的元素调整大小,并且您没有固定高度的滚动 view/content 视图,您的滚动视图将根据 phone 的屏幕尺寸调整大小。

如果您有 UIScrollView with UITextView inside 抱怨:

“ScrollView 需要对 y 位置或高度进行约束”。或“UIScrollView 可滚动内容大小歧义”

只需在 IB 的 UITextView 上取消选中默认的“启用滚动”。就像魔术一样工作:)

Xcode 11

几个小时以来,我一直在关注几个教程,其中 none 似乎有效。 Xcode 11 似乎有一些更新改变了滚动视图与自动布局的工作方式。

  1. 向视图添加 UIScrollView 并添加顶部、底部、前导和尾随约束。
  2. 在滚动视图中添加一个UIView。我们将其称为内容视图。
  3. 将内容视图的顶部、底部、前导和尾部约束添加到滚动 查看内容布局指南。将约束设置为 0。
  4. 内容视图滚动视图的框架布局指南之间添加等宽约束。 (不是滚动视图或主视图!)
  5. 暂时向内容视图添加高度限制,以便您可以添加内容。确保所有内容都有顶部、底部、前导和尾随约束。
  6. 删除内容视图的高度限制。

    I found an excellent tutorial at this link.