iOS ScrollView 需要对 y 位置或高度进行约束

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35624873/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:35:44  来源:igfitidea点击:

iOS ScrollView needs constraint for y position or height

iosobjective-cautolayoutstoryboardscrollview

提问by Bioaim

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

If i set a specific height constraint for my content view (e.g. 1000) the ScrollView works fine, but i got a static ContentView of 1000, which is not my goal, because my contentView got dynamic content, so it should be the height the content needs.

如果我为我的内容视图(例如 1000)设置了特定的高度约束,则 ScrollView 工作正常,但是我得到了 1000 的静态 ContentView,这不是我的目标,因为我的 contentView 获得了动态内容,所以它应该是内容的高度需要。

If i delete the height constraint for my ContentView, Xcode says:

如果我删除了 ContentView 的高度约束,Xcode 会说:

Missing Constraints:
ScrollView need constraints for: Y position or height

ScrollView is actually pinned at top and bottom, so i don't know why Xcode want's a height constraint for the ScrollView...

ScrollView 实际上固定在顶部和底部,所以我不知道为什么 Xcode 想要 ScrollView 的高度约束...

What is the right way to go, when i want the ContentView height to be the height the content needs?

当我希望 ContentView 高度是内容需要的高度时,正确的方法是什么?

回答by Bharat Modi

Whenever using ScrollView with auto layout always follow below steps,

每当使用带有自动布局的 ScrollView 时,请始终遵循以下步骤,

  1. ScrollView constraints: leadingSpace, topSpace, TrailingSpace, bottomSpace to superView and make sure when you control drag to add constraint, add it by pressing alt so that the constraint would be set without margin.

  2. Add UIView inside scroll view as container view and set its constraints: leadingSpace, topSpace, trailingSpace, bottomSpace to ScrollView without pressing alt button and set equalWidth to ScrollView.

  3. Whatever views you add inside this container view must have top to bottom constraint that is all view's should have vertical constraint, so containerView can calculate height required for itself based on the content inside it.

  1. ScrollView 约束:leadingSpace、topSpace、TrailingSpace、bottomSpace 到superView 并确保当你控制拖动添加约束时,按alt 添加它,这样约束将被设置为没有边距。

  2. 在滚动视图中添加 UIView 作为容器视图并设置其约束:leadingSpace、topSpace、 trailingSpace、bottomSpace 到 ScrollView 而不按 alt 按钮,并将 equalWidth 设置为 ScrollView

  3. 您在此容器视图中添加的任何视图都必须具有从上到下的约束,即所有视图都应具有垂直约束,因此 containerView 可以根据其中的内容计算自身所需的高度。

If the constraints are set correctly then the scrollView will set its content size automatically based on the component inside it and you do not need to set the content size manually, also the scrollView will only scroll if the component inside the container view is not fitting inside otherwise it won't scroll. If you want to make it scroll anyways then you need to check the Bounces Vertically property from storyboard to get the bounce effect.

如果约束设置正确,则 scrollView 将根据其中的组件自动设置其内容大小,您无需手动设置内容大小,如果容器视图中的组件不适合内部,scrollView 只会滚动否则它不会滚动。如果你想让它滚动,那么你需要检查故事板中的 Bounces Vertically 属性以获得反弹效果。

Note:While you set constraint to the component inside the scrollView, you will see the constraint warning till you set the constraint from top component to the bottom one, aways remember that your top component should have top constraint (Vertical constraint) to superView and the component at the bottom should have bottom space constraint to the super view. When this satisfy then all warning will disappear eventually.

注意:当您在 scrollView 内为组件设置约束时,您将看到约束警告,直到您将约束从顶部组件设置为底部组件,请记住,您的顶部组件应该对 superView 具有顶部约束(垂直约束),并且底部的组件应该对超级视图具有底部空间约束。当这满足时,所有警告最终都会消失。

ScrollView constraints:

滚动视图约束:

enter image description here

在此处输入图片说明

ContainerView constraints:

ContainerView 约束:

enter image description here

在此处输入图片说明

回答by alicanozkara

  1. Select your view controller
  2. Uncheck 'Adjust Scroll View Insets'
  1. 选择您的视图控制器
  2. 取消选中“调整滚动视图插入”

enter image description here

在此处输入图片说明

回答by Babken Vardanyan

Make sure the bottommost element inside of your content view inside of your scroll view has bottom space constraint set to 0 and make sure all elements inside content view have height set.

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

This makes content view resize according to elements inside it and you don't have fixed height of your scroll view/content view and your scroll view will resize with phone's screen size.

这使得内容视图根据其中的元素调整大小,并且您的滚动视图/内容视图没有固定的高度,并且您的滚动视图将根据手机的屏幕大小调整大小。

回答by bkSwifty

Xcode 11

Xcode 11

I've been following several tutorials on this for a few hours now, and none of them seem to work. It seems that Xcode 11 has some updates that change how the scroll views work with auto layout.

