October 11th, 2015
I struggled with how to pass data between view controllers in a Mac storyboard show segue so I’m detailing how I solved the problem here. I hope it helps others who have a similar problem.
Short version: a show segue involves window controllers, not view controllers. Implement
prepareForSegue in a
I’m writing a document-based application that generates PDF files. I want to preview the document’s PDF inside the application. In the storyboard I create a window controller and a view controller for the preview window. In the document window’s toolbar I have a Preview item. I create a segue to show the preview window when the Preview item is clicked. From a user interface perspective, everything works. I click the Preview item in the toolbar, and the preview window opens.
The next step is to get the preview window to show a PDF file. In my
NSDocument subclass I have a
preview method that creates a PDF file and returns a URL for that PDF file. In the
NSViewController subclass for the preview window’s view controller, I have a method that accepts a URL as an argument, creates a
PDFDocument object using the supplied URL, and tells the PDF view to use that
How do I pass the URL containing the PDF file from my
NSDocument subclass to the preview window’s view controller? Implement
I ran into problems figuring out where to implement
prepareForSegue. My first attempt was to implement it in the preview window’s view controller. The problem was that
prepareForSegue was not being called. I set a breakpoint inside
prepareForSegue, and the breakpoint was never reached.
I asked about this on Apple’s developer forums, and someone suggested I implement
prepareForSegue in the document window’s view controller. It was an excellent suggestion, but
prepareForSegue was still not being called. What’s the problem?
After much struggle I learned that the source and destination controllers for a show segue are window controllers, not view controllers. The solution was to create a
NSWindowController subclass for the document window and implement
prepareForSegue there. It worked.
prepareForSegue was being called.
In my implementation of
prepareForSegue, I used the
contentViewController property of
NSWindowController to access the document view controller so I could access the document, call its
preview method, and get the URL for the PDF file. I used the segue’s
destinationController property to access the preview window’s window controller. I used the
contentViewController property a second time to access the preview window’s view controller so I could pass the PDF’s URL to it.
I have not worked with iOS storyboards. If you ask me a question about them in a comment, I will not reply because I have no answer for you.
I am no expert on Mac storyboards. I will do my best to answer any questions about them, but there’s a decent chance the only answer I can provide is “I don’t know”.