Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Jul 15, 2009, 02:09 PM   #1
petron
macrumors member
 
Join Date: May 2009
Location: Malmo, Sweden
Send a message via ICQ to petron
Hillegass chapter 12, Challenge "About panel" help needed

Hi,
I just went through the Challenge in chapter 15.

When ready with the "cahllenge" I do see the About panel only for a second or so. then it disapear.

I enable it in the following way in the AppController.m:

Quote:
- (IBAction)showAboutPanelid)sender {
NSLog(@"Entered showAboutPanel");

BOOL success = [NSBundle loadNibNamed:@"About" owner:self];

if (success)
NSLog(@"Success");
else
NSLog(@"Not Success");
}

I do not know what I need to do with the outlet...

IBOutlet NSPanel *aboutPanel;


I will try to go through it again, but I will appreciate some help.

BR
/petron

Last edited by petron; Jul 16, 2009 at 04:40 AM.
petron is offline   0 Reply With Quote
Old Jul 15, 2009, 02:51 PM   #2
petron
Thread Starter
macrumors member
 
Join Date: May 2009
Location: Malmo, Sweden
Send a message via ICQ to petron
Now it works...

I have created new NSWindowController for About Palne and modified the AppController.m in the following way:

Quote:
- (IBAction)showAboutPanelid)sender {
NSLog(@"Entered showAboutPanel");

BOOL success = [NSBundle loadNibNamed:@"About" owner:self];
if (success) {
NSLog(@"Success");
aboutController = [[AboutController alloc] initWithWindowNibName: @"About"];
[aboutController showWindow:self];
} else {
NSLog(@"Not Success");
}
}

/petron
petron is offline   0 Reply With Quote
Old Jul 16, 2009, 01:31 AM   #3
thingsis
macrumors newbie
 
Join Date: Oct 2008
Location: Germany
Hi,

actually this should be all you need:
Code:
-(IBAction)showAboutPanel:(id)sender {
	[NSBundle loadNibNamed:@"AboutPanel" owner:self];
	[aboutPanel setTitle:@"Outlet geht!"];
}
Of course you don't even need to set the title. I just used it to check whether my outlet is working fine. It seems pretty similar to what you are doing. It also works when I assign the result of the NSBundle... to a BOOL var - which makes it even closer to your example.

thingsis
__________________
2.4GHz Whitebook, 2 GB RAM, 160 GB HD ; 8 GB 4th Gen iPod nano ; MacMini 1.83GHz, 4GB RAM, 320 GB HD, Samsung 226bw
thingsis is offline   0 Reply With Quote
Old Jul 16, 2009, 01:51 AM   #4
petron
Thread Starter
macrumors member
 
Join Date: May 2009
Location: Malmo, Sweden
Send a message via ICQ to petron
Hello Tingsis

It seems that I did something very wrong.

I do not have any outlet at all, since I did not know how to connect the Outlet "aboutPanel" and to whom to connect.

Is it declared in the AppController.h like this ?

IBOutlet NSPanel *aboutPanel;

I did create a NSwindowController and it works but your solution seems to be more sexy... How did you solved the Outlet connection ?

/petron

Last edited by petron; Jul 16, 2009 at 04:43 AM.
petron is offline   0 Reply With Quote
Old Jul 16, 2009, 08:57 AM   #5
thingsis
macrumors newbie
 
Join Date: Oct 2008
Location: Germany
Hi,

you are almost right
Code:
IBOutlet NSWindow *aboutPanel;
It might also work using NSPanel. I do not have the object graph in my head. Also, in InterfaceBuilder you set File's Owner to AppController and connect the aboutPanel Outlet of File's Owner to the actual Panel. Then it should work.

Thingsis
__________________
2.4GHz Whitebook, 2 GB RAM, 160 GB HD ; 8 GB 4th Gen iPod nano ; MacMini 1.83GHz, 4GB RAM, 320 GB HD, Samsung 226bw
thingsis is offline   0 Reply With Quote
Old Jul 16, 2009, 08:59 AM   #6
thingsis
macrumors newbie
 
Join Date: Oct 2008
Location: Germany
Hi again,

I just thought about it again...
Maybe the problem is not the actual outlet but that you forgot to set a class for File's Owner. Just an idea. Anyway, my post above is still valid I guess.

Thingsis
__________________
2.4GHz Whitebook, 2 GB RAM, 160 GB HD ; 8 GB 4th Gen iPod nano ; MacMini 1.83GHz, 4GB RAM, 320 GB HD, Samsung 226bw
thingsis is offline   0 Reply With Quote
Old Jul 16, 2009, 09:11 AM   #7
SRossi
macrumors regular
 
Join Date: May 2009
Location: Glasgow, Scotland
Quote:
Originally Posted by thingsis View Post
Hi,

