我是Mac开发新手,我们有任何方法吗? imagev = [NSArray arrayWithObjects
我需要一些像我们在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 :(得分: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];
}
答案 1 :(得分:1)
Cocoa没有animatedImageWithImages:duration:
之类的东西。 Cocoa中的图像可以在空间(不同的分辨率)和颜色深度上变化,但不是时间;单个图像始终是静态图像,从不动画。
(可能是动画GIF的例外,但GIF无法在每帧中显示超过255或256种颜色,并且不支持部分透明度。此外,我还没有尝试创建或使用NSImage或CGImage机器显示GIF。)
您需要做的不是创建图像,而是制作电影。 Add images to the movie, varying each one's duration to achieve the playback speed you want.然后,在movie view中显示您的电影,可选择the controller hidden。
答案 2 :(得分:1)
以 Ben Flynn 的优秀答案为基础。
在Swift 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.
}
答案 3 :(得分:0)
Swift 4.2
在添加beginTime
之前,我无法获得以前的答案。自Swift 3
起,一些常量也发生了变化。因此,我已将解决方案转换为Swift 4.2
。另外,我认为将其创建为CALayer
扩展会很方便:
extension CALayer {
static func image(sequence: [NSImage], duration: CFTimeInterval? = nil, frame: CGRect? = nil) -> CALayer {
let layer = CALayer()
if let f = frame { layer.frame = f }
layer.autoresizingMask = [.layerWidthSizable, .layerHeightSizable]
let keyPath = "contents"
let keyFrameAnimation = CAKeyframeAnimation(keyPath: keyPath)
keyFrameAnimation.values = sequence
keyFrameAnimation.calculationMode = .discrete
keyFrameAnimation.fillMode = .forwards
keyFrameAnimation.duration = duration ?? CFTimeInterval(sequence.count / 18)
keyFrameAnimation.repeatCount = Float.infinity
keyFrameAnimation.autoreverses = false
keyFrameAnimation.isRemovedOnCompletion = false
keyFrameAnimation.beginTime = 0.0
layer.add(keyFrameAnimation, forKey: keyPath)
return layer
}
}
像
一样使用let sequenceLayer = CALayer.image(sequence: imageSequence, duration: 0.55, frame: yourView.bounds)
答案 4 :(得分:0)
@interface AnimatedNSImage : NSImage
@property (nonatomic, retain) IBInspectable NSImageView *delegate;
@property (nonatomic, readonly) NSArray *frames;
@property (nonatomic, readonly) CGFloat duration;
- (instancetype) initWithImages:(NSArray*)frames duration:(CGFloat)duration;
@end
在.m文件中...
@interface AnimatedNSImage () {
NSTimer *_scheduledTimer;
NSArray *_frames;
NSUInteger _frameIndex;
CGFloat _duration;
}
@end
@implementation AnimatedNSImage
@synthesize delegate;
- (NSArray *) frames
{
return _frames;
}
- (CGImageRef) CGImage
{
if (_frames && _frames.count >0) {
NSImage *_frame = _frames[_frameIndex];
return _frame.CGImage;
}
return nil;
}
- (NSArray<NSImageRep *> *) representations
{
NSImage *_frame = _frames[_frameIndex];
return _frame.representations;
}
- (CGFloat) duration
{
return _duration;
}
- (void) __showNextFrame:(id)sender
{
_frameIndex = (_frameIndex + 1) % _frames.count;
if (delegate) {
[delegate setNeedsDisplay:YES];
}
}
- (NSSize) size
{
if (_frames && _frames.count >0) {
NSImage *_frame = _frames[_frameIndex];
return _frame.size;
}
return CGSizeZero;
}
- (void) setup
{
_scheduledTimer = [NSTimer scheduledTimerWithTimeInterval:_duration target:self selector:@selector(__showNextFrame:) userInfo:nil repeats:YES];
}
- (void) dealloc
{
[_scheduledTimer invalidate];
_scheduledTimer = nil;
}
- (instancetype) initWithImages:(NSArray *)frames duration:(CGFloat)duration
{
self = [super init];
if (self) {
_frames = frames;
_duration = duration / 100.0f;
[self setup];
}
return self;
}
@end
请注意,您必须将委托分配给NSImageView才能调用刷新。
一个例子。...
IBOutlet NSImageView *_testGifView;
AnimatedNSImage *_animatedImage = [NSImage animatedImageWithAnimatedGIFURL:[NSURL URLWithString:@"https://media.giphy.com/media/B2zB8mHrHHUXS57Cuz/giphy.gif"]];
_testGifView.image = _animatedImage;
_animatedImage.delegate = _testGifView;
当然,可以根据需要调整计划的计时器,因为输入时间以厘秒(而不是分钟)为单位。