【发布时间】:2012-10-22 15:01:33
【问题描述】:
我正在尝试根据 DCRoundSwitch 对象的值隐藏或显示视图,但 UIView 动画块没有动画 - 更改会立即应用。我还尝试使用 CATransaction 为视图层设置动画,但这些更改也立即应用了。如果将同一个动画块移动到另一个位置(例如 viewWillAppear:),动画效果很好。
非常感谢任何帮助确定动画无法正常工作的原因。谢谢!
这是动画代码:
- (void)switchValueChanged:(id)sender
{
[UIView animateWithDuration:0.33
animations:^{
self.containerView.alpha = self.switchView.isOn ? 1 : 0;
}];
}
作为参考,这里是 DCRoundSwitch 用于更改开关值的代码。 animated 是 YES 和 ignoreControlEvents 是 NO。
- (void)setOn:(BOOL)newOn animated:(BOOL)animated ignoreControlEvents:(BOOL)ignoreControlEvents
{
BOOL previousOn = self.on;
on = newOn;
ignoreTap = YES;
[CATransaction setAnimationDuration:0.014];
knobLayer.gripped = YES;
// setup by turning off the manual clipping of the toggleLayer and setting up a layer mask.
[self useLayerMasking];
[self positionLayersAndMask];
[CATransaction setCompletionBlock:^{
[CATransaction begin];
if (!animated)
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
else
[CATransaction setValue:(id)kCFBooleanFalse forKey:kCATransactionDisableActions];
CGFloat minToggleX = -toggleLayer.frame.size.width / 2.0 + toggleLayer.frame.size.height / 2.0;
CGFloat maxToggleX = -1;
if (self.on)
{
toggleLayer.frame = CGRectMake(maxToggleX,
toggleLayer.frame.origin.y,
toggleLayer.frame.size.width,
toggleLayer.frame.size.height);
}
else
{
toggleLayer.frame = CGRectMake(minToggleX,
toggleLayer.frame.origin.y,
toggleLayer.frame.size.width,
toggleLayer.frame.size.height);
}
if (!toggleLayer.mask)
{
[self useLayerMasking];
[toggleLayer setNeedsDisplay];
}
[self positionLayersAndMask];
knobLayer.gripped = NO;
[CATransaction setCompletionBlock:^{
[self removeLayerMask];
ignoreTap = NO;
// send the action here so it get's sent at the end of the animations
if (previousOn != on && !ignoreControlEvents)
[self sendActionsForControlEvents:UIControlEventValueChanged];
}];
[CATransaction commit];
}];
}
【问题讨论】:
-
另外:如果我用 UISwitch 替换 DCRoundSwitch,动画就会起作用,所以它必须与开关的动画块有关。有谁知道
CATransaction有什么问题吗? -
在有人问之前,我不能在最终产品中使用
UISwitch,因为DCRoundSwitch提供了UISwitch没有的自定义选项。 -
我看不到您是在初始事务中调用 [CATransaction begin] 还是提交。然而……更值得怀疑的是口罩的使用。从某种意义上说,您正在尝试为 alpha 值设置动画,同时弄乱蒙版,这是有问题的。由于我无法确切地看到你在用面具做什么,我不知道它是否会产生影响。一般来说(根据我的经验):如果您在动画块内(或在这种情况下与另一个动画块同时)对直接或间接影响属性(例如 alpha)的内容进行多项更改,...
-
(cont) 该属性的初始状态可能会在动画开始之前被覆盖。例如,在动画块中多次设置视图的帧可能会导致动画的初始帧成为间歇帧之一。在您的情况下,您可能正在使用蒙版操作视觉 alpha,或者如果使用图层蒙版(内部)实现实际 alpha。如果可以的话,我会尝试将 alpha 动画的功能与 setOn 动画结合起来,使动画块之间的属性更改不重叠。
-
初始事务中所做的更改被添加到隐式事务中,这就是没有调用
begin和commit的原因。图层/蒙版都是 DCRoundSwitch (github.com/domesticcatsoftware/DCRoundSwitch) 的一部分,它与容器共享父视图。对一个视图的掩码的更改不应该影响对同级的 alpha 的更改,不是吗?
标签: objective-c ios animation uiview