UIView transitionFromView:toView: 没有动画

Posted

技术标签:

【中文标题】UIView transitionFromView:toView: 没有动画【英文标题】:UIView transitionFromView:toView: isn't animating 【发布时间】:2012-03-27 18:46:57 【问题描述】:

我正在尝试为众多子视图中的一个特定子视图制作过渡动画。最初,当我尝试执行 transitionFromView:toView: 时,它会为整个 superView 设置动画,这不是我想要的。我只希望特定的子视图动画。所以我搜索并找到了这个:Transition behavior using transitionFromView and 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 移到了一个私有方法中,并且只在视图大小发生变化时调用它。现在一切正常。 :)

【问题讨论】:

【参考方案1】:

你放在那里的代码没有错误,我唯一能想到的就是你在其他地方有问题。您确定您的容器视图会转到您显示的视图吗?

你用什么方法调用它?

因为要制作动画,您需要做的事情如下所示(并且从您在此处发布的代码中您正在执行此操作):

UIView* normalView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
[normalView setBackgroundColor:[UIColor redColor]];
UIView* selectedView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
[selectedView setBackgroundColor:[UIColor blueColor]];

UIView* container = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[container setBackgroundColor:[UIColor grayColor]];

[container addSubview:selectedView];
[self.view addSubview:container];

然后调用方法进行翻转。

[UIView transitionFromView:selectedView toView:normalView duration:2.0 options:UIViewAnimationOptionTransitionFlipFromRight completion:^(BOOL fin)];

【讨论】:

好吧,所有对象都已正确初始化(我将把它添加到我的问题中)。你提到了self.view,但这段代码在 UIView 子类中,所以它只是self。容器是否需要是self 的直接子视图,因为它代表普通超级视图(selectedView.superview)是self 的直接子视图,但容器不是(它是self 子视图的子视图)。 不...没关系。我尝试将容器设置为 self 的子视图,但我得到了相同的行为。 对不起@AaronHayman,但需要更多信息才能帮助您。就像你在哪里打电话一样。你看到过渡了吗?因为在 viewDidLoad 例如你可以看到动画。在流程结束时,您看到的是普通视图还是选定视图?它们在没有动画的情况下改变还是不改变? 啊,是的,抱歉我没说清楚。是的,发生了过渡,但没有动画。所以最后,我看到了我应该看到的正常视图。运行此代码以响应 UITapGestureRecognizer。但是这些视图都不是 UINavigationController 的一部分。这个特定的动画过渡本质上是“取消选择”先前的选择,而另一个标准动画(不是过渡动画)对所点击的视图的选择进行动画处理。非常简单,除了过渡动画外,一切正常。 我之前的评论是错误的,正确的是:因为在 viewDidLoad 例如你看不到动画。您正在做的事情是阻止您的动画,例如将其放入 viewController 的 viewDidLoad 中,但我不知道如何为您提供更多帮助,抱歉。 =/

以上是关于UIView transitionFromView:toView: 没有动画的主要内容,如果未能解决你的问题,请参考以下文章

UIView transitionFromView 在容器中没有动画

+[UIView transitionFromView:toView:...] 有多个视图

UIView 过渡动画

使用 transitionFromView:toView:duration:options:completion 但使用 addSubview 时,电影没有在横向模式下正确显示

自定义动画

如何在容器(UIView)内居中对齐 2 个 UIView,而不将它们放在 UIView 内