1

DCRoundSwitchオブジェクトの値に基づいてビューを表示または非表示にしようとしていますが、UIViewアニメーションブロックがアニメーション化されていません。変更は即座に適用されます。また、CATransactionを使用してビューのレイヤーをアニメーション化しようとしましたが、それらの変更も即座に適用されました。同じアニメーションブロックを別の場所(たとえば、viewWillAppear :)に移動すると、アニメーションは正常に機能します。

アニメーションが機能しない理由を特定するための助けをいただければ幸いです。ありがとう!

アニメーションコードは次のとおりです。

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

参考までに、DCRoundSwitchがスイッチ値を変更するために使用するコードを次に示します。animatedでありYESignoreControlEventsです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];
    }];
}
4

3 に答える 3

2

@Mattで暗黙のトランザクションについて話すと、私は考えました... UIViewのanimateメソッドはラップアラウンドし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]また必要でした)

助けてくれてありがとう。

于 2012-10-22T19:29:38.057 に答える
1

CATransactionを使用したDCRoundSwitchコードで何が起こっているのか、そしてこれがどのように機能するのかわかりません。しかし、あなたはこれを試すことができます:

[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.33];

self.containerView.alpha = self.switchView.isOn ? 1 : 0;

[UIView commitAnimations];
于 2012-10-22T15:22:59.040 に答える
0

上記のオースティンソリューションを使用しました。しかし、それを修正することはできません。

私はこれを以下のコードで使用しました。これは正しく機能します。

このスレッドをフォローアップしてください

https://github.com/domesticcatsoftware/DCRoundSwitch/issues/12

Uは、このDCRoundSwitchを使用しているクラスに移動でき、そのクラスのdeallocメソッドにこの行を配置します。

 - (void)dealloc
 {
      [self.MyDCRoundSwitch removeTarget:nil
                         action:NULL
                         forControlEvents:UIControlEventAllEvents];
      [super dealloc];
 }
于 2013-03-22T13:44:27.043 に答える