you are almost right
Code:
IBOutlet NSWindow *aboutPanel;
It might also work using NSPanel. I do not have the object graph in my head. Also, in InterfaceBuilder you set File's Owner to AppController and connect the aboutPanel Outlet of File's Owner to the actual Panel. Then it should work.

Thingsis
When I did that challenge I didn't have any Outlets I did exactly the same as what happened during the chapter my AppController.h file is:

Code:
@class PrefrenceController;
@class AboutController;

@interface AppController : NSObject {
	PrefrenceController *prefrenceController;
	AboutController *aboutController;
}
- (IBAction)showPrefrencePanel:(id)sender;
- (IBAction)showAboutPanel:(id)sender;

@end
Then I implemented the AboutController file's which opened the nib.

Hope this helps.

Stephen

Edit: Also you make the File Owner the class of your AboutController. Not the AppController.

Edit again: About adding the outlet you would point it to NSPanel not NSWindow. Should work after that.
__________________
macMini, 2.0 GHz Core 2 Duo, 1 GB RAM, 120GB hd;
Dell S2209W 21.5" monitor;
iPhone 4GS 16GB;
30 GB iPod video;

Last edited by SRossi; Jul 16, 2009 at 09:50 AM.
SRossi is offline   0 Reply With Quote
Old Jul 16, 2009, 09:14 PM   #8
petron
Thread Starter
macrumors member
 
Join Date: May 2009
Location: Malmo, Sweden
Send a message via ICQ to petron
Hi,
I wake up early and needed to try....

First answer to Stephen..
Well, both you and I went through the same path with very small differences. It of course works but it is not as sexy as the solution that Thingis made and what the Hillegass had in mind. The Hillegass in his "Challenge" description specified the use of an Outlet. Any way thanks for comments.

Secondly answer to Thingis..
Thanks for the tips regarding the "you set File's Owner to AppController"
After I done this the possibility to connect the Outlet became obvious and possible.

Here is the actual method, it looks even better if one does not need to change the title of the panel window. It even could be one_liners method if I will drop the NSLog lines.

Quote:
- (IBAction)showAboutPanel : (id)sender {
NSLog(@"Entered showAboutPanel");

BOOL success = [NSBundle loadNibNamed:@"About" owner:self];
if (success) {
NSLog(@"Loaded nib");
} else {
NSLog(@"Not able to load nib");
}
}
The last comment is that I think that you should use the NSPanel and not NSWindow. Both solutions works but the NSPanel is more correct class.

Any way thanks to all for the help and cooperation. The most important thing is that I learned something new and maybe I understand the subject a bit better.

/petron
petron is offline   0 Reply With Quote
Old Aug 16, 2009, 07:35 PM   #9
beebauman
macrumors newbie
 
Join Date: Feb 2009
I believe that the objective of the challenge was to avoid using an NSWindowController (Hillegass wants you to understand what the controller is doing for you behind the scenes, and how to do it yourself if you don't use one). The purpose of setting the outlet is to enable the AppController to know about and message the about panel. Here is what you do when the user selects the "About" option from the menu:

1) Load the NIB (but only if it hasn't already been loaded)
2) Tell the about panel not to release itself when the window is closed
3) Display the about panel again if it has been closed

Relevant code:

AppController.h:

@interface AppController : NSObject {
IBOutlet NSPanel *aboutPanel;
BOOL aboutNibWasLoaded;
}

- (IBAction)showAboutPanelid)sender;

AppController.m:

- (IBAction)showAboutPanelid)sender
{
if ( aboutNibWasLoaded == 0 ) {
aboutNibWasLoaded = [NSBundle loadNibNamed:@"About" owner:self];
[aboutPanel setReleasedWhenClosed:NO];
}

if ( ! [aboutPanel isVisible] )
[aboutPanel makeKeyAndOrderFront:self];
}
beebauman is offline   0 Reply With Quote
Old Aug 16, 2009, 10:39 PM   #10
mdeh
macrumors 6502
 
