我继承了 UIView。它的一些子视图是动画的。重新启动这些的正确方法是啥?

Posted

技术标签:

【中文标题】我继承了 UIView。它的一些子视图是动画的。重新启动这些的正确方法是啥?【英文标题】:I subclassed UIView. Some of its subviews are animated. What's the correct way to restart these?我继承了 UIView。它的一些子视图是动画的。重新启动这些的正确方法是什么? 【发布时间】:2013-03-23 00:52:40 【问题描述】:

好的,所以我对 UIView 进行了子类化,并且视图有一堆子视图。这些子视图是动画的。当我将另一个视图控制器推到顶部时,或者应用程序进入后台时,动画停止。

在我的子视图中重新启动这些动画的正确方法是什么。我不想让 View Controller 告诉 View 重新启动它们,因为我觉得 View 应该知道何时需要重新启动,而无需另一个对象明确告知。

但我不能在子类 UIView 上使用 layoutSubviews,因为正在发生的动画正在添加新的 UIImageViews。发生这种情况时,会在 UIView 子类上调用 layoutSubviews。所以 layoutSubviews 被调用了很多,我不能用它来重新启动动画。

想法?

更新 - 动画代码看起来像这样......但我认为这并不重要。

[UIView animateWithDuration:ANIMATION_DURATION delay:0 options:UIViewAnimationOptionCurveLinear     animations:^
    [subview setFrame:finalFrame];
 completion:^(BOOL finished) 
    [subview removeFromSuperview];
];

【问题讨论】:

你能发布一些代码来说明你的问题吗?具体来说,你是如何制作动画的(可能是 +[UIView animate...] 调用?),你的 -layoutSubviews 究竟做了什么? 您可以通过 view.superview != nil 检查视图是否可见并开始您的动画。 视图总是有一个超级视图。我想要一种优雅的方式来触发重启。 【参考方案1】:

使用 NSNotificationCenter 通知视图视图控制器再次出现,如下所示:

在你的 UIView 中,在 init 方法中添加这个:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(methodToExecuteWhenUIViewControllerComesBackUp:) name:@"Came Back" object:nil];

然后在您的“其他 viewController”中,在您再次展示原始控制器的方法中,添加:

[[NSNotificationCenter defaultCenter] postNotificationName:@"Came Back" object:nil];

然后,当您返回原始 viewController 时,您的 UIView 将收到通知。为每个要重新设置动画的子视图重复第一段代码。

当任何子视图被删除(释放)内存时,请确保执行:

[[NSNotificationCenter defaultCenter] removeObserver:self];

如果上面的代码没有执行,通知中心会尝试通知一个不再存在的对象,导致你的应用崩溃。

【讨论】:

我可以做这样的事情,但我真的不想把这段代码放在视图控制器中。我觉得视图应该能够根据需要自行重置。明白我的意思吗? 我明白了,但是UIView的不是简单地“知道”什么时候重新激活...这段代码比较轻量级,我真的不明白为什么你不能插入代码,告诉我是不是特定的原因。 是的,我可能会使用这样的东西。我希望有一种优雅的方式。感觉并不优雅,因为我需要在视图上公开一个方法来重新启动动画并从视图控制器中的 2 个位置调用它。然后当我在任何其他地方使用这个视图时,我需要做同样的事情。我当然可以,只是似乎有更好的方法。 layoutSubviews 几乎可以工作......除了动画的一部分正在添加新的子视图,这会触发 layoutSubviews。所以我不能。哦,好吧,也许我现在就安顿下来继续前进。【参考方案2】:

不要使用UIView Animation,最好使用Core Animation

CAAnimation 中,它有一个名为removedOnCompletion 的属性,默认为YES,将其设置为NO(yourCAAnimation.removedOnCompletion = NO;),它将使您的应用从background 变为foreground,动画也为@987654330 @

苹果说:

removedOnCompletion

Determines if the animation is removed from the target layer’s animations upon completion.

@property(getter=isRemovedOnCompletion) BOOL removedOnCompletion
Discussion
When YES, the animation is removed from the target layer’s animations once its active duration has passed. Defaults to YES.

Availability
Available in ios 2.0 and later.
Related Sample Code
MoveMe
Declared In
CAAnimation.h

【讨论】:

听起来removedOnCompletion 对我没有帮助。动画在视图离开前景时停止,而不是在它们完成时停止。虽然他们当时也这样做。这似乎对我没有帮助。

以上是关于我继承了 UIView。它的一些子视图是动画的。重新启动这些的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

iPhone UIView 动画禁用 UIButton 子视图

用动画重绘 UIView

用动画调整 UIView 的大小,子视图不会动画

动画 UIView 的子视图在动画期间不保持约束

CALayer 详解

同时动画两个 UIView 子视图不起作用