Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Spike099

macrumors regular
Original poster
Feb 18, 2007
143
0
Canada
So this is my noobish problem.

The situation:

2 NIBs:
MainMenu
AddPersonPanel

Within MainMenu contains an instance of appController, appController contains an variable for AddPersonController. When a button is pressed on the window of mainmenu, it shows the panel of AddPersonPanel. AddPersonPanel is a custom class of AddPersonController.

So, when I click the add button in the AddPersonPanel, it calls the add function in AddPersonController. I have a NSImage within this class that I need to be passed to the appController.

I have tried making an instance of appController in the AddPersonPanel and linking the add button to the add function in appController, but it never executes.

How can I return the image to the appController, or call a function from appController and pass it a variable.

Thanks guys, let me know if this needs more detail or even some code.
 

zedLondon

macrumors member
Jun 25, 2007
44
0
London
Not really sure I understand what you're after, and as a noob myself, take all this with a pinch of salt.

When I needed to pass something to a new item within an arrayed controller, I created a subclass of NSArrayController and reimplemented the -(id)newObject method.

I also added IBOutlets for the UI controls that would act as the inputs for the info. In my case text boxes, In yours the image. Then linked these in IB

In my reimplemented newObject, I then passed the values to the new object to set it up.

In your app controller have your array controller be of the type of your subclassed array controller, and in IB change the custom class of the declared instance of the array controller to your sub classed version.

That way when you use the add method, the correct info is passed.

I'm sure that's all very badly explained.
 

garethlewis2

macrumors 6502
Dec 6, 2006
277
1
It sounds like he doesn't actually want to send the NSImage to window, but the otherway round. And you can't do that with IB.

There are a variety of ways. You could add a sheet, and call the sheet. When the sheet ends, a method is called you can use to retrieve the data.

The other way is probably similar to what you are currently doing. You press a button which sends an event to what ever method you have in your main class to do something. You show the screen. You need to show it as a modal screen, so you can retrieve data afterwards. I can't remember the code for this, it isn't difficult.

Or use NSDocument in a bizarre and twisted way.
 

Eraserhead

macrumors G4
Nov 3, 2005
10,434
12,250
UK
So this is my noobish problem.
Thanks guys, let me know if this needs more detail or even some code.

I'm not convinced that subclassing NSArrayController or using a sheet is the best way to pass this image.

In my experience you only need to subclass stuff when absolutely necessary, and in this case I don't think it's needed.

You may find CoreData would be a good approach for what you are doing, then you can store the image in an NSManagedObject and then you can use valueForKey to recover it.

It would probably be helpful for you to post the project file so we can take a look, I for one am very confused about what you are trying to do, so this post probably doesn't make sense.

If you don't want to post the source, send me a PM with it, or describe what you want to do, not which classes you are using as that will enable us to help you better.
 

Spike099

macrumors regular
Original poster
Feb 18, 2007
143
0
Canada
Hey, I will do so when I get home... Still another 7 hours before that though.

Thanks for your input guys. I will have to read up about Core Data in the meantime.
 

whooleytoo

macrumors 604
Aug 2, 2002
6,607
716
Cork, Ireland.
If I understand the problem correctly: you have two objects, appController and AddPersonController, and you want the add method in AddPersonController to pass an NSImage to appController. Is that right?

If so, you just need to add an IBOutlet to AddPersonController, and connect it to appController. Then simply add a
Code:
-(void) setImage:(NSImage*) theImage;
method to appController and call that from the add method in AddPersonController.

(From your message, it seems the two objects might be in two different nibs. I don't know if you can connect outlets between nibs, but I'm guessing you can).
 

Spike099

macrumors regular
Original poster
Feb 18, 2007
143
0
Canada
Yeah, I don't think that is possible.

The issue is that appController is initialized in MainMenu. So when I initialize the new NIB, I would have to pass it a pointed to the appController so that I can call it's methods.

In appController I tried

Code:
[addPersonController showWindow2:self];

In addPersonController I had

Code:
- (void)showWindow2:(id)sender
{
 appController = sender;
 [self showWindow:self];
}

As I go on about this, I forget what happened. I'm pretty sure this did not work. I will have to further test this when I get home.

From the responses, there is alot I can try in attempt to achieve this. However, it may be more beneficial to keep the panel in the same NIB anyway.
 

whooleytoo

macrumors 604
Aug 2, 2002
6,607
716
Cork, Ireland.
There's a good chance the code you posted would crash. If appController is a member/instance variable of AddPersonController, you need to retain the pointer in that method. Something like:

Code:
- (void)showWindow2:(id)sender
{
    if (appController != sender)
    {
        [appController release];
        appController = [sender retain];
    }
    [self showWindow:self];
}

That may or may not be the problem, but it's something to be aware of. Feel free to post the code/project or snippets if you'd like us to take a look.
 

Spike099

