Search code examples
objective-ccocoaappkit

What is the equivalent of SwiftUI NavigationSplitView and NavigationLink in Cocoa/Appkit?


I want to use Appkit/Cocoa to create a split view with a side bar, I have this sample code in SwiftUI that does that:

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationSplitView {
            // Sidebar
            List {
                NavigationLink("Item 1", value: "Item 1 Details")
                NavigationLink("Item 2", value: "Item 2 Details")
                NavigationLink("Item 3", value: "Item 3 Details")
            }
            .navigationTitle("Items")
        } content: {
            // Main content (detail view for selected item)
            Text("Select an item to see details.")
                .padding()
        } detail: {
            // Detail view (for the selected item)
            Text("Select an item from the sidebar to view details.")
                .padding()
        }
    }
}

struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

enter image description here

Now, for AppKit I tried using an NSSplitViewController:

enter image description here

@interface SplitViewController : NSSplitViewController<NSSplitViewDelegate>

@property (strong) IBOutlet NSSplitView *splitView;

@property (weak) IBOutlet NSSplitViewItem *sideBarView;
@property (weak) IBOutlet NSSplitViewItem *rightView;

-(IBAction)hideSideBarNow:(id)sender;

@end

Notice that I also had to manually add a ToolbarItem with the 'sidebar.left' icon that calls a method to collapse the view when clicked:

enter image description here

-(void)hideSideBarNow:(id)sender
{
    static BOOL isCollapsing = YES;
    [[[[self splitViewItems] firstObject] animator] setCollapsed:isCollapsing];
    
    isCollapsing = !isCollapsing;
}

This works fine and all but I noticed the button looks a bit different if you compare it to the SwiftUI version or any other macOS applications. So I wonder am I doing this right or is there another way to get this side bar? Do I really have to manually add a toolbar item with a target/action to make this work on appkit?

I know that I could use NSHostingController to use a SwiftUI controller but I want to do it with Appkit/Cocoa only.


Solution

  • am I doing this right or is there another way to get this side bar?

    Yes. The other way is to build a custom split view from NSViews.

    Do I really have to manually add a toolbar item with a target/action to make this work on appkit?

    Yes. The target is the NSSplitViewController and the action is toggleSidebar(_:).