【问题标题】:Different transparencies in Cocoa?可可中有不同的透明胶片?
【发布时间】:2012-02-03 20:55:15
【问题描述】:

我重载了 NSWindow 并创建了我自己的自定义窗口(无边框和透明度为 0.3 alphaValue)。我将在这个窗口中绘制图像。有什么方法可以让我在不透明的窗口中绘制的图像?我希望窗口保持透明,但希望图像不透明。我该怎么做?

Mac OS X 雪豹 Xcode 3.2.6

【问题讨论】:

    标签: objective-c macos cocoa


    【解决方案1】:

    @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) 是半透明/透明的。
    • 我无法重现这个。我把NSImageView 扔进了我的,它看起来不透明。我在一个 10.7 的盒子上进行测试,但这不应该改变。你能发布一个示例项目吗?
    【解决方案2】:

    这种方法存在潜在问题。
    请求“[self setStyleMask:NSBorderlessWindowMask];” (使用任何可能的 StyleMask 值)将导致该窗口的击键事件在随后将窗口显示为工作表时丢失。在这一点上,我今天向 Apple 报告了一个错误。

    【讨论】:

      【解决方案3】:

      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
      

      【讨论】:

        猜你喜欢
        • 2016-04-09
        • 1970-01-01
        • 2014-10-30
        • 2014-07-13
        • 2015-11-19
        • 1970-01-01
        • 1970-01-01
        • 2011-06-30
        • 1970-01-01
        相关资源
        最近更新 更多