Clifton Labrum
Clifton Labrum

Reputation: 14138

NSPopover Background Color (Including Triangle) with macOS Mojave Dark Mode

Swift 4.2, Xcode 10, macOS 10.14

I have created the following NSView subclass that I put on the root view of all my NSPopover instances in my storyboard. But I noticed that when I switch the color mode in macOS Mojave (from dark to light or the other way around) that it doesn't update the background color of my NSPopover.

class PopoverMain:NSView{
  override func viewDidMoveToWindow() {
    guard let frameView = window?.contentView?.superview else { return }

    let backgroundView = NSView(frame: frameView.bounds)
    backgroundView.backgroundColor(color: Color(named: "MyColor")!)
    backgroundView.autoresizingMask = [.width, .height]

    frameView.addSubview(backgroundView, positioned: .below, relativeTo: frameView)
  }
}

I believe this is because a color mode transition only calls these methods (source) and not viewDidMoveToWindow():

Has anyone figured out a reliable way to color the background of an NSPopover (including its triangle) and have it work seamlessly on macOS Mojave?

Upvotes: 2

Views: 1019

Answers (1)

Clifton Labrum
Clifton Labrum

Reputation: 14138

It's funny how writing up your question leads to a solution (sometimes quickly). I realized I needed to create another NSView subclass responsible for generating the NSView that's loaded into the NSPopover. Note the addition of the PopoverMainView class:

class PopoverMain:NSView{
  override func viewDidMoveToWindow() {
    guard let frameView = window?.contentView?.superview else { return }

    let backgroundView = PopoverMainView(frame: frameView.bounds)
    backgroundView.autoresizingMask = [.width, .height]
    frameView.addSubview(backgroundView, positioned: .below, relativeTo: frameView)
  }
}

class PopoverMainView:NSView {
  override func draw(_ dirtyRect: NSRect) {
    Color(named: "MyColor")!.set()
    self.bounds.fill()
  }
}

Upvotes: 3

Related Questions