【问题标题】:Auto-Layout Issues: iOS 7 vs iOS8自动布局问题:iOS 7 与 iOS8
【发布时间】:2014-11-06 02:40:43
【问题描述】:

我正在尝试创建一个像这样工作的可折叠工具栏(在 iOS 7 中运行——用于可视化目的的丑陋颜色等):

但是,当我在 iOS 8 中运行代码时,会发生以下情况: 我已经建立了一个基于以下内容的约束系统:

centering view(未显示)将工具栏保持在屏幕中间。 sizing view 被调整为折叠工具栏。 sizing view 锚定在 centering view 的右侧(通过 trailing 约束)。 container view 保存工具栏的实际内容。它锚定在sizing view 的右侧(也通过trailing 约束)。 各种content views 包含在container view 中。他们没有任何限制。系统默认应用的约束应该是宽、高、顶、左,这样可以保证它们在container view中保持相对位置。

工具栏的折叠实现如下:

- (IBAction)showLess:(id)sender {
    self.widthConstraint.constant = 50; // adjust this number for collapse / expand
    [UIView animateWithDuration:0.3 animations:^{
        [self.centeringView layoutIfNeeded]; // trigger animation
    }];
}

调整sizing view的宽度。

问题: iOS 8 似乎表现得好像我已经锚定了内容视图,但事实并非如此。

衷心感谢:

  • 解释为什么 iOS 8 会对给定的(相当简单的)约束做出如此完全不同的解释。
  • 关于如何在 iOS 8 中获得预期行为的指针

Source code 可用 here(适用于 iOS 8 的更新版本)。

更新: Stack-overflow 的答案解决了这个问题。基本上,正确的答案是this,但它在this answer 中得到了很好的总结。 iOS7 和 iOS8 之间的区别不在于解释约束的方式,而在于更新命令通过视图层次结构向下传播的方式。 当我在 iOS 7 中首次实现该行为时,我注意到只有在 sizing view 的父视图(即 centering view)上调用 layoutIfNeeded 时,动画才能正常工作。在 iOS 7 中,这显然会自动降低视图层次结构。在 iOS 8 中,情况并非如此。您必须手动使约束已更改为setNeedsLayout 的视图无效,然后使用layoutIfNeeded 更新布局。我在更新代码中的解决方案如下所示:

- (IBAction)showLess:(id)sender {
    self.widthConstraint.constant = 50;
    [self.sizingView setNeedsLayout]; // *** THIS LINE IS NECESSARY TO MAKE THINGS WORK IN iOS 8
    [UIView animateWithDuration:0.3 animations:^{
        [self.sizingView layoutIfNeeded]; // trigger animation
    }];
}

我希望这可以帮助其他也被这个前向兼容性问题困扰的人。

【问题讨论】:

  • 我在我的一个应用中也看到了同样的情况。
  • 给这个问题添加一个正常的答案,并标记为答案。我来这里两次以为它​​没有修复,然后我阅读了更新。
  • 另外,考虑接受解决方案。

标签: ios autolayout constraints


【解决方案1】:

问题已通过 Stack-overflow 的答案得到解决。基本上,正确的答案是this,但它在this answer 中得到了很好的总结。 iOS7 和 iOS8 之间的区别不在于解释约束的方式,而在于更新命令通过视图层次结构向下传播的方式。当我在 iOS 7 中首次实现该行为时,我注意到只有在 sizing view 的父视图(即 centering view)上调用 layoutIfNeeded 时,动画才能正常工作。在 iOS 7 中,这显然会自动降低视图层次结构。在 iOS 8 中,情况不是:您必须手动使约束已更改为 setNeedsLayout 的视图无效,然后使用 layoutIfNeeded 更新布局。我在更新代码中的解决方案如下所示:

- (IBAction)showLess:(id)sender {
    self.widthConstraint.constant = 50;
    [self.sizingView setNeedsLayout]; // *** THIS LINE IS NECESSARY TO MAKE THINGS WORK IN iOS 8
    [UIView animateWithDuration:0.3 animations:^{
        [self.sizingView layoutIfNeeded]; // trigger animation
    }];
}

我已更新问题以包含答案,但作为对@unmircea 的回应,我也发布了单独的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-23
    • 1970-01-01
    • 1970-01-01
    • 2015-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多