简体   繁体   中英

Editable NSTextField inside not .titled NSPanel

I'm making a bridge for react-native-macos. I need NSPanel with the same behaviour as Spotlight.

I programmatically created NSPanel and NSTextField inside. Everything working as expected, but if I change NSPanel to not.titled - the text field is disabled.

Works:

panel = NSPanel(contentRect: NSRect(x: 0, y: 0, width: 400, height: 40), styleMask: [
    .borderless,
    .nonactivatingPanel,
    .titled,  < ------- HERE
    .resizable,
  ], backing: .buffered, defer: true)

searchField = NSTextField()
searchField.delegate = self
searchField.isBezeled = false
searchField.font = NSFont.systemFont(ofSize: 20, weight: .light
searchField.drawsBackground = false
searchField.placeholderString = "Query here..."
searchField.setFrameSize(NSMakeSize(400, 40)

Doesn't work:

panel = NSPanel(contentRect: NSRect(x: 0, y: 0, width: 400, height: 40), styleMask: [
    .borderless,
    .nonactivatingPanel,
    .resizable,
  ], backing: .buffered, defer: true)

searchField = NSTextField()
searchField.delegate = self
searchField.isBezeled = false
searchField.font = NSFont.systemFont(ofSize: 20, weight: .light
searchField.drawsBackground = false
searchField.placeholderString = "Query here..."
searchField.setFrameSize(NSMakeSize(400, 40)

How can I do NSPanel with hidden titlebar and editable NSTextField inside?

I believe .borderless and .titled are mutually exclusive. In other words, when you specify .borderless in the top code, the .titled overrides it and you get end up getting a "normal window" that handles events normally. In the second code, the .borderless actually registers and you end up getting a borderless window subclass that handles events quite differently. But all of this is beside the point.

Assuming you can require greater than macOS 10.10, you can use the following code:

panel = NSPanel(contentRect: NSRect(x: 0, y: 0, width: 400, height: 40), styleMask: [
    .titled,
    .fullSizeContentView,
    ], backing: .buffered, defer: true)
panel.titleVisibility = .hidden
panel.titlebarAppearsTransparent = true
panel.makeFirstResponder(searchField)
panel.makeKeyAndOrderFront(nil)

This gets a full-sized titled panel that handles events normally (it allows its views to become key). Then before showing the panel, hide the titlebar and also make it transparent. Note that to have the titlebar fully disappeared, you need to not use any of the .resizable , .closable , or .miniaturizable options.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM