8

这是另一个NSWindow问题......我有无边框窗口,透明,以这种方式创建......

- (id)initWithView:(NSView *)view anchorPoint:(NSPoint)anchorPoint position:(NSPoint)position distance:(CGFloat)distance {
  if ( !view ) {
    return nil;
  }

  NSSize size = view.intrinsicContentSize;
  NSRect contentRect = NSMakeRect( 0, 0, size.width, size.height );

  self = [super initWithContentRect:contentRect
                          styleMask:NSBorderlessWindowMask
                            backing:NSBackingStoreBuffered
                              defer:NO];

  if ( !self ) {
    return nil;
  }

  _windowView = view;
  _anchorPoint = anchorPoint;
  _position = position;
  _distance = distance;

  [self setContentView:_windowView];

  [self setExcludedFromWindowsMenu:YES];
  [self setMovableByWindowBackground:NO];

  [self setOpaque:NO];
  [self setBackgroundColor:[NSColor clearColor]];

  [self setHasShadow:YES];
  [self useOptimizedDrawing:YES];

  [self setReleasedWhenClosed:NO];

  [self setFrame:[self windowRectWithSize:contentRect.size] display:YES];

  [self setAnchorAttribute:NSLayoutAttributeTop forOrientation:NSLayoutConstraintOrientationVertical];
  [self setAnchorAttribute:NSLayoutAttributeCenterX forOrientation:NSLayoutConstraintOrientationHorizontal];

  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(viewFrameDidChange:)
                                               name:NSViewFrameDidChangeNotification
                                             object:nil];

  return self;
}

...并被viewFrameDidChange:定义为...

- (void)viewFrameDidChange:(NSNotification *)note {
  if ( note.object != self.contentView ) {
    return;
  }

  [self display];
  [self setHasShadow:NO];
  [self setHasShadow:YES];
}

...这是获得适当NSWindow阴影的唯一方法。换句话说,每当窗口大小发生变化时,我都必须调用,display否则窗口阴影会被削弱 - 它不在整个窗口周围 - 只是窗口的一部分,等等。setHasShadow:NOsetHasShadow:YES

在我开始动画高度之前,这确实有效。如果高度是动画的,阴影会正确地重新计算和显示,但整个窗口和阴影会闪烁并且非常难看。

一个想法为什么阴影在闪烁?我尝试将 , 替换displaysetHasShadow:NO/YES[self invalidateShadow]但它根本不起作用,并且阴影以错误的方式显示。

如何在无边框/透明窗口中使用阴影为窗口高度设置动画以避免闪烁?

这是闪烁阴影的视频。http://d.pr/v/lbkQ

4

2 回答 2

2

也许最好在动画开始时关闭阴影并在完成后重新打开。不要在动画期间切换此设置。我想我在其他窗户上也看到了这一点。

于 2013-04-22T17:32:49.707 回答
2

阴影计算和绘制是一个非常消耗资源的操作。因此,我不建议您在每次帧更改时使阴影无效并重新计算。此外,NSWindowDelegate有一个–windowDidResize:方法,为什么要使用观察者呢?

  1. 如何调整窗口大小?也许添加NSResizableWindowMask到窗口的样式掩码可以解决问题?你应该试一试。

  2. 另一个建议 - 检查窗口的内容是否与窗口一起正确调整大小。您将窗口设置为透明。但如果窗口内没有内容,则不会显示阴影。您还可以尝试将您的视图作为子视图添加到现有窗口的 contentView 而不是替换它。

我的项目中的设置几乎相同,我可以告诉您在调整窗口大小时正确显示了窗口的阴影。

PS A 建议:不要在对象的初始化方法中依赖'self'。它可能还没有完全准备好使用。以最小值初始化,在您的控制器中创建窗口后调整窗口(例如,您不能确定 setFrame:display 会以正确的大小执行您期望的操作)。您遇到的故障也可能与此有关。

于 2013-05-01T20:14:17.883 回答