Jump to content

iPhone SDK - Interface Builder Tutorial


  • Please log in to reply
114 replies to this topic

#1
stroke

stroke

    InsanelyMac Sage

  • Members
  • PipPipPipPipPip
  • 350 posts
  • Location:Russia
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.
  • Create a new Cocoa Touch project in Xcode.
  • 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.
    Posted Image
  • 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.
  • 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
  • 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];
    }
  • Build and Go. Your new iPhone App should be using the XIB you just made.
Hope this gets people started with Interface Builder.

#2
(MoC)

(MoC)

    InsanelyMacaholic

  • Members
  • PipPipPipPipPipPipPipPipPipPipPip
  • 2,653 posts
  • Gender:Male
  • Location:/dev/moc
  • Interests:Plenty.

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.

  • Create a new Cocoa Touch project in Xcode.
  • 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.
    Posted Image
  • 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.
  • 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
  • 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];
    }
  • 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!

#3
C.J.

C.J.

    InsanelyMac Protégé

  • Members
  • Pip
  • 29 posts
Not too difficult. Just takes little away from the advertised simplicity of IB..I think I'll wait until Apple fixes some of the bugs though, like the messed up Build & Go button..

#4
mmk

mmk

    InsanelyMac Sage

  • Members
  • PipPipPipPipPipPip
  • 421 posts
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

#5
geez

geez

    InsanelyMac Protégé

  • Members
  • Pip
  • 22 posts
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!

#6
DaveGee

DaveGee

    InsanelyMac Protégé

  • Members
  • PipPip
  • 75 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. ... 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

#7
pix

pix

    InsanelyMac Protégé

  • Just Joined
  • Pip
  • 3 posts
cool thanks!

any idea how to use UINavigationContoller, UITabBarController and the UIViewCOntrollers in IB?

#8
maverick808

maverick808

    InsanelyMac Protégé

  • Members
  • Pip
  • 5 posts
I have the same problem in that it crashes when I click the button. Also tried with no code in the method so yeah it must be the connection. I had hooked up the touch down event.

Sucks, crappy beta.

#9
stroke

stroke

    InsanelyMac Sage

  • Members
  • PipPipPipPipPip
  • 350 posts
  • Location:Russia
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.

#10
maverick808

maverick808

    InsanelyMac Protégé

  • Members
  • Pip
  • 5 posts
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.

#11
stroke

stroke

    InsanelyMac Sage

  • Members
  • PipPipPipPipPip
  • 350 posts
  • Location:Russia
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.

#12
maverick808

maverick808

    InsanelyMac Protégé

  • Members
  • Pip
  • 5 posts

Ah, yes, I see what you meanperhaps 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.

#13
mmk

mmk

    InsanelyMac Sage

  • Members
  • PipPipPipPipPipPip
  • 421 posts
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.

#14
mmk

mmk

    InsanelyMac Sage

  • Members
  • PipPipPipPipPipPip
  • 421 posts
Here is the first HelloWorld working example (with events).
I resolved the issue with the label text not showing up properly.


Attached File  HelloWorld.zip   1.34MB   490 downloads

#15
pix

pix

    InsanelyMac Protégé

  • Just Joined
  • Pip
  • 3 posts
the button example is helpful, thanks, but do you guys know how to use any of the ViewControllers (Navigation, Toolbar) in IB?

#16
DaveGee

DaveGee

    InsanelyMac Protégé

  • Members
  • PipPip
  • 75 posts

Here is the first HelloWorld working example (with events).
I resolved the issue with the label text not showing up properly.
Attached File  HelloWorld.zip   1.34MB   490 downloads


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

#17
maverick808

maverick808

    InsanelyMac Protégé

  • Members
  • Pip
  • 5 posts

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...Posted ImagePosted Image

#18
DaveGee

DaveGee

    InsanelyMac Protégé

  • Members
  • PipPip
  • 75 posts

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

#19
newky2k

newky2k

    InsanelyMac Protégé

  • Just Joined
  • Pip
  • 1 posts
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 ];

#20
stroke

stroke

    InsanelyMac Sage

  • Members
  • PipPipPipPipPip
  • 350 posts
  • Location:Russia
You shouldn't use lastObject as the the last object in the NIB isn't always going to be your view. Find out which index it's at, then do objectAtIndex:n.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users

© 2014 InsanelyMac  |   News  |   Forum  |   Downloads  |   OSx86 Wiki  |   Mac Netbook  |   PHP hosting by CatN  |   Designed by Ed Gain  |   Logo by irfan  |   Privacy Policy