自动布局和动画

Auto layout and animation

在我的程序中,我有 14 个不同的按钮,每个按钮都有一个字母。每个按钮都通过自动布局相互连接。所以有很多疯狂的限制。请参阅第一张图片以获取解释:

但我希望能够通过 UIAnimation 来回移动每个按钮,而不会弄乱整个自动布局设置。请参阅第二张图片进行解释,我想做什么:

现在我目前用来获取这些动画的代码:

self.letterA.translatesAutoresizingMaskIntoConstraints = YES;
[UIView animateWithDuration:0.2 animations:^{
    [letterA setFrame:CGRectMake(x, y, width, height)];
}];

现在程序完美运行了!绝对没有任何问题!但唯一的 "problem" 是此代码在控制台中生成此消息:

Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. 
Try this: 
    (1) look at each constraint and try to figure out which you don't expect; 
    (2) find the code that added the unwanted constraint or constraints and fix it. 
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 

并且这个 warning/error/problem 一直持续数次,每次移动 UIButton。现在我该怎么办?

  1. 我可以忽略 Unable to simultaneously satisfy constraints 吗?或者这会在未来造成麻烦吗?
  2. 如果没有,如何解决?由于涉及大量的约束,如何在不编辑每个约束的情况下修复它?
  3. 我非常想使用 setFrame:
  4. 继续制作动画

如果您使用自动布局,则应将 translateAutoResizingMask 设置为 false,否则您将不断收到此错误。相反,您应该仅在动画块之前使用约束设置新位置,然后在动画块中调用 layoutIfNeeded。当您在界面生成器中设置约束时,会自动将 translateAutoResizingMaskToConstraints 设置为 false。

你的观点:

  1. "Can I ignore the Unable to simultaneously satisfy constraints warning" 不。忽略它是一个非常糟糕的主意,即使 UI 出现或多或少如您所愿,即使有警告也是如此。这意味着系统正在决定如何呈现您的布局,因为您提供的说明是矛盾的。它分析了您提供的约束,并找到了一种通过打破其中一个或多个约束来创建一致布局的方法。不能保证它会决定在不同的屏幕尺寸或 OS 版本上打破相同的限制。忽略此警告会大大增加 UI 错误的可能性。

  2. 我会重新考虑 UI 的整个设计方式。 IB/Storyboard 自动布局适用于 UI 达到一定复杂程度。这个 UI 看起来稍微超出了那个复杂程度 - 如果瓷砖不需要移动,那就没问题了。正如他们所做的那样,程序化自动布局可能会使事情变得更简单。 我将采取的方法如下。

    一个。创建一个 tile 对象,它公开 NSLayoutConstraint 属性用于顶部、左侧、宽度和高度约束。 (这些约束将添加到超级视图中,但也会存储在磁贴本身中)。

    b。使用工厂对象方法设置视图,将新图块的起始位置偏移量、宽度和高度作为参数。使用这些值独立地设置每个图块上的约束。根本不要将瓷砖彼此约束 - 所有约束都应该是内部的(宽度,高度)或相对于父视图(x,y)。这意味着当您对更改进行动画处理时,只有一个图块会受到影响。您实际上有更多约束,但它们在代码中,因此更易于管理。

    c).使用 UIView 动画四处移动图块并使用图块上的约束调整它们的大小。您可以存储每个图块位置的初始帧,并使用这些值来确定目标约束值。您应该能够轻松地以这种方式调整图块的位置和大小。

    d). Apple 的 API for NSLayoutConstraint 有点冗长和难看。考虑使用 Masonry,一种更好的自动布局 DSL,以保持您的代码整洁。

  3. 您可以继续使用 -setFrame:,只要您不使用 Autolayout - 这两种方法不能很好地结合使用。如果您希望您的应用在多个屏幕尺寸上 运行,您需要使用自动布局,或者重新计算每一帧并在代码中动态偏移。如果您不这样做(也许它是一个 iPad 应用程序并且您不关心专业版,那么只需使用 -setFrame:)。但是,总的来说,我建议硬着头皮学习 Autolayout