2012-10-22 84 views
1

我試圖隱藏或顯示根據DCRoundSwitch對象的值的視圖,但是UIView的動畫塊不動畫 - 將立即應用更改。我也嘗試使用CATransaction爲視圖的圖層製作動畫,但這些更改也是即時應用的。如果同一個動畫塊被移動到另一個位置(比如viewWillAppear :),那麼動畫工作正常。的UIView動畫動畫沒有價值更改事件

任何幫助確定爲什麼動畫不能正常工作是極大的讚賞。謝謝!

這裏的動畫代碼:

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

此外:如果我用UISwitch替換DCRoundSwitch,動畫工作,所以它必須是關於交換機的動畫塊。有誰知道'CATransaction'有任何問題嗎? – Austin

+0

在任何人詢問之前,我不能在最終產品中使用'UISwitch',因爲'DCRoundSwitch'提供'UISwitch'不提供的定製選項。 – Austin

+0

我沒有看到你在最初的交易中致電[CATransaction begin]。然而......更可疑的是使用口罩。可疑的是,你正在嘗試製作一個alpha值,同時搞亂了一個面具。由於我無法確切知道你在做什麼,我不知道它是否會產生影響。一般來說(根據我的經驗):如果您在動畫塊內(或在此情況下與另一個動畫塊同時)直接或間接地對影響屬性(如alpha)的某些內容提供多個更改,... – Matt

回答

2

談到與@馬特隱含的交易讓我思考...的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]也是必要的)

謝謝你們的幫助。

+0

太棒了!很高興你想出來了。 – Matt

1

我不知道什麼發生在與CATransaction DCRoundSwitch代碼以及如何工作。 不過你可以試試這個:

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

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

[UIView commitAnimations]; 
+0

這應該提供與使用動畫塊相同的行爲,並且此格式不贊成使用動畫塊。一些默認設置已經改變(動畫曲線?),但是沒有任何東西會導致動畫不能根據不同的實現工作/工作。 – Matt

+0

感謝帖子,但@Matt是正確的;這有相同的結果。 – Austin

0

我已經使用上述奧斯汀溶液。但無法解決它。

我已經使用這個下面的代碼。哪些工作正常。

請跟進這個線程

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

U可以隨便去對正使用此DCRoundSwitch類,在把這個行類的dealloc方法。

- (void)dealloc 
{ 
     [self.MyDCRoundSwitch removeTarget:nil 
         action:NULL 
         forControlEvents:UIControlEventAllEvents]; 
     [super dealloc]; 
}