在iOS8/Xcode 6预览版中,使用UIScrollview和autolayout似乎无法正常工作?

8
以下是UIScrollView + autolayout的步骤,这些步骤对我有效,但在iOS8 / Xcode 6预览版中无效(使用故事板,启用大小类):
  1. 将滚动视图添加到根视图。
  2. 将零间距固定到所有超级视图的边缘。
  3. 将UIView(contentView)添加到上面的滚动视图中。
  4. 将零间距固定到滚动视图的所有边缘
  5. 向contentView添加一些小部件并将contentView的高度更改为2000。
=> 在iOS 7中,此contentView可以滚动,但我无法在iOS 8预览版中使相同的步骤起作用。
即使在iOS 7中似乎有效,也可能我没有按照正确的方式进行? 有什么建议吗?

Matt说对了两次。我刚刚检查了Xcode 6 beta 6,现在一切都正常工作了。也许我应该删除整个帖子,以免混淆任何人(我不知道如何操作)。至少,我只是想在这里放一个注释,以便我们知道这不再是一个问题。 - Sean
2个回答

7
我很惊讶没有看到更多关于这个的评论。在iOS 8中,滚动视图内部自动布局很大程度上已经失效(截至本文撰写时)。
编辑:在第5个种子版本中进行了修复,因此应忽略这个提醒!
据说规则是(请参见https://developer.apple.com/library/prerelease/ios/technotes/tn2154/_index.html),如果滚动视图的内容(其子视图或子视图)与滚动视图的全部四个边界对齐,则设置内容大小。
但在iOS 8中,仅当确定子视图高度和宽度的约束全部为绝对值而不是内在值时,该规则才会失败。
因此,例如,请考虑那篇技术说明底部的代码,在其中通过代码创建了一个滚动视图和一个真正巨大的图像视图(以下是代码;我已校正了一个小错误,一个 @ 符号被省略了)。
- (void)viewDidLoad {
    UIScrollView *scrollView;
    UIImageView *imageView;
    NSDictionary *viewsDictionary;
    // Create the scroll view and the image view.
    scrollView  = [[UIScrollView alloc] init];
    imageView = [[UIImageView alloc] init];
    // Add an image to the image view.
    [imageView setImage:[UIImage imageNamed:@"MyReallyBigImage"]];
    // Add the scroll view to our view.
    [self.view addSubview:scrollView];
    // Add the image view to the scroll view.
    [scrollView addSubview:imageView];
    // Set the translatesAutoresizingMaskIntoConstraints to NO so that the views
    // autoresizing mask is not translated into auto layout constraints.
    scrollView.translatesAutoresizingMaskIntoConstraints  = NO;
    imageView.translatesAutoresizingMaskIntoConstraints = NO;
    // Set the constraints for the scroll view and the image view.
    viewsDictionary = NSDictionaryOfVariableBindings(scrollView, imageView);
    [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:|[imageView]|" 
        options:0 metrics: 0 views:viewsDictionary]];
    [scrollView addConstraints:[NSLayoutConstraint 
        constraintsWithVisualFormat:@"V:|[imageView]|" 
        options:0 metrics: 0 views:viewsDictionary]];
}

那段代码是可行的(假设你有一个非常大的图片),因为图像视图是由内在约束大小的。但现在将最后两行改成这样:
    [scrollView addConstraints:[NSLayoutConstraint 
        constraintsWithVisualFormat:@"H:|[imageView(1000)]|" 
        options:0 metrics: 0 views:viewsDictionary]];
    [scrollView addConstraints:[NSLayoutConstraint 
        constraintsWithVisualFormat:@"V:|[imageView(1000)]|" 
        options:0 metrics: 0 views:viewsDictionary]];

现在您拥有的是一个可以在iOS 7上滚动但不能在iOS 8上滚动的滚动视图。进一步调查显示,这是因为内容大小仍为(0,0);它不遵循内容视图的绝对宽度和高度约束。

有其他人在Xcode 6 beta 5中遇到滚动视图无法显示的情况吗?如果记录附加到滚动视图的视图的子视图,则会列出它,但在模拟器中不会呈现。 - RyJ
@RyJ,听起来你可能犯了一些基本的约束错误。这是可能的吗?特别是,每当一个视图似乎没有显示出来时,请运行时检查是否存在模糊布局。此外,使用新奇的Xcode 6视图调试器!它会显示所有视图及其约束。确实,“记录子视图”已经过时了!那种东西早在2013年就过时了! :) - matt

0

UIScrollView + AutoLayout 的使用步骤如下:

  1. 将滚动视图添加到根视图中
  2. 在滚动视图上方添加包含视图

为滚动视图添加以下约束条件:

  1. 右侧间距等于父视图的间距 = 0
  2. 左侧间距等于父视图的间距 = 0
  3. 顶部间距等于父视图的间距 = 0
  4. 底部间距等于父视图的间距 = 0

为滚动视图的包含视图添加以下约束条件(在这种情况下,滚动视图是父视图):

  1. 右侧间距等于父视图的间距 = 0
  2. 左侧间距等于父视图的间距 = 0
  3. 顶部间距等于父视图的间距 = 0
  4. 底部间距等于父视图的间距 = 0
  5. 包含视图的高度(如果您正在使用垂直滚动),否则包含视图的宽度(如果您正在使用水平滚动)。
  6. 水平居中对齐(如果您正在使用垂直滚动),否则垂直居中对齐(如果您正在使用水平滚动)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接