UIView动画没有动画改变价值事件

时间:2012-10-22 15:01:33

标签: objective-c ios animation uiview

我正在尝试隐藏或显示基于DCRoundSwitch对象的值的视图,但UIView动画块不是动画 - 立即应用更改。我还尝试使用CATransaction为视图的图层设置动画,但这些更改也会立即应用。如果将相同的动画块移动到另一个位置(例如,viewWillAppear :),则动画可以正常工作。

非常感谢任何有助于确定动画效果不起作用的帮助。谢谢!

这是动画代码:

- (void)switchValueChanged:(id)sender
{
    [UIView animateWithDuration:0.33
                     animations:^{
                         self.containerView.alpha = self.switchView.isOn ? 1 : 0;
                     }];
}

作为参考,这是DCRoundSwitch用于更改开关值的代码。 animatedYESignoreControlEventsNO

- (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];
    }];
}

3 个答案:

答案 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];
 }