【发布时间】:2012-02-03 20:55:15
【问题描述】:
我重载了 NSWindow 并创建了我自己的自定义窗口(无边框和透明度为 0.3 alphaValue)。我将在这个窗口中绘制图像。有什么方法可以让我在不透明的窗口中绘制的图像?我希望窗口保持透明,但希望图像不透明。我该怎么做?
Mac OS X 雪豹 Xcode 3.2.6
【问题讨论】:
标签: objective-c macos cocoa
我重载了 NSWindow 并创建了我自己的自定义窗口(无边框和透明度为 0.3 alphaValue)。我将在这个窗口中绘制图像。有什么方法可以让我在不透明的窗口中绘制的图像?我希望窗口保持透明,但希望图像不透明。我该怎么做?
Mac OS X 雪豹 Xcode 3.2.6
【问题讨论】:
标签: objective-c macos cocoa
@ughoavgfhw 是在正确的轨道上,但实际上要容易得多。您只需将opaque 设置为NO 并将backgroundColor 设置为半透明即可。
@implementation MYWindow
- (void)setup
{
[self setStyleMask:NSBorderlessWindowMask];
[self setOpaque:NO];
[self setBackgroundColor:[NSColor colorWithCalibratedWhite:1.0 alpha:0.3]];
}
// We override init and awakeFromNib so this works with or without a nib file
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag
{
self = [super initWithContentRect:contentRect styleMask:aStyle backing:bufferingType defer:flag];
if (self)
{
[self setup];
}
return self;
}
- (void)awakeFromNib
{
[super awakeFromNib];
[self setup];
}
@end
【讨论】:
NSImageView 扔进了我的,它看起来不透明。我在一个 10.7 的盒子上进行测试,但这不应该改变。你能发布一个示例项目吗?
这种方法存在潜在问题。
请求“[self setStyleMask:NSBorderlessWindowMask];” (使用任何可能的 StyleMask 值)将导致该窗口的击键事件在随后将窗口显示为工作表时丢失。在这一点上,我今天向 Apple 报告了一个错误。
【讨论】:
将alphaValue 属性保留为1,并将opaque 属性设置为NO。然后,将默认的contentView 替换为在其drawRect: 方法中使用alpha 分量为0.3 的颜色填充自身的颜色。当您更改alphaValue 属性时,它会更改在窗口中绘制的所有内容的显示方式。当您将其设为非透明时,它根本不会在内容视图下方绘制黑色背景,因此如果内容视图是透明的,则窗口也是透明的,但在其上绘制的任何内容都不会受到影响。
这是一个使用带有 0.3 alpha 分量的白色背景的示例。请注意,我覆盖了 setContentView: 方法。这样我就可以将传递的视图中的任何视图复制到透明内容视图中,如果从 nib 加载窗口尤其必要,因为 nib 加载会在加载时更改内容视图。 (您可以改为在 IB 中更改内容视图的类。)
@interface MyWindow_ContentView : NSView
@end
@implementation MyWindow
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag {
if(self = [super initWithContentRect:contentRect styleMask:aStyle backing:bufferingType defer:flag]) {
[super setOpaque:NO];
[super setContentView:[[[MyWindow_ContentView alloc] init] autorelease]];
}
return self;
}
- (void)setOpaque:(BOOL)ignored {}
- (void)setContentView:(NSView *)newView {
NSArray *views = [[self.contentView subviews] copy];
[views makeObjectsPerformSelector:@selector(removeFromSuperview)];
views = [[newView subviews] copy];
[views makeObjectsPerformSelector:@selector(removeFromSuperview)];
for(NSView *view in views) [self.contentView addSubview:view];
[views release];
}
@end
@implementation MyWindow_ContentView
- (void)drawRect:(NSRect)rect {
[[NSColor colorWithCalibratedWhite:1 alpha:0.3] set];
NSRectFill(rect);
}
@end
【讨论】: