我正在尝试隐藏或显示基于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];
}];
}
答案 0 :(得分:2)
谈到与@Matt的隐式事务让我思考... UIView的动画方法环绕CATransaction
,并且属性更改通常会添加到隐式事务中。但是,没有为完成块中所做的更改创建事务,这显然会影响[UIView animateWithDuration]
。我改变了
if (previousOn != on && !ignoreControlEvents)
[self sendActionsForControlEvents:UIControlEventValueChanged];
到
if (previousOn != on && !ignoreControlEvents)
{
[CATransaction begin];
[CATransaction setDisableActions:NO];
[self sendActionsForControlEvents:UIControlEventValueChanged];
[CATransaction commit];
}
它有效。 ([CATransaction setDisableActions:NO]
也是必要的)
感谢各位帮忙。
答案 1 :(得分:1)
我不知道在CATRaction的DCRoundSwitch代码中发生了什么,以及它是如何工作的。 但你可以试试这个:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.33];
self.containerView.alpha = self.switchView.isOn ? 1 : 0;
[UIView commitAnimations];
答案 2 :(得分:0)
我使用了上述奥斯汀解决方案。但无法修复它。
我使用了以下代码。这是正常的。
请跟进此主题
https://github.com/domesticcatsoftware/DCRoundSwitch/issues/12
你可以直接去使用这个DCRoundSwitch的Class,在该类的dealloc方法中放入这行。
- (void)dealloc
{
[self.MyDCRoundSwitch removeTarget:nil
action:NULL
forControlEvents:UIControlEventAllEvents];
[super dealloc];
}