UIView动画表现得很奇怪

时间:2015-08-03 07:34:41

标签: swift animation uiview swift2 ios9

我的视图控制器视图有一个子视图 - 一个“登录”面板,有两个输入文本字段 - 位于其中心,在Interface Builder中设置了自动布局约束。视图控制器类还有一个插座设置,用于引用垂直约束并在运行时对其进行操作。

在启动时 - viewDidLayoutSubviews() - ,我在属性(constraintInitialValue)中缓存垂直约束的值,计算一个值,该值将隐藏视图边界下的面板(基于面板的两个和视图的大小)并立即应用该值,在用户看到视图之前有效地隐藏面板。我还将这个计算出的“屏幕外”值限制在另一个属性(constraintOffscreenValue)中,以供以后使用(例如,“隐藏”面板)。

(我在viewDidLayoutSubviews()中进行了所有这些初始设置,因为它是第一次获得视图控制器视图的实际边界的机会。)

(对于记录,原始约束值为0.0:中心Y,无偏移。而且,对于iPhone 6和我面板的当前大小,“屏幕外值”为-453.0 。)

在后台,我对用户进行身份验证。如果失败,我将登录面板设置为原始位置(屏幕中心)。

到目前为止,非常好。

接下来,当用户输入他们的凭证并点击密码的返回密钥(最后一个输入字段)时,我执行一些本地验证(例如,字符串不为空)并通过将其设置为动画来“关闭”面板它的屏幕外位置。如果我使用以下代码执行此操作:

UIView.animateWithDuration(NSTimeInterval(0.3),
            delay:NSTimeInterval(0.0),
            options:UIViewAnimationOptions.CurveEaseOut,
            animations: { () -> Void in

                self.panelVerticalSpaceConstraint.constant = self.constraintOffscreenValue
                self.view.layoutIfNeeded()
            },
            completion: { (finished) -> Void in

            }
        )

viewDidLayoutSubviews()在动画期间被多次调用,但从第二次调用开始,我的代码就会立即返回。我上面提到的初始设置确实执行不止一次)

我的面板略微向上移动,然后同样向下移动,结束于屏幕中心(相反,它应该在最底部消失)。

如果我尝试将动画持续时间从0.3更改为10.0(以便正确了解正在发生的事情),相反,面板会快速“跳转”到几乎以上视图的上边缘,慢慢地动画回到中心。也就是说,如果没有发生初始跳转,我将获得所需的结果(移动到视图的底部)。

有什么建议吗?提前谢谢......

ADDENDUM:如果我不是试图向下设置面板动画,而是立即将约束设置为其屏幕外值,如下所示:

self.panelVerticalSpaceConstraint.constant = self.constraintOffscreenValue
self.view.layoutIfNeeded()

......它会立即消失,只会立即反弹到视图的中心! 动画来自哪里?约束是否以某种方式“抵制变革”?

1 个答案:

答案 0 :(得分:2)

好的,我找到了答案。对于一些奇怪的命运怪癖,我只能发现 向SO发帖提出错误(诅咒我一百万次!)。

事实证明,另一个单独的动画正在同时执行(因此,干扰)我的低于面板到屏幕底部的动画:

我碰巧有一个类似的动画,当键盘出现时调整面板的位置("躲开键盘"动画),当键盘被解除时再次向下调整,但是仅在发生实际重叠的设备(即较小的屏幕)上,通过检查键盘的尺寸(沿UIKeyboardWillShowNotification通知传递)与主视图和面板的尺寸。

我完全忘记了那个,因为我在iPhone 6模拟器上进行测试,屏幕尺寸仅导致最小的(几乎不可察觉但仍然存在)键盘重叠,因此面板调整动画。当我在 iPhone 6 + 模拟器上尝试代码时(因为没有发生重叠而完全跳过键盘闪避动画),问题完全消失,所有动画都按预期运行。

我的代码中不再需要此其他 restore-panel-duck--the-keyboard 动画,因为解除键盘的唯一方法是输入有效凭据并进行身份验证开始(将面板完全放下,屏幕外)。如果输入的凭据无法在服务器端进行身份验证,则该面板仅重新出现。