Search code examples
swiftxcodemacosnstoolbarnstoolbaritem

NSToolbar Flexible space not working in Swift 5.x


I developed this app using Xcode 10.1 (Swift 4.2 I believe) and toolbar looks good:

enter image description here

But I ported in over to my Xcode 11.6 (Swift 5.2 I believe), now the right-most item on the toolbar is no longer on the far right:

enter image description here

Before the port, I added that plus button - the checkbox (Show Hidden) was one of the first items and was never changed since. Also the buttons function as expected - their actions fire OK. Note: This app uses no Storyboards or IB things.

Since my code in split over several files (with lots of unrelated code), I will give an overview.

class ToolbarController: NSObject, NSToolbarDelegate {

let toolbar = NSToolbar(identifier: NSToolbar.Identifier("toolbar"))
lazy var toolbarItem1: NSToolbarItem = {
    let toolbarItem = NSToolbarItem(itemIdentifier: NSToolbarItem.Identifier(rawValue: "Btn1"))
    let button = NSButton(frame: NSRect(x: 0, y: 0, width: 40, height: 1))
    button.target = self
   ...
    toolbarItem.view = button
    return toolbarItem
}() // defined as "lazy" to allow "self"
var toolbarItemSpace: NSToolbarItem = {
    let toolbarItem = NSToolbarItem(itemIdentifier: NSToolbarItem.Identifier.space)
    return toolbarItem
}()
 ...
var toolbarItemFlexSpace: NSToolbarItem = {
    let toolbarItem = NSToolbarItem(itemIdentifier: NSToolbarItem.Identifier.flexibleSpace)
    return toolbarItem
}()
lazy var toolbarItemShowHidden: NSToolbarItem = {
    let toolbarItem = NSToolbarItem(itemIdentifier: NSToolbarItem.Identifier(rawValue: "Checkbox"))
    let box = NSBox(frame: NSRect(x: 0, y: 0, width: 120, height: 40))
    let button = NSButton() // put in NSBox to use isolated action
  ...
    button.target = self
    box.contentView = button
    box.sizeToFit() // tightly fit the contents (button)
    toolbarItem.view = box
    return toolbarItem
}()
lazy var tbItems: [NSToolbarItem] = [toolbarItem1, ...]

That class defines the toolbar, add the items, implements all those toolbar (delegate) methods and makes it the delegate. My NSWindowController then set it to the application toolbar.

Can anyone see an issue with my code that causes the above? Otherwise, is this a bug?


Solution

  • Had the same problem with Swift 5.0 ... even though the documentation says minSize and maxSize are deprecated, I solved this like:

    let toolbarItem = NSToolbarItem(itemIdentifier: NSToolbarItem.Identifier.flexibleSpace)
    toolbarItem.minSize = NSSize(width: 1, height: 1)
    toolbarItem.maxSize = NSSize(width: 1000, height: 1) //just some large value
    return toolbarItem
    

    Maybe this works as well for Swift 5.2