Join Date: Jan 2009
Quote:
Originally Posted by beebauman View Post
I believe that the objective of the challenge was to avoid using an NSWindowController (Hillegass wants you to understand what the controller is doing for you behind the scenes, and how to do it yourself if you don't use one).
Yes...makes perfect sense now. I too wondered what the purpose of the outlet was.

Here's my code....taking most from yours.

Code:
-(id) init
{
	
	self = [ super init];
	nibIsLoaded = NO;
	return self;
	
}
 



-(IBAction) showPanel: (id) sender
{
	if ( nibIsLoaded== NO){
		{
		nibIsLoaded = [NSBundle loadNibNamed: @"About" owner: self];
		[aboutWindow setReleasedWhenClosed:NO];
		}
	if ( !nibIsLoaded)
		NSLog(@"Could not load custom About window");
		
	 }
	
	else 
		if ( nibIsLoaded)
	
	{
		NSLog(@"Custom \"About window\" already open");
		[aboutWindow makeKeyAndOrderFront:self ];
	}
}
	
-(void) dealloc
{
	if (nibIsLoaded == YES)
	[aboutWindow release];
	[super dealloc];
}

Last edited by mdeh; Aug 16, 2009 at 11:39 PM.
mdeh is offline   0 Reply With Quote
Old Oct 4, 2009, 12:14 PM   #11
Pommade
macrumors newbie
 
Join Date: Oct 2009
Hi here is another solution

First of All, in the Interface Builder :

- uncheck the 'Release When Close' in the Behavior group of Window menu of the Panel Attributes, in the inspector window.

- then in the 'File's Owner' identity, just add 'aboutPanel' in the class outlet table view (click plus button); let the type set to id.

Save your nib file then leave the IB.

Now, let's examin the code. In bold are the piece i added for this challenge.

AppController.h
Code:
#import <Cocoa/Cocoa.h>
@class PreferenceController;

@interface AppController : NSObject {
	PreferenceController *preferenceController;
	IBOutlet NSPanel *aboutPanel;
}
- (IBAction)showPreferencePanel:(id)sender;
- (IBAction)showAboutPanel:(id)sender;
@end
Now let's see the showAboutPanel method :

in AppController.m
Code:
#import "AppController.h"
#import "PreferenceController.h"


@implementation AppController

- (IBAction)showPreferencePanel:(id)sender
{...}

- (IBAction)showAboutPanel:(id)sender
{

       // if my nib wasn't loaded, my aboutPanel is nil, then that means i
        // have to load the nib
	if (!aboutPanel) {
		BOOL succes = [NSBundle loadNibNamed:@"About" owner:self];

                // if it succed, Appcontroller becomes the file's owner and
                // aboutPanel is linked (set in the IB previously in the file's
                // owner attributes). Otherwise, i get a messsage of failure in
                // the console
		if (!succes) {
			NSLog(@"Failure loading the about panel nib file");
		}
	} else {
                // the other case is that the panel is existing, so we just
                // bring it to the front.
		[aboutPanel makeKeyAndOrderFront:self];
	}
}

@end
If any question...

Last edited by Pommade; Oct 7, 2009 at 06:00 AM.
Pommade is offline   0 Reply With Quote
Old Oct 20, 2009, 07:46 AM   #12
Darkroom
Guest
 
Join Date: Dec 2006
Location: Montréal, Canada
Quote:
Originally Posted by Pommade View Post
Code:
- (IBAction)showAboutPanelid)sender
{

// if my nib wasn't loaded, my aboutPanel is nil, then that means i
// have to load the nib
if (!aboutPanel) {
BOOL succes = [NSBundle loadNibNamed:@"About" owner:self];

// if it succed, Appcontroller becomes the file's owner and
// aboutPanel is linked (set in the IB previously in the file's
// owner attributes). Otherwise, i get a messsage of failure in
// the console
if (!succes) {
NSLog(@"Failure loading the about panel nib file");
}
} else {
// the other case is that the panel is existing, so we just
// bring it to the front.
[aboutPanel makeKeyAndOrderFront:self];
}
}
if you've unchecked "Release When Closed" in IB, the above code will not display your custom panel again if it is closed after being once opened. it's ideal to only load the XIB once while simply showing it if has been loaded.

Code:
- (IBAction)showAboutPanel:(id)sender
	{
	if (!aboutPanel)
		{
		NSLog(@"load then display");
		[NSBundle loadNibNamed:@"About" owner:self];
		[aboutPanel makeKeyAndOrderFront:self];
		}
		else
		{
		NSLog(@"only display - has already been loaded");
		[aboutPanel makeKeyAndOrderFront:self];
		}
	}
Darkroom is offline   0 Reply With Quote
Old Oct 21, 2009, 03:58 AM   #13
Pommade
macrumors newbie
 
Join Date: Oct 2009
Misunderstanding

Hi.

I think there's a misunderstanding, Darkroom. When i write :
Quote:
First of All, in the Interface Builder :

- uncheck the 'Release When Close' in the Behavior group of Window menu of the Panel Attributes, in the inspector window.
it means that i don't want that the panel release itself when it recieving a close message( typically posted when hitting the little red close button on the top left of the panel).

What does it imply? It implies that when the panel is 'closed', its behavior is not anymore : "Free the memory zone it was using";
but now its : "Only hide its view".
It implies too that when the panel is closed, its outlet (translate by the pointer pointing on this object) still pointing on a still used memory zone, and not anymore on a freed memory zony which could contain anything else.


