无边框,透明窗口,当动画窗口高度时闪烁阴影



这是另一个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,否则窗口阴影就会被破坏-它不是在整个窗口周围-只是窗口的一部分,等等。

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

知道为什么影子在闪烁吗?我试图用[self invalidateShadow]代替display, setHasShadow:NO/YES,但它根本不起作用,阴影以错误的方式显示。

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

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

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

  1. 如何调整窗口大小?也许添加NSResizableWindowMask窗口的样式蒙版会做的伎俩?你应该试试。

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

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

注:建议:不要在对象的初始化方法中依赖'self'。它可能还没有完全准备好使用。初始化最小,调整窗口后,它是在你的控制器创建(例如,你不能确定setFrame:display将做你所期望的正确的大小)。

也许最好在动画开始时关闭阴影,完成后再打开。不要在动画期间切换此设置。我想我在其他窗口也看到过这种情况。

最新更新