Yuma Technical Inc.
Yuma Technical Inc.

Reputation: 723

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?

Upvotes: 1

Views: 771

Answers (2)

RabinDev
RabinDev

Reputation: 658

Found a way without living w/ the warning & not using the deprecated properties.

We create a transparent subview for the NASToolbarItem with the min / max constraints in advance, so the system has a way to calc the min and max size itself.

let toolbarItem = NSToolbarItem(itemIdentifier: NSToolbarItem.Identifier.flexibleSpace)

// view to be hosted in the flexible space toolbar item
let view = NSView(frame: CGRect(origin: .zero, size: CGSize(width: MIN_TOOLBAR_ITEM_W, height: MIN_TOOLBAR_H)))
view.widthAnchor.constraint(lessThanOrEqualToConstant: MAX_TOOLBAR_ITEM_W).isActive = true
view.widthAnchor.constraint(greaterThanOrEqualToConstant: MIN_TOOLBAR_ITEM_W).isActive = true

// set the view and return
toolbarItem?.view = view
return toolbarItem

Upvotes: 1

Sili
Sili

Reputation: 54

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

Upvotes: 1

Related Questions