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

时间:2016-02-25 10:37:26

标签: ios objective-c autolayout storyboard scrollview

-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高度达到内容需要的高度时,正确的方法是怎样的?

8 个答案:

答案 0 :(得分:124)

每次使用带有自动布局的ScrollView时,请始终按照以下步骤进行操作

  1. ScrollView约束:leadingSpace,topSpace,TrailingSpace,bottomSpace到superView并确保当你控制拖动以添加约束时通过按alt添加它以便约束将被设置为无边距。

  2. 在滚动视图中添加UIView作为内容视图并设置其约束: leadingSpace,topSpace,trailingSpace,bottomSpace to ScrollView,无需按alt键并将equalWidth设置为ScrollView。

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

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

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

    ScrollView约束:

    enter image description here

    ContainerView约束:

    enter image description here

答案 1 :(得分:4)

Xcode 11

我已经关注了好几个小时的教程,但似乎都没有用。似乎Xcode 11进行了一些更新,更改了滚动视图与自动布局的工作方式。

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

    I found an excellent tutorial at this link.

答案 2 :(得分:2)

  1. 选择您的视图控制器
  2. 取消选中'调整滚动视图插播'
  3. enter image description here

答案 3 :(得分:1)

它会起作用

-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

答案 4 :(得分:1)

Bharat Modi的答案几乎解决了这个问题,但我(Xcode 8.3.2,iOS 10 SDK)也必须将内容视图的高度和宽度与UIScrollView的高度和宽度相匹配。

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

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

这就是我所拥有的:

UIScrollView in IB without warnings

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

我尝试使用滚动视图,内容视图和另一个固定宽度和高度的虚拟视图来模拟内容,但似乎没有任何东西让IB感到高兴。

(对不起,我没有足够的代表将此作为对原始答案的评论)。

更新:

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

self.uiContentViewHeightConstraint.constant = mapViewBottomY + 15

一切正常。这里的关键基本上是当滚动视图中有一个视图时 - 该视图定义滚动视图的内容大小。正如人们之前提到的,内容视图的大小必须在构建时完全定义,以便IB快乐。您可以在运行时通过插座自由操纵值 - 这很容易且安全。

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

答案 5 :(得分:1)

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

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

答案 6 :(得分:0)

使用scrollview的内容视图设置标签左上角和下边距约束,并将UILable的行数设置为0.它将根据内容的大小扩展内容视图

enter image description here

答案 7 :(得分:0)

一个小技巧-如果您有内部带有UITextView的UIScrollView 抱怨:

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

只需在IB中的UITextView上取消选中默认的“ Scrolling Enabled”即可。的工作原理就像魔术:) enter image description here