2011-06-26 114 views
2

現在,在你得到所有的螞蟻之前,這是可可我說的是,而不是可可觸摸。就這樣,讓我們​​開始吧。我最近開始爲Mac編程。爲什麼?因爲它很酷。你知道什麼不是很酷嗎?無法像其他酷炫的孩子一樣擁有漂亮的花式動畫。我無法弄清楚這一點,如果你能幫助我,你將挽救我留在我頭上的少數頭髮。CABasicAnimation不是動畫。幫幫我?

好的,我有一個NSCollectionView。花了我很多時間來弄清楚,但無論如何。我已經在界面生成器中對該層進行了NSCollectionView。我聽說這應該會讓這個神奇的工作。我想這對我的動畫集合視圖:

//usersView is my NSCollectionView 
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];  
CATransform3D scale = CATransform3DMakeScale(2.0, 2.0, 0.0); 
[anim setFromValue:[NSValue valueWithCATransform3D:CATransform3DIdentity]]; 
[anim setToValue:[NSValue valueWithCATransform3D:scale]]; 
[anim setDuration:1.0f]; 
[[usersView layer] addAnimation:anim forKey:nil]; 
[[usersView layer] setTransform:scale]; 

現在,這裏的交易:它變換的觀點,但不與酷動畫。我也試過這個:

[CATransaction begin]; 
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; 
[CATransaction setValue:[NSNumber numberWithFloat:3.0f] forKey:kCATransactionAnimationDuration]; 
[usersView layer].transform = CATransform3DMakeScale(2.0, 2.0, 0.0); 
[CATransaction commit]; 

沒有骰子。我確實相信我需要幫助。謝謝。

+0

「NSCollectionView」的超級視圖是否也支持層? –

+0

@Rob:通過superview,你的意思是包含'NSCollectionView'的視圖嗎?不,這不對。原因是因爲它是一個透明窗口,我不希望視圖變成醜陋的灰色。 – Catastrophe

回答

1

我認爲,試圖暗示動畫(通過指定爲transform屬性的新值)的第二部分的代碼,你需要跳過,說不是動畫效果設置kCATransactionDisableActions屬性true自過渡(這與你的意圖完全相反)。爲了明確你可以設置該屬性爲false.也可能很容易出現其他一些問題。在編碼和運行之前,我似乎從不知道到底需要什麼。 (隨着核心動畫,我總是發現自己正在逐漸趨向於我想要的結果,但最終得到至少來動畫它真的激勵我繼續調整代碼,直到它按照我想要的方式工作,即,核心動畫不容易拾取。)

至於第一個問題,顯式動畫,我相信一個問題與設置圖層的transform屬性的最後一行有關;我會開始把它放在外面(儘管從長遠來看,它可能需要在其他地方反擊)。設置該轉換會立即將圖層更改爲動畫完成時的外觀(這就是您看到轉換立即發生的原因),但這並不能完全解釋自從事務以來沒有看到任何動畫(一旦代碼完成就開始動畫即即時轉換髮生後)確實具有「開始」和「結束」值。首先,我會先找到一些示例代碼,它會執行類似的動畫並逐個改變它以獲得您想要的內容。 (這就是我在嘗試完全編寫自己的動畫代碼並使其失敗之後學會了使用核心動畫的原因;確實需要很長時間才能正確使用動畫,但我真的對此有了更好的感覺)。要回到文檔,真正嘗試獲得core animation rendering architecture,即層樹的概念,呈現樹渲染樹,在動畫的不同階段所顯示的內容以及如何影響它(在一系列試驗和錯誤之後,它們將再次陷入困境)。只要堅持下去,直到它是有道理的!

+0

感謝您抽出時間寫出所有內容。偉大的信息。謝謝! – Catastrophe

1

您可能需要使用

[usersView setWantsLayer:YES]; 

,如果你弄清楚,你的層是零。默認情況下,所有視圖都沒有圖層。

+0

這個給我修好了,謝謝! – Romejanic

0

經過幾次嘗試,我終於得到了我的動畫工作。有幾件事要注意我們的。

如果你想轉換到錨定在中心,那麼你應該在CALayer:致電anchorPoint之前添加以它的父!否則,子視圖將從anchorPoint位置開始切割。

CALayer *layer = _completionIndicator.layer; 
layer.anchorPoint = CGPointMake(.5, .5); 

裹在一個runAnimationGroup塊動畫調用(_completionIndicator是定義爲NSView一個屬性,centerInSuperview定義如下):

[self.contentView addSubview:_completionIndicator]; 
[_completionIndicator centerInSuperview]; 

[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) { 
    CGFloat duration = <#duration#>; 

    CALayer *layer = _completionIndicator.layer; 
    CABasicAnimation *animation; 

    //Transform 
    animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 
    animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(<#scale#>, <#scale#>, 1.0)]; 
    animation.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity]; 
    [animation setDuration:duration]; 
    animation.fillMode = kCAFillModeForwards; 
    animation.removedOnCompletion = NO; 
    [layer addAnimation:animation forKey:@"zoomIn"]; 

    //Fade 
    animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
    animation.fromValue = [NSNumber numberWithFloat:0.0]; 
    animation.toValue = [NSNumber numberWithFloat:1.0]; 
    [animation setDuration:duration]; 
    animation.fillMode = kCAFillModeForwards; 
    animation.removedOnCompletion = NO; 
    [layer addAnimation:animation forKey:@"fadeIn"]; 
} completionHandler:^{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 
     [NSThread sleepForTimeInterval:<#seconds#>]; 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      [self hideCompletionIndicator]; 
     }); 

    }); 

}]; 

設置fillMode是一個必不可少流暢的動畫。默認值爲kCAFillModeRemoved,在第一次運行後運行動畫時會導致跳轉。

在OSX 10.11上,不需要在NSView上設置wantsLayer。我不知道以前的版本。

要隱藏視圖,只需相反執行,並且移除在完成塊中的視圖:

- (void) hideCompletionIndicator 
{ 
    [NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) { 
     CGFloat duration = <#duration#>; 

     CALayer *layer = _completionIndicator.layer; 
     CABasicAnimation *animation; 

     //Transform 
     animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 
     animation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity]; 
     animation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(<#scale#>, <#scale#>, 1.0)]; 
     [animation setDuration:duration]; 
     animation.fillMode = kCAFillModeForwards; 
     animation.removedOnCompletion = NO; 
     [layer addAnimation:animation forKey:@"zoomOut"]; 

     //Fade 
     animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
     animation.fromValue = [NSNumber numberWithFloat:1.0]; 
     animation.toValue = [NSNumber numberWithFloat:0.0]; 
     [animation setDuration:duration]; 
     animation.fillMode = kCAFillModeForwards; 
     animation.removedOnCompletion = NO; 
     [layer addAnimation:animation forKey:@"fadeOut"]; 
    } completionHandler:^{ 
     [_completionIndicator removeFromSuperview]; 
    }]; 
} 

的NSView類別執行

@implementation NSView (Additions) 

- (void) centerInSuperview 
{ 
    [self centerInView:[self superview]]; 
} 

- (void) centerInView:(NSView *)otherView 
{ 
    int w = self.frame.size.width; 
    int h = self.frame.size.height; 
    int x = (otherView.frame.size.width - w)/2; 
    int y = (otherView.frame.size.height - h)/2; 

    self.frame = NSMakeRect(x, y, w, h); 

} 

@end 

的NSView類別接口

@interface NSView (Additions) 

- (void) centerInSuperview; 
- (void) centerInView:(NSView *)otherView; 

@end