隐藏NSWindow的标题栏

25

有没有方法可以隐藏NSWindow中的标题栏?我不想完全编写一个新的自定义窗口。我不能使用NSBorderlessWindowMask,因为我的窗口上有一个底部栏,使用NSBorderlessWindowMask会使其消失。我还尝试了使用setContentBorderThickness:forEdge:与NSMaxYEdge并将其设置为0,但也不起作用。

非常感谢您的帮助。


我最终改变了我的应用程序设计,以便不需要这样做。对于那些考虑采取同样做法的人来说,这并不是一个好的选择。 - indragie
9个回答

36
[yourWindow setStyleMask:NSBorderlessWindowMask];

5
我相信你也需要覆盖canBecomeKeyWindow或类似的方法。我试过了,但结果是我的窗口没有显示出来。不过,我使用了Bijan提供的苹果示例代码,那样就很好地解决了问题。 - Kenny Wyland
indragie明确表示他不能使用NSBorderlessWindowMask。 - ctpenrose
@KennyWyland,链接是什么? - skywinder
目前这对我不起作用...即使我覆盖了“canBecomeKeyWindow”等。 - Morkrom

23

从OS X 10.10开始,您可以隐藏标题栏。

window1.titlebarAppearsTransparent = true
window1.titleVisibility            = .Hidden

也许你想覆盖窗口样式。

window1.styleMask = NSResizableWindowMask
                  | NSTitledWindowMask
                  | NSFullSizeContentViewWindowMask

更新至 Swift 5:window.styleMask = [.resizable, .titled, .closable, .miniaturizable, .fullSizeContentView] - endavid
这在全屏模式下将不起作用。当您将鼠标移动到屏幕顶部时,标题栏仍将显示。 - Andrew_STOP_RU_WAR_IN_UA

6

Swift 4.1中的欢迎界面NSWindow / NSViewController设置方法

extension NSWindow {

   enum Style {
      case welcome
   }

   convenience init(contentRect: CGRect, style: Style) {
      switch style {
      case .welcome:
         let styleMask: NSWindow.StyleMask = [.closable, .titled, .fullSizeContentView]
         self.init(contentRect: contentRect, styleMask: styleMask, backing: .buffered, defer: true)
         titlebarAppearsTransparent = true
         titleVisibility = .hidden
         standardWindowButton(.zoomButton)?.isHidden = true
         standardWindowButton(.miniaturizeButton)?.isHidden = true
      }
   }
}

class WelcomeWindowController: NSWindowController {

   private (set) lazy var viewController = WelcomeViewController()
   private let contentWindow: NSWindow

   init() {
      contentWindow = NSWindow(contentRect: CGRect(x: 400, y: 200, width: 800, height: 472), style: .welcome)
      super.init(window: contentWindow)

      let frameSize = contentWindow.contentRect(forFrameRect: contentWindow.frame).size
      viewController.view.setFrameSize(frameSize)
      contentWindow.contentViewController = viewController
   }
}

class WelcomeViewController: NSViewController {

   private lazy var contentView = View()

   override func loadView() {
      view = contentView
   }

   init() {
      super.init(nibName: nil, bundle: nil)
   }

   override func viewDidLoad() {
      super.viewDidLoad()
      contentView.backgroundColor = .white
   }
}

class View: NSView {

   var backgroundColor: NSColor?

   convenience init() {
      self.init(frame: NSRect())
   }

   override func draw(_ dirtyRect: NSRect) {
      if let backgroundColor = backgroundColor {
         backgroundColor.setFill()
         dirtyRect.fill()
      } else {
         super.draw(dirtyRect)
      }
   }
}

结果

欢迎界面的NSWindow风格


如何使用这段代码? - Andrew_STOP_RU_WAR_IN_UA
只需显示窗口:https://developer.apple.com/documentation/appkit/nswindowcontroller/1534037-showwindow - Vlad
这段代码甚至在Swift 5中都无法编译 https://prnt.sc/26dwnqx - Andrew_STOP_RU_WAR_IN_UA
在答案的顶部提到示例代码适用于Swift 4.1。 - Vlad

1
如果获取关闭按钮的superview,会发生什么?你能隐藏它吗?
// Imagine that 'self' is the NSWindow derived class
NSButton *miniaturizeButton = [self standardWindowButton:NSWindowMiniaturizeButton];
NSView* titleBarView = [miniaturizeButton superview];
[titleBarView setHidden:YES];

1
我尝试了这个,但它只是把窗口变成了白色和空白。如果没有错的话,按钮的superview是NSThemeFrame。然而,我可以尝试调整视图的框架大小,以查看是否可以缩小它。 - indragie
调整框架效果不佳,我得到了各种奇怪的结果。我想我基本上被卡住了。 - indragie
无法正常工作的原因是 NSThemeFrame 是窗口 contentView 的超级视图。隐藏框架视图,所有子视图也会被隐藏。 - NSResponder
只是为了好玩,我转储了NSThemeFrame的头文件和其他相关类,然后在其中找到了一些用于返回标题栏高度的私有方法。然后我在我的NSWindow子类中加载了自定义主题框架子类并尝试了它,它确实起作用了,但同时也去掉了我的圆角和底部栏。哦,算了。 - indragie

1

我有这样的经历:当我第一次设置窗口的内容视图,然后将窗口设置为无边框时:

[yourWindow setStyleMask:NSBorderlessWindowMask];

我的窗口里什么也没有显示出来。因此,我首先设置了样式掩码,然后设置了内容视图:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{ 
    // 1. borderless window
    [[self window] setStyleMask: NSBorderlessWindowMask];
    // 2. create the master View Controller
    self.masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController" bundle:nil];
    // 3. Add the view controller to the Window's content view
    [self.window.contentView addSubview:self.masterViewController.view];
    self.masterViewController.view.frame = ((NSView*)self.window.contentView).bounds;     
}

瞧,我的窗口内容已经出现了。


1

我知道的唯一方法是创建一个没有标题栏的窗口(参见NSBorderlessWindowMask)。请注意,您不能在IB中轻松地创建没有标题栏的窗口,因此您需要在代码中进行一些工作(有几种不同的方法,您可能可以弄清楚)。

使用没有标题栏的窗口的一个大缺点是,您现在需要处理更多标准外观和行为 - 圆角等。


1
在Storyboard或XIB中选择Window,并勾选红圈选项。

0

-1

Swift

NSApp.mainWindow?.styleMask = .borderless

enter image description here


1
你不能在运行时更改这个东西。否则会导致你的应用程序崩溃。 - Andrew_STOP_RU_WAR_IN_UA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接