【问题标题】:cocoa hello world screensaver可可你好世界屏保
【发布时间】:2010-03-17 05:58:57
【问题描述】:

我一直在研究 NSView,因此我想我会尝试使用屏幕保护程序。我已经能够在 NSView 中显示和图像,但我无法修改此示例代码以在 ScreenSaverView 中显示简单的图片。

http://www.mactech.com/articles/mactech/Vol.20/20.06/ScreenSaversInCocoa/

顺便说一句,适用于 Snow Leopard 的很棒的教程。

我想简单地显示一个图像,我需要看起来像这样的东西......

我做错了什么?

//
//  try_screensaverView.m
//  try screensaver
//

#import "try_screensaverView.h"

@implementation try_screensaverView

- (id)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview
{
    self = [super initWithFrame:frame isPreview:isPreview];
    if (self) {
        [self setAnimationTimeInterval:1]; //refresh once per sec
    }
    return self;
}

- (void)startAnimation
{
    [super startAnimation];

    NSString *path = [[NSBundle mainBundle] pathForResource:@"leaf" ofType:@"JPG" inDirectory:@""];
    image = [[NSImage alloc] initWithContentsOfFile:path];
}

- (void)stopAnimation
{
    [super stopAnimation];
}

- (void)drawRect:(NSRect)rect
{
    [super drawRect:rect];
}

- (void)animateOneFrame
{
    //////////////////////////////////////////////////////////
    //load image and display  This does not scale the image

    NSRect bounds = [self bounds];
    NSSize newSize;
    newSize.width = bounds.size.width;
    newSize.height = bounds.size.height;
    [image setSize:newSize];
    NSRect imageRect;
    imageRect.origin = NSZeroPoint;
    imageRect.size = [image size];
    NSRect drawingRect = imageRect;
    [image drawInRect:drawingRect fromRect:imageRect operation:NSCompositeSourceOver fraction:1];
}

- (BOOL)hasConfigureSheet
{
    return NO;
}

- (NSWindow*)configureSheet
{
    return nil;
}

@end

【问题讨论】:

  • 它做了什么? (顺便说一句,您正在泄漏图像。释放对象(对于非 GC)并将 ivar 设置为 nil(对于 GC)以修复泄漏。)

标签: objective-c cocoa screensaver


【解决方案1】:
NSRect bounds = [self bounds];
NSSize newSize;
newSize.width = bounds.size.width;
newSize.height = bounds.size.height;
[image setSize:newSize];

我不知道你为什么这样做。

NSRect imageRect;
imageRect.origin = NSZeroPoint;
imageRect.size = [image size];

又名。 [self bounds].size.

NSRect drawingRect = imageRect;
[image drawInRect:drawingRect fromRect:imageRect operation:NSCompositeSourceOver fraction:1];

[image drawInRect:[self bounds] fromRect:[self bounds] operation:NSCompositeSourceOver fraction:1]

如果您尝试以自然大小绘制图像,则没有理由向其发送setSize: 消息。剪掉整个第一部分,其余部分应该可以正常工作。

如果您尝试填满屏幕(这会缩放,这与评论相矛盾),请将drawingRect 设置为[self bounds],而不是imageRect。这完全按照它的意思:

image,
    draw into (the bounds of the view),
    from (the image's entire area).

[image
    drawInRect:[self bounds]
      fromRect:imageRect
              ⋮
];

自然大小固定位置绘制和全屏绘制都不是有效的屏幕保护程序。后者是不可挽回的;您可以通过为屏幕周围的图像设置动画来使前者有用。

【讨论】:

  • 这很好,但还是不行。我应该在开始动画中加载图像吗?你能不能给我一个工作的 .m 文件?超级简单的 .m 文件在此先感谢!
  • 您可能应该更早地加载图像;我可能会在initWithBundle: 中这样做。如果在你这样做之后它仍然不起作用,那么你将需要定义“不起作用”。
【解决方案2】:

我遇到了类似的问题,所以我会发布我的解决方案。 OP 试图通过 NSBundle 的 mainBundle 加载图像内容。相反,您会更幸运地获取屏幕保护程序的包并从那里加载文件,如下所示:

NSBundle *saverBundle = [NSBundle bundleForClass:[self class]];
NSImage *image = [[NSImage alloc] initWithContentsOfFile:[saverBundle pathForResource:@"image" ofType:@"png"]];

【讨论】:

    【解决方案3】:

    由于您在animateOneFrame 中进行绘图,请尝试删除您覆盖的drawRect

    【讨论】:

      猜你喜欢
      • 2011-02-20
      • 2021-11-19
      • 2015-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多