我正在尝试为众多子视图中的一个特定子视图制作过渡动画。最初,当我尝试执行transitionFromView:toView:
它时,它会为整个 superView 设置动画,这不是我想要的。我只希望特定的子视图动画。所以我搜索并发现了这个:使用 transitionFromView 和 transitionWithView 的转换行为,它建议创建一个容器视图来执行动画。好的,很简单,所以我想出了这段代码:
UIView *container = [[UIView alloc] init];
container.frame = selected.frame;
selected.frame = container.bounds;
[selected.superview addSubview:container];
[container addSubview:selected];
[UIView transitionFromView:selected toView:normal duration:.2f options:UIViewAnimationOptionTransitionFlipFromLeft completion:^(BOOL fin){
normal.frame = container.frame;
[container.superview addSubview:normal];
[container removeFromSuperview];
}];
但现在我根本没有动画。我可能错过了一些简单的东西,但我找不到它。有任何想法吗?
更新
所有的值都被初始化。如果我在此代码块运行之前中断,我会通过调试器控制台将其拉出:
(gdb) po normal
<SLabel: 0x9c43150; frame = (0 0; 40 40); text = '28'; tag = 28; layer = <CALayer: 0x9c43190>>
(gdb) po selected
<SLabel: 0x9ca5f00; frame = (137 148; 45 37); text = '28'; tag = 28; layer = <CALayer: 0x9c596b0>>
(gdb) po [normal superview]
Can't print the description of a NIL object.
(gdb) po [selected superview]
<UIView: 0x9c4c890; frame = (0 0; 320 190); layer = <CALayer: 0x9c4c8c0>>
在代码运行到第 5 行之后(就在转换方法之前),我得到:
(gdb) po container
<UIView: 0x848bfc0; frame = (47 74; 45 37); layer = <CALayer: 0x9c32b10>>
(gdb) po [container superview]
<UIView: 0x9c4c890; frame = (0 0; 320 190); layer = <CALayer: 0x9c4c8c0>>
(gdb) po [selected superview]
<UIView: 0x848bfc0; frame = (47 74; 45 37); layer = <CALayer: 0x9c32b10>>
所以一切似乎都是正确的。容器放置在所选视图的位置(这是我要从其翻转的视图)。添加到所选视图的超级视图的容器。选定的视图被放置在容器内。最后运行过渡(之后进行清理)。但我仍然没有动画......过渡立即发生。
请注意,视图之间的转换是正确发生的。我根本没有动画。
另一个问题:为了执行动画,过渡视图是否必须是 UINavigationController 视图的子视图,无论多远?我从未见过像这样我记得的任何要求,但这是我的代码的一个非标准方面。如果您遵循每个视图的超级视图,则在导航控制器到达窗口之前不会成为导航控制器的一部分。有时 Apple 的框架以意想不到的方式相互依赖……我想知道这是否是其中之一。
最后的答案是我所有的代码都是正确的。正在发生的事情是layoutSubviews
在我开始动画之后被调用,它在动画甚至有机会开始之前重新布置了我的所有子视图。我不太清楚为什么它被称为。我没有从我的代码中调用它,所以我猜出于某种原因,我的移动视图触发 UIView 调用它。无论如何,我将我的代码移出layoutSubviews
一个私有方法,并且只在视图大小发生变化时调用它。现在一切正常。:)