Dr.Kameleon
Dr.Kameleon

Reputation: 22820

How to toggle visibility of NSSplitView subView + hide Pane Splitter divider?

We have a parent Split view (NSSplitView), and two subviews, Content and SideBar (the sidebar is on the right).

What would be the optimal Cocoa-friendly way to toggle the SideBar view?

HINT : I've been trying to do that, but still I had issues hiding the divider of the NSSplitView as well. How could I do it, while hiding it at the same time?

Upvotes: 8

Views: 9453

Answers (6)

rs7
rs7

Reputation: 1630

Easiest way to do it is as follows - and it's animated: [SWIFT 5]

    splitViewItems[1].animator().isCollapsed = false // Show side pane
    splitViewItems[1].animator().isCollapsed = true // hide side pane

Upvotes: 6

Ely
Ely

Reputation: 9131

If your NSSplitView control is part of a NSSplitViewController object, then you can simply use this:

splitViewController.toggleSidebar(nil)

Upvotes: 1

Peter Ahlberg
Peter Ahlberg

Reputation: 1379

In Xcode 9.0 with Storyboards open Application Scene select View->Menu->Show sidebar. CTRL-click Show Sidebar, in sent actions delete the provided one, click on x. From the circle CTRL drag to First Responder in application scene and select toggleSideBar to connect to. Open storyboard and select the first split view item and in attributes inspector change behaviour from default to sidebar. Run and try with view menu item show/hide. All done in interface builder no code. toggleSideBar handles the first split view item. https://github.com/Dis3buted/SplitViewController

Upvotes: 4

Luis Vieira Damiani
Luis Vieira Damiani

Reputation: 319

I got some artifacts with the code above, likely because it was out of context. I am sure it works where it was meant to. Anyway, here is a very streamlined implementation:

// this is the declaration of a left vertical subview of
// 'splitViewController', which is the name of the split view's outlet

var leftView: NSView {
    return self.splitViewController.subviews[0] as NSView
    }

// here is the action of a button that toggles the left vertical subview
// the left subview is always restored to 100 pixels here

@IBAction func someButton(sender: AnyObject) {

    if splitViewController.isSubviewCollapsed(leftView) {
        splitViewController.setPosition(100, ofDividerAtIndex: 0)
        leftView.hidden = false
    } else {
        splitViewController.setPosition(0, ofDividerAtIndex: 0)
        leftView.hidden = true
    }
}

To see a good example using animations, control-click to download this file.

Upvotes: 3

Bjorn
Bjorn

Reputation: 71860

I wrote a Swift version of the content in the link from @Nathan's answer that works for me. In the context of my example splitView is set elsewhere, probably as an instance property on an encompassing class:

func toggleSidebar () {
    if splitView.isSubviewCollapsed(splitView.subviews[1] as NSView) {
        openSidebar()
    } else {
        closeSidebar()
    }
}

func closeSidebar () {
    let mainView = splitView.subviews[0] as NSView
    let sidepanel = splitView.subviews[1] as NSView
    sidepanel.hidden = true
    let viewFrame = splitView.frame
    mainView.frame.size = NSMakeSize(viewFrame.size.width, viewFrame.size.height)
    splitView.display()
}

func openSidebar () {
    let sidepanel = splitView.subviews[1] as NSView
    sidepanel.hidden = false
    let viewFrame = splitView.frame
    sidepanel.frame.size = NSMakeSize(viewFrame.size.width, 200)
    splitView.display()
}

These functions will probably methods in a class, they are for me. If your splitView can be nil you obviously have to check for that. This also assumes you have two subviews and the one at index 1, here as sidePanel is the one you want to collapse.

Upvotes: 4

Nathan Kinsinger
Nathan Kinsinger

Reputation: 25021

Here's a pretty decent tutorial that shows how to do this: Unraveling the Mysteries of NSSplitView.

Hiding the divider is done in NSSplitView's delegate method splitView:shouldHideDividerAtIndex:.

You will have to animate the frame size change yourself if you don't like the way NSSplitView does it.

Upvotes: 8

Related Questions