macrumors regular
Original poster
Feb 18, 2007
143
0
Canada
whooleytoo, I will definitely post the code tonight. Don't have access to my Mac from here :(.
 

Krevnik

macrumors 601
Sep 8, 2003
4,101
1,312
From the responses, there is alot I can try in attempt to achieve this. However, it may be more beneficial to keep the panel in the same NIB anyway.

Windows and their panels should probably be in the same NIB. Otherwise you get to do the dirty work of figuring out how to get objects from the loaded NIB.

For smaller apps, I would say the rule of thumb is: Main Window and its panels/sheets should be in one NIB (or Document Window), and things like a Preferences window should get its own NIB (since it should just hook into UserDefaults).
 

Spike099

macrumors regular
Original poster
Feb 18, 2007
143
0
Canada
Okay I got it working. I was thinking of using a sheet to perform this task but had not yet looked into making sheets. So... I am displaying the panel(now a window) using a sheet. Now that I can pass the image, a whole new series of problems have been presented with resizing and cropping :D . I'm sure you'll all be hearing about them soon enough.

In my adventures I found:

Code:
[NSBundle loadNibNamed: @"MyCustomSheet" owner: self];

I have not looked into this yet. But from the look of it I can load a sheet from another NIB using the current window as it's owner. If I ever really want the sheet in another NIB, maybe NSBundle is where I should be looking.

Thanks guys for helping me out. Much appreciated.
 

Nutter

macrumors 6502
Mar 31, 2005
432
0
London, England
Yes, that's right. It's a good idea to put the sheet in a separate nib, so that you can delay loading it into memory until you actually need it. Your custom window or window controller can be the owner of the nib.

It's true that (as Krevnik says) putting each window, sheet, panel etc into its own nib restricts the connections you can make in interface builder, but that can actually be a good thing as it forces you to keep your objects in a hierarchy rather than a spaghetti.
 

Spike099

macrumors regular
Original poster
Feb 18, 2007
143
0
Canada
Now loading Nib

Alright I now have my sheet in a separate Nib as my appController was just getting too messy. The nib file is been loaded via NSNib

In appController.h
Code:
NSArray *addPersonPanel;

In appController.m
Code:
- (IBAction)openSheet:(id)sender
{
	addPersonPanel = [self loadMyNibFile];
	[NSApp beginSheet:[addPersonPanel ***********]
	   modalForWindow:mainWindow
		modalDelegate:self
	   didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
		  contextInfo:NULL];
}

- (NSArray*)loadMyNibFile
{
    NSNib*      aNib = [[NSNib alloc] initWithNibNamed:@"AddPersonPanel" bundle:nil];
    NSArray*    topLevelObjs = nil;
	
    if (![aNib instantiateNibWithOwner:self topLevelObjects:&topLevelObjs])
    {
        NSLog(@"Warning! Could not load nib file.\n");
        return nil;
    }
	[aNib release];
	
        [topLevelObjs makeObjectsPerformSelector:@selector(release)];
	
	return topLevelObjs;
}

I really just don't understand top level objects, I know it's everything contained in the Nib(minus file owner and first responder). However how do I know what index to issue my actions.

Ex, where ********* is in the method opedSheet.
 

Eraserhead

macrumors G4
Nov 3, 2005
10,434
12,250
UK
Each nib file needs to have a separate controller, it should be a subclass of NSWindowController.

In that Controller you have an init method which looks like this, where NewNib is the name of the nib file you are trying to load:
Code:
-(id)init{
	[super init];
	[NSBundle loadNibNamed:@"NewNib"
					 owner:self];
	//more custom code goes in here.
	return self;
}


With regards to this [addPersonPanel ***********] piece of code I have no idea what you are trying to do, you can only load one sheet at a time.
 

Spike099

macrumors regular
Original poster
Feb 18, 2007
143
0
Canada
Okay, so my variable in appController.h should be

Code:
NSWindowController *addPersonPanel

then initialize in appController.m and load sheet like this?

Code:
addPersonPanel = [[NSWindowController alloc] init];
	[NSApp beginSheet:addPersonPanel
	   modalForWindow:mainWindow
		modalDelegate:self
	   didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
		  contextInfo:NULL];

This makes sense to me. I was going through a tone of documentation and some examples, but nothing ever said to make the nib's file owner a NSWindowController. Nor did they say to put the init code in the Nib file it's self.

I'll have to wait and try when I get home. Thanks.
 

Eraserhead

macrumors G4
Nov 3, 2005
10,434
12,250
UK
You still are barking up the wrong tree, you beginSheet on the IBOutlet pointing to the window in the NSWindowController.

Go and read chapter 22 of the Aaron Hillegass book, it explains sheets perfectly well.

If you don't own a copy of it, I suggest that you buy it.
 

Spike099

macrumors regular
Original poster
Feb 18, 2007
143
0
Canada
Okay I got it working finally. The whole Nib thing through me off and was causing me to forget other things. Thanks for your patience Eraserhead.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.