2012-12-28 43 views
2

我是新的Mac開發,我們有像 imagev = [NSArray的arrayWithObjects任何方法NSImageView動畫

我需要一個像我們在iOS的做一些事情想在Mac做,

imageVie.animationImages = [NSArray arrayWithObjects: 
[UIImage imageNamed:@"1.png"],[UIImage imageNamed:@"2.png"], 
[UIImage imageNamed:@"3.png"],[UIImage imageNamed:@"4.png"], 
[UIImage imageNamed:@"5.png"],[UIImage imageNamed:@"6.png"], 
[UIImage imageNamed:@"7.png"] ,nil]; 

在iPhone,我怎麼能動畫

問候

+0

我認爲你缺少你想後... – Thilo

+0

我需要一個像我們在iOS的做一些事情的一半要在Mac做,imageVie.animationImages = [NSArray arrayWithObjects:[UIImage imageNamed:@「1.png」],[UIImage imageNamed:@「2.png」],[UIImage imageNamed:@「3.png」],[UIImage imageNamed:@ 「4.png」],[UIImage imageNamed:@「5.png」],[UIImage imageNamed:@「6.png」],[UIImage imageNamed:@「7.png」],nil]; – kiri

+0

@kiri:那麼,您想要拍攝一系列圖像,從它們製作單個動畫圖像,並在Mac的圖像視圖中顯示該圖像? –

回答

1

可可沒有任何類似animatedImageWithImages:duration:。 Cocoa中的圖像可能因空間(不同分辨率)和顏色深度而異,但不是時間;一張圖片總是一張靜態圖片,從未動畫過。

(有可能是動畫GIF的例外,但GIF不能顯示超過255幀或每幀256色,並且不支持部分透明度此外,我還沒有嘗試創建或顯示使用GIF NSImage或CGImage機器)。

你需要做的是創建一個圖像,而不是一個電影。 Add images to the movie, varying each one's duration to achieve the playback speed you want.然後,顯示您的電影movie view,可選the controller hidden

3

我發現有人在用我已經足夠接近的Core Animation approach to this issue。我稍微修改了一下。您需要@import QuartzCore;

- (void)awakeFromNib 
{ 
    CALayer *layer = [CALayer layer]; 
    NSMutableArray *spinnerImages = [NSMutableArray arrayWithCapacity:30u]; 
    for (NSUInteger i = 0; i < 30; ++i) 
    { 
     NSString *imageName = [NSString stringWithFormat:@"spinner%@", @(i)]; 
     [spinnerImages addObject:[NSImage imageNamed:imageName]]; 
    } 
    self.spinnerImages = spinnerImages; 
    layer.frame = self.imageView.bounds; 
    [self.imageView setLayer:layer]; // This view is just a container for the layer. Its frame can be managed by a xib. 
    self.imageView.wantsLayer = YES; 

    self.spinnerLayer = layer; 
} 

然後你就可以像這樣製作動畫:由本弗林

- (void)stopAnimating 
{ 
    if ([self.layer.animationKeys containsObject:kAnimationKey]) 
    { 
     [self.layer removeAnimationForKey:kAnimationKey]; 
    } 
} 

- (void)startAnimating 
{ 
    if ([self.layer.animationKeys containsObject:kAnimationKey]) 
    { 
     return; 
    } 
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:kAnimationKey]; 
    [animation setCalculationMode:kCAAnimationDiscrete]; 
    [animation setDuration:1.0f]; 
    [animation setRepeatCount:HUGE_VALF]; 
    [animation setValues:self.spinnerImages]; 
    [self.spinnerLayer addAnimation:animation forKey:kAnimationKey]; 
} 
+0

正在嘗試使用簡單的計時器替換圖像,導致CPU佔用90%左右。使用CoreAnimation將其降低至接近1%。 – bauerMusic

+0

有沒有辦法讓我的序列只有一次動畫,以便最後一幀仍然存在? – ixany

1

建立在偉大的答案。

在夫特3:

// This needs to happen around init. 
// NSView (and who inherit from it) does not come with a layer. 
// self.layer will be nil at init. 
self.layer = CALayer() 
self.wantsLayer = true 

let layer = CALayer() 
let keyPath = "contents" // (I did not find a constant for that key.) 
let frameAnimation = CAKeyframeAnimation(keyPath: keyPath) 
frameAnimation.calculationMode = kCAAnimationDiscrete 

// Duration 
// This is the duration of one cycle 
let durationOfAnimation: CFTimeInterval = 2.5 
frameAnimation.duration = durationOfAnimation 
frameAnimation.repeatCount = HUGE// can also use Float.infinity 

let imageSeq: [NSImage] = imageSequance // Your images to animate 
frameAnimation.values = imageSeq 

// Sadly, there are no layout constraints on CALayer. 
// If your view will be resized while animating, you'll need to override 
// 'func layout()' and calculate aspect ratio if needs be 
let layerRect = CGRect(origin: CGPoint.zero, size: self.frame.size) 
layer.frame = layerRect 
layer.bounds = layerRect 
layer.add(frameAnimation, forKey: keyPath) 

self.layer?.addSublayer(layer) 

如果視圖有望被調整大小:

刪除這些行:

let layerRect = CGRect(origin: CGPoint.zero, size: self.frame.size) 
layer.frame = layerRect 
layer.bounds = layerRect 

以及將所述子層後調用self.needsLayout = true。這將導致layout()被調用。

//let layerRect = CGRect(origin: CGPoint.zero, size: self.frame.size) 
//layer.frame = layerRect 
//layer.bounds = layerRect 
layer.add(frameAnimation, forKey: keyPath) 

self.layer?.addSublayer(layer) 
self.needsLayout = true 

最後,覆蓋layout()

override func layout() { 
    super.layout() 

    var layerFrame = CGRect(origin: CGPoint.zero, size: self.frame.size) 
    self.myLayer.frame = layerFrame 
    self.myLayer.bounds = // Adjust ratio as needed. 
} 
+0

有沒有辦法讓我的序列只有一次動畫,以便最後一幀仍然存在? – ixany

+0

我所做的是安排一個計時器在動畫結束時觸發(即動畫持續時間號碼)並移除動畫層。此時您只需呈現選定的圖像。一些CoreAnimation允許在最後一幀「倒帶」離開動畫,但我沒有看到這個選項。 – bauerMusic