Jump to content

iPhone SDK - Interface Builder Tutorial


115 posts in this topic

Recommended Posts

This is just a quick jump-start to using Interface Builder with Cocoa Touch apps and Xcode. Since the documentation offers no explanation of how to do this, I thought this may be helpful.

  1. Create a new Cocoa Touch project in Xcode.
  2. You should be presented with the main window, you can ignore this for now. Open Interface Builder. The New Document window will open, select Window in the fourth tab.
    picture1bu9.png
  3. Now just add whatever you want from the library to your view. Save the view to the directory of your recently created Xcode project as "MainWindow", and it should ask if you if you wish to add it to the project. Check the box next to the app name you just created, and hit Add.
  4. Go back to Xcode, and open up <your_app_name>appDelegate.m. It should look like:
    #import "SDK_IB_TestAppDelegate.h"
    #import "MyView.h"
    
    @implementation SDK_IB_TestAppDelegate
    
    @synthesize window;
    @synthesize contentView;
    
    - (void)applicationDidFinishLaunching:(UIApplication *)application {	
    // Create window
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    
    // Set up content view
    self.contentView = [[[MyView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
    [window addSubview:contentView];
    
    // Show window
    [window makeKeyAndVisible];
    }
    
    - (void)dealloc {
    [contentView release];
    [window release];
    [super dealloc];
    }
    
    @end


     

  5. We need to remove all the extra view code, and load our XIB. Edit the applicationDidFinishLaunching: method to look like this:
    - (void)applicationDidFinishLaunching:(UIApplication *)application {	
    // Create window
    self.window = [[[NSBundle mainBundle] loadNibNamed:@"MainWindow" owner:self options:nil] objectAtIndex:0];
    
    // Show window
    [window makeKeyAndVisible];
    }


     

  6. Build and Go. Your new iPhone App should be using the XIB you just made.

Hope this gets people started with Interface Builder.

Link to comment
Share on other sites

This is just a quick jump-start to using Interface Builder with Cocoa Touch apps and Xcode. Since the documentation offers no explanation of how to do this, I thought this may be helpful.
  1. Create a new Cocoa Touch project in Xcode.
  2. You should be presented with the main window, you can ignore this for now. Open Interface Builder. The New Document window will open, select Window in the fourth tab.
    picture1bu9.png
  3. Now just add whatever you want from the library to your view. Save the view to the directory of your recently created Xcode project as "MainWindow", and it should ask if you if you wish to add it to the project. Check the box next to the app name you just created, and hit Add.
  4. Go back to Xcode, and open up <your_app_name>appDelegate.m. It should look like:
    #import "SDK_IB_TestAppDelegate.h"
    #import "MyView.h"
    
    @implementation SDK_IB_TestAppDelegate
    
    @synthesize window;
    @synthesize contentView;
    
    - (void)applicationDidFinishLaunching:(UIApplication *)application {	
    // Create window
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    
    // Set up content view
    self.contentView = [[[MyView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
    [window addSubview:contentView];
    
    // Show window
    [window makeKeyAndVisible];
    }
    
    - (void)dealloc {
    [contentView release];
    [window release];
    [super dealloc];
    }
    
    @end


     

  5. We need to remove all the extra view code, and load our XIB. Edit the applicationDidFinishLaunching: method to look like this:
    - (void)applicationDidFinishLaunching:(UIApplication *)application {	
    // Create window
    self.window = [[[NSBundle mainBundle] loadNibNamed:@"MainWindow" owner:self options:nil] objectAtIndex:0];
    
    // Show window
    [window makeKeyAndVisible];
    }


     

  6. Build and Go. Your new iPhone App should be using the XIB you just made.

Hope this gets people started with Interface Builder.

 

Danke stroke. This new build is confusing as hell!

Link to comment
Share on other sites

I'm trying a simple example - I just put up a label and a button, modify MyView to extend NSObject and added an action "changeText:" and an outlet "label".

Added an object controller in IB, change class to MyView, connected outlet label to my label and the event "Touch Up Inside" (also tried all the other events) with the action changeText. The action basically does a printf and [label setText: @"It works"];

I cannot run it, the sim crashes when i push the button. Any ideas why ? The problem definitely is not from the action code (i tried with no code :)), but from the connection. Did i do something wrong ?

 

Thx,

M

Link to comment
Share on other sites

Brilliant little jump-start tutorial - one for the newbies (like me). I find that once I can actually drop something like a button on to the interface and get that up and running (albeit in the simulator), I've got enough to get going with.

 

Thanks very much!

Link to comment
Share on other sites

This is just a quick jump-start to using Interface Builder with Cocoa Touch apps and Xcode. Since the documentation offers no explanation of how to do this, I thought this may be helpful. ... Hope this gets people started with Interface Builder.

 

Fantastic! Brilliant!! Well done old man!!!

 

I'd never consider calling myself a real developer, at best I'm a code hacker (since thats what I do) and with the (lack of) knowledge to back that up! Well, anyway, these kinds of 'leg ups' are *really* helpful in keeping me moving forward with the stuff I'm (trying to) play with. Now it pains me to learn that UI bindings do not seem to be a part of the iPhone world (not as of today at least)... Welcome back to the joyful world of writing glue code... :trumpet:

 

Dave

Link to comment
Share on other sites

For those with the crashing problem, have you checked the console? What sort of error is it? By looking at the example code one of you pasted above, it looks like it could be an unrecognized selector (setText:). Try label.text = @"It works". I'll check it out myself, though.

Link to comment
Share on other sites

It's not the way the text is set that is the problem, because if you comment it out and leave an empty action then it still crashes. Console says...

 

28/03/2008 19:24:00 launchd[157] launchd(157,0xa040afa0) malloc: *** error for object 0x800003: Non-aligned pointer being freed*** set a breakpoint in malloc_error_break to debug

 

If someone has a working example project of just a simple UI with a button and a label that works without crashing then could you please upload your project somewhere so that I, and others, can compare in order to find out if it's something we're doing or if it's our installation that's messed up.

 

It's definitely the connector. As soon as I remove the connector from the button to my class it no longer crashes. Put the connector back, even with an empty stub, and it starts crashing.

Link to comment
Share on other sites

Ah, yes, I see what you mean… perhaps it is in the set up of the methods? It may not follow the -(void)action:(id)sender; convention, I guess we'll have to wait until the docs are updated.

 

Yes, just seems odd that Apple would release the new beta without the documentation being ready if they knew everyone would rapidly run into this problem. I can't help but feel it's either a bug or I'm missing something obvious.

Link to comment
Share on other sites

OK

 

I have made it work guys ..

The problem was the controller....

Basically, drop a view into the window, make it of custom class MyView, where MyView : UIView (!) and add there the outlets and actions. Connect the button and label and now it will work.

The only way i could make something work was to add a view to the window and customize that view. Separate controllers are not made instances, i dunno why.

 

I still have some problems though:

 

1) I do this action for button pressed:

 

x ++;

[label setText: [NSString stringWithFormat: @"Button pressed %i times", x]];

 

The thing is that for each press the text overwrites the previous text, as in words are written over the old ones -- i have tried a setText:@"" and then set the text, same result. Is there some kind of repaint or somthing? I tried reload, reloadData but it will result in a crash.

 

2)

 

After i finished with a view, how do i get rid of it ? I mean dealloc ?

 

eg look at this button action:

x++;

if (x%2 == 0) {

[label removeFromSuperview];

} else {

[label setText: [NSString stringWithFormat: @"Button pressed %i times", x]];

}

 

I was expecting first click to make the label show "Button pressed 1 times", second click to dealloc button, 3rd click to crash.

However, 3rd click will show "Button pressed 3 times" overwrite over "Button pressed 1 times" :-)

 

For those who did not understand what i mean by overwrite, there will be a "3" over "1" so u get a kinda of "$" :( instead of the number.

 

Any thoughts ?

 

Cheers,

M.

Link to comment
Share on other sites

Here is the first HelloWorld working example (with events).

I resolved the issue with the label text not showing up properly.

HelloWorld.zip

 

Great example but I have one question...

 

How / Where / Who?!!? Are the connections being bade?

 

I mean I'm pretty comfortable in IB (tho its changed over the past few years since I last touched it...

 

I see in your nib 3 items:

 

1 Button

1 Label - with text set to Hello World

1 Label - with text set to nothing

 

I see in your MyView.h file that you have outlets:

 

IBOutlet id button;

IBOutlet id label;

IBOutlet id status;

 

What I can't figure out is how did you (in IB) indicate that:

 

'Button' in your nib = 'button' in your MyView.h?

'Label' in your nib = 'label' in your MyView.h?

'Label' in your nib = 'status' in your MyView.h?

 

Control bindings are gone so its not that way... and I tried control-drag option-drag shift-drag and any other form of ___-drag from the actual controls to somewhere that would let me say YES this control is 'status', YES this control is 'label' etc etc etc.

 

What am I missing?!

 

Dave

Link to comment
Share on other sites

I have made it work guys ..
Yup, you have ;) Works here when I put the components on a UIView and connect up to that. Thanks.
How / Where / Who?!!? Are the connections being bade?
The connections are being made to the UIView. When you first open IB and have a blank window the first thing you should do is drag a UIView from the object library onto that blank window. Change the UIView's class to one of your own (e.g. MyView). Add a single action called changeText: and a single outlet called labelText of type UILabel. Now you hook the button outlet up to the view (so control-drag from the buttons Touch Up Inside event to a blank part of the view). Then finally hook the view up to the label by control dragging from the view (a blank area) to the label.Here's some images that might make it a bit clearer...picture1tw7.th.pngpicture2ys9.th.png
Link to comment
Share on other sites

Now you hook the button outlet up to the view (so control-drag from the buttons Touch Up Inside event to a blank part of the view). Then finally hook the view up to the label by control dragging from the view (a blank area) to the label.Here's some images that might make it a bit clearer...

 

This took care of it for me... ugh I think I'm to the point where I've forgotten more about IB then I remember... :(

 

What made things easier for me was to take IB out of 'Icon View' and put it into 'Outline View' - made things much easier for me...

 

Dave

Link to comment
Share on other sites

Interface Builder allows you to create the xib files with just a view, rather than a window.Does anyone know yet how to load the view from this into a view?

Interface Builder allows you to create the xib files with just a view, rather than a window.Does anyone know yet how to load the view from this into a view?
I got it to work with this

UIView *view = [[[NSBundle mainBundle] loadNibNamed:@"mainwindow" owner:self options:nil] lastObject ];

Link to comment
Share on other sites

Here is a semi-working example with controllers. You have one nav controller and two view controllers in there.

For some reason, the table views are not updated -- you can see that for soups you have 4 rows and for desserts there are 6 rows, but the first 4 are taken up by the soups. Also, when going back, the row stays selected.

If anyone finds out what's wrong in the example, pls tell :-)

 

Cheers,

M

 

Receipes_v.table.zip

Link to comment
Share on other sites

Here is the first HelloWorld working example (with events).

I resolved the issue with the label text not showing up properly.

 

so how did you get the label to clear and overwrite the text (to avoid 1 + 3 = ' )? I'm getting the same problem in another project.

thanks

Link to comment
Share on other sites

Okay has anyone tried table views AND turning on UITableViewCellAccessoryDetailDisclosureButton?

 

It's used in place of: UITableViewCellAccessoryDisclosureIndicator

 

The 'DisclosureIndicator' puts that little ">" and the end of each menu entry.

 

The 'DetailDisclosureButton' puts a neat info icon at the end that acts like a button so you now have TWO ways to react with someone clicking on a single menu item...

 

1 - They simply click on the line itself, anywhere but the fancy info-graphic at the end of the row.

2 - They DO click on the fancy info-graphic at the end of the row.

 

But my question is what code do I use to 'react' to someone pressing on the info-graphic... I've searched tons of source but not a single one makes use of the icon.

 

You can see it in action on an iPod Touch if you go to the networking area... each wifi network it remembered will/should have one.

 

Dave

Link to comment
Share on other sites

It's more proper to just use the line

 

[[NSBundle mainBundle] loadNibNamed:@"MyNib" owner:self options:nil];

 

In your app delegate and in your NIB make the controller an instance of the app delegate class, then just control-drag to make your connection to the window, etc.

 

Then all you need do is call this in your code to show the main window:

 

[window makeKeyAndVisible];

 

So your code can be just like:

 

Header

#import <UIKit/UIKit.h>
@interface MyAppDelegate : NSObject  <UIApplicationDelegate>
{
   IBOutlet UIWindow *window;
}

@property (nonatomic, retain) UIWindow *window;
@end

 

Main Code

 

@implementation MyAppDelegate
@synthesize window;

- (void)applicationDidFinishLaunching:(UIApplication *)application
{
[[NSBundle mainBundle] loadNibNamed:@"MyNib" owner:self options:nil];
[window makeKeyAndVisible];
}

@end

Link to comment
Share on other sites

 Share

×
×
  • Create New...