1

I'm using an NSSplitViewController subclass and the delegate methods are not being called.

This is purely programmatically without nib/storyboard.

The code can be copied to a new project. The file needs to be named main.swift. Also remove "Main interface" in the project settings.

// File: main.swift

import Cocoa

// AppDelegate

class AppDelegate: NSObject, NSApplicationDelegate {

  let window = NSWindow(
    contentRect: NSRect(x: 0, y: 0, width: 600, height: 400),
    styleMask: [ .titled, .closable, .resizable ],
    backing: .buffered,
    defer: false
  )

  func applicationDidFinishLaunching(_ aNotification: Notification) {
    let splitViewController = MySplitViewController()
    window.contentView = splitViewController.view
    window.makeKeyAndOrderFront(nil)
  }

}

// NSSplitViewController

class MySplitViewController: NSSplitViewController {

  convenience init() {
    self.init(nibName: nil, bundle: nil)
    // Left
    let viewController1 = NSViewController()
    viewController1.view = NSView()
    let item1 = NSSplitViewItem(viewController: viewController1)
    item1.minimumThickness = 100
    item1.maximumThickness = 200
    addSplitViewItem(item1)
    // Right
    let viewController2 = NSViewController()
    viewController2.view = NSView()
    let item2 = NSSplitViewItem(viewController: viewController2)
    addSplitViewItem(item2)
  }

  override func viewDidLoad() {
    super.viewDidLoad()
    print(splitView.delegate!)   // Logs "Project1.MySplitViewController"
  }

  // Never called
  override func splitView(_ splitView: NSSplitView, additionalEffectiveRectOfDividerAt dividerIndex: Int) -> NSRect {
    print("\(#function)")
    return super.splitView(splitView, additionalEffectiveRectOfDividerAt: dividerIndex)
  }

}

let application = NSApplication.shared
let applicationDelegate = AppDelegate()

application.delegate = applicationDelegate
application.run()

When running the code you can see that the split view shows up and works fine.

The viewDidLoad() method prints "Project1.MySplitViewController", so the delegate is set.

But the splitView(_:additionalEffectiveRectOfDividerAt:) method is not called (or any other NSSplitViewDelegate if implemented).

  • What are you doing to invoke that method? – koen Feb 10 '20 at 20:34
  • This method is a delegate method, so it is not to be invoked by my code. –  Feb 10 '20 at 20:37
  • I understand. So when do you expect that this method is called? User interaction? – koen Feb 10 '20 at 20:40
  • Why does this matter? Not one of the NSSplitViewDelegate methods is called. –  Feb 10 '20 at 20:43
  • 1
    Your sample doesn't work for me. "This is purely programmatically without nib/storyboard. The code can be copied to a new project" > "-[NSNib _initWithNibNamed:bundle:options:] could not load the nibName: View in bundle (null)." – TheNextman Feb 10 '20 at 21:17
  • 1
    Same here. @Elliot: please provide a [example]. – koen Feb 10 '20 at 22:30
  • I changed the code. –  Feb 11 '20 at 03:23

1 Answers1

2

The delegate method is not called because the MySplitViewController is released at the end of applicationDidFinishLaunching. Let AppDelegate hold a strong reference to the MySplitViewController.

Willeke
  • 14,578
  • 4
  • 19
  • 47