【问题标题】:NSImage rotation in NSView is not workingNSView 中的 NSImage 旋转不起作用
【发布时间】:2012-05-31 15:00:07
【问题描述】:

我正在尝试在 NSView 中旋转 NSImage。首先,我将向您展示我到目前为止所做的工作。


图片:



头文件


#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>

@interface AppController : NSObject {
    CALayer *syncFirst;
}

@property (weak) IBOutlet NSView *nsview;

- (IBAction)buttonClicked:(id)sender;
- (CGImageRef) convertToCGImageFromNasImage:(NSImage *) image;

@end

实现文件,只有相关方法


- (void)awakeFromNib {
    
    NSImage *image = [NSImage imageNamed:@"SyncRing.png"];
    //init layer
    syncFirst = [CALayer layer];
    
    //animatated content size init
    syncFirst.bounds = CGRectMake(0, 0, image.size.width, image.size.height);
    syncFirst.position = CGPointMake(10, 10);
    syncFirst.contents = (id)[self convertToCGImageFromNasImage:image];

    [nsview.layer addSublayer:syncFirst];
}

 /*To convert NSImage in CGImage*/

- (CGImageRef) convertToCGImageFromNasImage:(NSImage *) image {
     NSData* cocoaData = [NSBitmapImageRep TIFFRepresentationOfImageRepsInArray: [image representations]];
     CFDataRef carbonData = (__bridge CFDataRef)cocoaData;
     CGImageSourceRef imageSourceRef = CGImageSourceCreateWithData(carbonData, NULL);
     CGImageRef myCGImage = CGImageSourceCreateImageAtIndex(imageSourceRef, 0, NULL);
     return myCGImage;
}

/*When button click animate the image*/

- (IBAction) buttonClicked:(id)sender {
    CABasicAnimation* rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    rotationAnimation.toValue = [NSNumber numberWithFloat:(2 * M_PI) * 1];
    rotationAnimation.duration = 1.0f;
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    [syncFirst addAnimation:rotationAnimation forKey:@"rotateAnimation"];
}

问题:


基本上,我试图在单击按钮后旋转此图像。我正在尝试的代码不是 100% 实现,而是从包括 Apple 文档在内的几个不同地方学习的。现在,很明显我犯了一些天真的错误,但从逻辑上讲,我的代码对我来说似乎是正确的。如果有人能指出我的错误并让我了解它为什么不起作用,那就太好了。

【问题讨论】:

    标签: objective-c macos cocoa core-animation cabasicanimation


    【解决方案1】:

    对于任何未来的访问者,该代码可以完美运行,如果需要,您可以使用它,除非确保在 nsview 中添加层之前,我们必须设置 nsview 想要层。

    所以,变化将是……


    - (void)awakeFromNib {
    
        NSImage *image = [NSImage imageNamed:@"SyncRing.png"];
        //init layer
        syncFirst = [CALayer layer];
    
        //animatated content size init
        syncFirst.bounds = CGRectMake(0, 0, image.size.width, image.size.height);
        syncFirst.position = CGPointMake(10, 10);
        syncFirst.contents = (id)[self convertToCGImageFromNasImage:image];
        
        /*HERE SETWANTSLAYER TO TRUE IN ORDER TO FIX*/
        [nsview setWantsLayer:YES];
    
        [nsview.layer addSublayer:syncFirst];
    }
    

    使用此代码之前

    请参考评论中的讨论。有一些有用的提示,我在解决问题时忽略了这些提示。归功于 - Peter Hosey

    【讨论】:

    • 不要忘记将nsviewlayer设置为您首先创建的图层。您不应该操作 AppKit 创建的 layer-backed view 的 layer。如果要添加自己的子图层,则必须为视图创建自己的图层并使其成为图层托管视图。有关详细信息,请参阅setWantsLayer: 的文档:developer.apple.com/library/mac/documentation/Cocoa/Reference/…:
    • @PeterHosey,我检查了 Apple 的示例代码,但它保存了旧的内容视图,因此当动画完成时,他们可以清理并设置所有内容。但就我而言,动画永远存在。还有一件事,所以如果我想以正确的方式做,我必须创建一个图层作为动画的hostingLayer,将它添加到nsview中,然后将我的动画图层添加到hostingLayer中。我说的对吗?
    • 是的,你必须创建自己的图层,交给视图,并告诉视图它想要图层。我认为在将根层传递给视图之前或之后添加子层并不重要。 (请注意,“hostingLayer”没有意义:视图承载层,而不是相反。)
    • 太好了,非常感谢不吝赐教
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多