如何使用autolayout为视图设置动画更改视图层次结构?

时间:2013-04-24 18:14:36

标签: ios animation view subview

我有一个名为self.myMainView的超级视图

在该视图中,我有三个子视图:UIView * view1(绿色视图),UIView * view2(灰色视图),UIImageView * view3

我想动画移动视图3

当视图3完成此动画时,我想要更改视图层次结构,就像示例屏幕截图一样。

以下是示例图片:

before:

and after our manipulations it must be

3 个答案:

答案 0 :(得分:1)

您正在做的是更改视图分层顺序的常规标准方法。所以问题不是这个,而是用你的话说#34;但是,它违反了我的动画"和#34;压碎我的动画"。那么,问题在于你的动画,如果它可以被违反"并且"粉碎"通过重新排列图层。但是,在您的问题中,您没有提供有关动画的任何信息!然而,这显然是问题的核心。

编辑:既然您已经发布了动画代码,我就可以测试了,我看到了问题所在。问题是你正在使用autolayout。

view3由约束定位。当您为view3的位置设置动画时,您违反了这些限制,但这并不会立即显现出来。但是当您交换view1view2的分层顺序时,会执行布局!然后强制执行view3的约束。由于这些限制没有改变,我们会看到view3返回原来的位置。

最简单的解决方案是,如果您不需要,请关闭自动布局。否则,您必须在动画之后或作为动画的一部分更改约束。实际上,您可以通过设置其位置约束来重新定位view3。我在书中描述了这一切:http://www.apeth.com/iOSBook/ch17.html#_animation_and_autolayout

答案 1 :(得分:0)

如果您只想切换两个子视图中的哪一个,那么您可以简单地使用[UIView bringSubviewToFront:]而不是直接搞乱子视图阵列的顺序吗?这可能会解决动画问题。我要尝试的另一件事是在if( finished )的调用周围添加exchangeSubviewAtIndex,以确保它不会干扰其他动画视图。

答案 2 :(得分:0)

问题在于视图3的约束在动画之后不会改变,当我们想要操纵视图层次结构时,动画停止正常工作。马特在他的回答中说到了这一点,他也从他的伟大着作中提供了一个解决方案:http://www.apeth.com/iOSBook/ch17.html#_animation_and_autolayout 谢谢你,马特。

我稍微改变了这个解决方案,并决定在这里发布它给任何需要它的人。但是如果你想更好地理解这一点,我强烈建议你阅读关于动画的章节,链接在上面。

首先,我们需要为视图3的移动设置动画,然后更改我们的约束,并且只有在此更改视图层次结构之后。在书中找到了几种方法,但在我看来这是最好的方法:

layout = -35.0; //  new constraint constant of self.view3

NSArray *constraintsForAnimation = self.myMainView.constraints; // all constraints of superview 

NSUInteger indexOfconstraintsAttribute = [constraintsForAnimation
indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){ // get index of constraint of view 3

    NSLayoutConstraint *constraint = obj;


    return (([constraint.firstItem isEqual: self.view3])) ? idx : NO; // return this index if we found constraint of view 3

}];


constraint.constant = layout; // changing the constraint of view3 

[UIView animateWithDuration:0.3 animations:^{ // animation
   [self.view3 layoutIfNeeded]; // apply new constraints to view3
}];


[self.myMainView exchangeSubviewAtIndex:3 withSubviewAtIndex:4];// toggle view 1 with view 2

我们仅在约束的帮助下移动视图3,我们不设置框架或中心视图属性。 好的,我们完成了,这就像我想要的那样工作。希望这也对你有帮助。