几个小时以来,我一直在关注这方面的几个教程,但它们似乎都不起作用。Xcode 11 似乎有一些更新,可以改变滚动视图与自动布局的工作方式。

  1. Add a UIScrollViewto the view and add top, bottom, leading, and trailing constraints.
  2. Add a UIViewto the scroll view. We will call this the content view.
  3. Add top, bottom, leading, and trailing constraints from the content view to the scroll view's Content Layout Guide. Set the constraints to 0.
  4. Add an equal width constraint between the content viewand the scroll view's Frame Layout Guide. (Not the scroll view or the main view!)
  5. Temporarily add a height constraint to the content view so that you can add your content. Make sure that all content has top, bottom, leading, and trailing constraints.
  6. Delete the height constraint on the content view.

    I found an excellent tutorial at this link.

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

    我在这个链接上找到了一个很好的教程。

回答by Mohamed Jaleel Nazir

It will work

它会工作

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

Do same for your ContentView , Your Own Calculation for your Content

对你的 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];
}];
}

Edit 1

编辑 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;
    }

Edit 2

编辑 2

Check the site, this will help you... uitableviewcell-dynamic-height-with-autolayout-conclusion

检查站点,这将帮助您... uitableviewcell-dynamic-height-with-autolayout-conclusion

回答by denis.kim

Bharat Modi's answer pretty much solves the issue, but I (Xcode 8.3.2, iOS 10 SDK) also had to match the Content View's height and width to UIScrollView's height and width.

Bharat Modi 的回答几乎解决了这个问题,但我(Xcode 8.3.2,iOS 10 SDK)还必须将 Content View 的高度和宽度与 UIScrollView 的高度和宽度相匹配。

This will pin the content size to just visible area, but it makes IB happy. Then (I think) it's just a matter of calculating the content size correctly and setting it programmatically. Which I would've had to do anyway, since if you have dynamic content you can only do that at run time.

这会将内容大小固定到可见区域,但它让 IB 高兴。然后(我认为)这只是正确计算内容大小并以编程方式设置的问题。无论如何我都必须这样做,因为如果您有动态内容,则只能在运行时执行此操作。

You might also need to tweak the "Adjust scroll view insets" settings of the view controller if you have a navigation bar.

如果您有导航栏,您可能还需要调整视图控制器的“调整滚动视图插入”设置。

This is what I have:

这就是我所拥有的:

UIScrollView in IB without warnings

IB中的UIScrollView没有警告

Note that this could be just a peculiarity of my setup, because the official suggestions (https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithScrollViews.html) also don't mention that this needs to be done.

请注意,这可能只是我的设置的一个特点,因为官方建议(https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/WorkingwithScrollViews.html)也没有提到这一点需要完成。

I tried figuring this out using just a scroll view, a content view and another dummy view of fixed width and height to imitate the content, but nothing seemed to make IB happy.

我尝试仅使用滚动视图、内容视图和另一个固定宽度和高度的虚拟视图来模拟内容来解决这个问题,但似乎没有什么让 IB 高兴。

(Sorry, I don't have enough rep to put this as a comment on the original answer).

(抱歉,我没有足够的代表将其作为对原始答案的评论)。



UPDATE:

更新:

So actually what I ended up doing is setting my Content View to a fixed height in IB and creating an outlet for that height constraint in the code. Then after the view has loaded all of its dynamic content I just update the height constraint like so:

所以实际上我最终做的是在 IB 中将我的内容视图设置为固定高度,并在代码中为该高度约束创建一个出口。然后在视图加载所有动态内容后,我只需更新高度约束,如下所示:

self.uiContentViewHeightConstraint.constant = mapViewBottomY + 15

And everything works. The key here is basically that when there's a view inside a scroll view - that view defines scroll view's content size. As people have mentioned before, size of content view has to be fully defined at build time in order for IB to be happy. You are free to manipulate the values at run time though through outlets - it's easy and safe.

一切正常。这里的关键基本上是当滚动视图中有一个视图时 - 该视图定义了滚动视图的内容大小。正如人们之前提到的,内容视图的大小必须在构建时完全定义,以使 IB 满意。您可以在运行时通过出口自由操纵这些值 - 这既简单又安全。

One advantage of having the content view at fixed size in IB is that since you've fixed the content size, views inside the content view can now be defined as usual, using relative offsets.

在 IB 中使用固定大小的内容视图的一个优点是,由于您已经固定了内容大小,现在可以使用相对偏移量像往常一样定义内容视图内的视图。

回答by MuhammadTalhaSiddiqui

Set your label left top right and bottom margin constraint with content view of scrollview, and set number of line of UILable to 0. It will expand your content view as per the size of your content

使用滚动视图的内容视图设置标签左上右下边距约束,并将 UILable 的行数设置为 0。它将根据内容的大小扩展您的内容视图

enter image description here

在此处输入图片说明

回答by Vitya Shurapov

One little trick- if you have UIScrollView with UITextView insidecomplaining that:

一个小技巧 - 如果你有UIScrollView 和 UITextView 里面抱怨:

"ScrollView needs constraint for y position or height". Or "UIScrollView Scrollable Content Size Ambiguity"

“ScrollView 需要对 y 位置或高度进行约束”。或者“UIScrollView Scrollable Content Size Ambiguity”

Just uncheck default “Scrolling Enabled” on UITextView in the IB.Works like magic :) enter image description here

只需在 IB 中取消选中 UITextView 上的默认“启用滚动”。像魔术一样工作:) 在此处输入图片说明