So then let's resume :
- the about panel i 've made only hide itself when the close button is hit.

Next, i did this following step :
Quote:
- then in the 'File's Owner' identity, just add 'aboutPanel' in the class outlet table view (click plus button); let the type set to id.
I hope that you understood that my intention was to tell my panel that its futur owner (wathever it will be) will have a outlet pointing on itself. In this case, the file's owner is going to be AppController, so i only have to declare the outlet in its header (which is one Aaron Hillegass directive for this challenge).


Now let 's run on paper this little piece of code.

i launch the Raisman app, and my controller class is initialized; during this initialisation, the outlet pointing on my about panel point on nil.
It happens what happens, and i click on "show about panel" in my menu. It calls the showPanel:sender method (if i've correctly linked my Menu Item Target).
Let's see what happens:
First of all i test my AppController outlet aboutPanel :
Quote:
if (!aboutPanel)
. It s the first time i launch this method, so my aboutPanel still pointing on nil, which means (!aboutPanel) = YES, so i go to the statement.
In this statement, i load the nib, and i link to it AppController.
Quote:
BOOL succes = [NSBundle loadNibNamed:@"About" owner:self];
If the loading is a succes, my About Panel is unarchived, shown and the file's owner link its outlet aboutPanel to the About Panel. So then the outlet aboutPanel of AppController points now on the About Panel.

If the nib can't be load if print a message of failure in the console.
Quote:
if (!succes) {
NSLog(@"Failure loading the about panel nib file");
}
That 's what happens when the showAboutPanel:sender is first called.

At this point, now my About Panel is in on front and the outlet aboutPanel points on it and it's not nil.

Then I decide to close the About Panel. After hit the close buton, the panel is no more visible, but it still residing in memory, according the behavior we impose to it. So then my outlet still pointing on a active memory zone well defined.

Further in time, i decide to it again the menu item "Show about Panel"

Let's see what happens in showAboutPanel:sender method:
I test again my outlet ,
Quote:
if(!aboutPanel)
but this time aboutPanel is no more nil, it's value is the address of the About Panel(which still existing in memory), so (!aboutPanel) = NO; so then i go to the else statement and i unhide my About Panel, and put it in front :
Quote:
[aboutPanel makeKeyAndOrderFront:self];
I close again my About Panel, it will not release my Panel, and my outlet will point again on the well defined piece of memory occupied by the About Panel. And So on, And so on.

Let me correct your piece of code, will you.
In your if statement,
Quote:
if (!aboutPanel)
{
NSLog(@"load then display");
[NSBundle loadNibNamed:@"About" owner:self];
[aboutPanel makeKeyAndOrderFront:self];
}
(...)
Calling [aboutPanel makeKeyAndOrderFront:self]; is redundant, because when you load your nib, instances are created and when our about panel is created, its default behavior is to be on front of our app (it's acting like a basic panel).

Anyway, i hardly recommand you to try my piece of code. It works on my mini-mac mac os x 10.5.8.
Your piece of code is valid, but i say that it is not well optimized according me.

Sincerely, me.
Pommade is offline   0 Reply With Quote
Old Jan 13, 2011, 02:51 PM   #14
hubrisForAll
macrumors newbie
 
Join Date: Jan 2011
Location: Houston
Question about BOOL success

Is the point of using BOOL success = .....

only so that you can test if you successfully loaded the nib file?

As is, my code:

Code:
if (!aboutPanel) {
[NSBundle loadNibNamed:@"About" owner:self];
}
else {
[aboutPanel makeKeyAndOrderFront:self];
}
With File's Owner as my AppController (not a window Controller), and aboutPanel an outlet to my panel titled "About."

Also - according to Apple Documentation, an NSPanel's default behavior is to NOT release when sent the message [panel close] - this is however not consistent with the "Release on close" checkbox being on by default in Interface Builder. Odd?
hubrisForAll is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Tim Cook: "North America was a challenge. We had no growth" easy-peasy Apple, Industry and Internet Discussion 41 Feb 12, 2014 09:21 PM
Delete button needed in App Store "updates" tab lazybump91 iOS 7 33 Aug 27, 2013 08:17 PM
challenge for the "iPundit" (i meaning != idiot .ok). Flv player that has playlists.. Seget007 iOS 6 0 Jun 11, 2013 02:29 PM
The PowerBook G3 "Lombard" running OS X Public Beta Challenge AlbertEinstein PowerPC Macs 11 Feb 18, 2013 04:59 PM
rMBP "ghosting/retention" experience and seeking advice needed! theuserjohnny MacBook Pro 6 Jul 8, 2012 12:14 AM

Forum Jump

All times are GMT -5. The time now is 01:31 PM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC