Re: Could not connect the action to target of class
Re: Could not connect the action to target of class
- Subject: Re: Could not connect the action to target of class
- From: Sherm Pendley <email@hidden>
- Date: Sat, 12 Mar 2005 13:42:07 -0500
On Mar 12, 2005, at 8:23 AM, Hamish Allan wrote:
On Mar 11, 2005, at 22:13, Sherm Pendley wrote:
If you're working with a complex app that needs multiple window
controllers, or a subclass of NSWindowController, override
-makeWindowControllers in your document class and create the
controllers there.
I don't need multiple window controllers, but would you agree with me
that I need a view-controller?
I think we're referring to the same thing by different names. I call it
a "window controller" because that's the class it's derived from,
you're calling it a "view controller" because that's the role it plays
in your app design - but we're really talking about the same object.
Sorry for the confusion!
You don't need multiple window controllers, but it sounds like you do
want a subclass of NSWindowController that has the outlets & actions
you need. When it needs to access the document object that owns it,
simply use [self document].
In other words, create an NSWindowController subclass. Add the outlets
and actions to it that you need for your view controller. Assign the
"File's Owner" class to your subclass - we'll call it
"MyViewController" - in IB, and make all the connections to/from
"File's Owner" instead of instantiating an object.
Then, in your document class, delete the -windowNibName and override
-makeWindowControllers instead, with something like this:
- (void) makeWindowControllers {
MyViewController *vc = [[MyViewController alloc]
initWithWindowNibName: @"MyDocument"];
[self addWindowController: vc];
}
There's two key difference in the above from the default implementation
- when the default implementation creates a window controller, it gets
the name of the Nib to load by calling -windowNibName, which is the
method you usually override. And, it initializes the window controller
with -initWithWindowNibName:owner:, to make the document object the
owner of the Nib. The above uses a hard-coded Nib name, and it doesn't
specify a Nib owner, which means the view controller will be the Nib's
owner.
You have two options for handling action messages. If you connect them
to the "File's Owner" in IB, they'll go the the view controller; it
could use [self document] to get its parent document when it needs to
forward messages it doesn't want to handle for itself. Or, since the
document object is part of the responder chain, you could send messages
to "First Responder" instead. The first option is good if you want your
view controller to do something in addition to sending a message to the
document, such as tell some view objects to update themselves.
It seems to me that it's my view-controller that wants access to all
these GUI elements, so if I instantiate it programmatically I'm going
to have to pass it all the IBOutlets from my NSDocument subclass,
which then has no further use for them. This seems wrong, which is why
I want to instantiate it in IB and connect it all up there.
You have the right idea, as far as splitting up your controller layer
into separate model and view controllers. It's just that, in a
document-based app, you usually want to create the view controller(s)
in -makeWindowControllers. When you do it that way, and call
-addWindowController:, NSDocument will automatically make itself the
delegate of the view controller, keep track of the active view
controllers, and so forth.
So is it not possible to instantiate and connect view-controllers from
within IB at all?
It's possible, I'm sure. But it runs "against the grain" of the
document architecture, so it'd be more work.
sherm--
Cocoa programming in Perl: http://camelbones.sourceforge.net
Hire me! My resume: http://www.dot-app.org
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden