Blasmo
Blasmo

Reputation: 518

SwiftUI: NSPageController in NSViewControllerRepresentable crashes

Im' trying to put a NSPageController in a SwiftUI NSViewControllerRepresentable programatically, but when the app runs, it crashes with the following error:

 -[NSNib _initWithNibNamed:bundle:options:] could not load the nibName: test.PageController in bundle (null).

This is the smallest example I could think off to demonstrate the problem:

PageView:

struct PageView: NSViewControllerRepresentable {
    
    let data = ["green", "blue", "red"]
    
    typealias NSViewControllerType = PageController
    
    func makeNSViewController(context: Context) -> PageController {
        let pageController = PageController()
        pageController.arrangedObjects = data
        pageController.delegate = pageController
        return pageController
    }
    
    func updateNSViewController(_ nsViewController: PageController, context: Context) {
        
    }
    
}

PageController:

class PageController: NSPageController, NSPageControllerDelegate {
    
    func pageController(_ pageController: NSPageController, identifierFor object: Any) -> NSPageController.ObjectIdentifier {
        return (object as? String) ?? "green"
    }
    
    func pageController(_ pageController: NSPageController, viewControllerForIdentifier identifier: NSPageController.ObjectIdentifier) -> NSViewController {
        let rootView: Color
        switch identifier {
        case "green":
            rootView = .green
        case "red":
            rootView = .red
        default:
            rootView = .blue
        }
        return NSHostingController(rootView: rootView)
    }
    
}

So far I tried creating custom initialisers that call super.init(nibName: nil, bundle: nil) on NSPageController, but that didn't work either. Ive also tried overwriting 'loadView', but I still didn't get it to work.

I did find that the app crashes in the loadView call of the NSPageController inside the makeNSViewController call.

Upvotes: 3

Views: 981

Answers (1)

JuJoDi
JuJoDi

Reputation: 14975

The convenience initializer for NSViewControllers by default try to load their views from nib.

You need to override loadView and actually supply a view to the Page Controller

override func loadView() {
        self.view = NSView() // the view being controlled
}

Upvotes: 3

Related Questions