I am very new to iPhone development. I often encounter IBAction, IBOutlet and so on when reading Objective-C and Swift code. What does IB stand for?
"Interface Builder".
Before Xcode 4, the interface files (XIBs and NIBs) were edited in a separate program called Interface Builder, hence the prefix.
IBAction is defined to void, and IBOutlet to nothing. They are just clues to Interface Builder when parsing files to make them available for connections.
Just to add the reference, inside AppKit/NSNibDeclarations.h you'll find these:
#ifndef IBOutlet
#define IBOutlet
#endif
#ifndef IBAction
#define IBAction void
#endif
So, actually, code like this:
#interface ...
{
IBOutlet NSTextField *label;
}
- (IBAction)buttonPressed:(id)sender;
#end
Will be transformed into:
#interface ...
{
NSTextField *label;
}
- (void)buttonPressed:(id)sender;
#end
By the preprocessor, even before the compiler sees it. Those keywords were acting just as clues to Interface Builder.
IB stands for interface builder, as you connect objects via the interface builder .
IBAction and IBOutlet are interface Builder Constants
IBOutlet:A Controller class can refer to the object in the nib file using a special constant called IBOutlet.
IBActions:Interface objects in the nib file can be set to trigger specific methods in controller class using IBAction as return type of the method.
Related
I'm an Objective-C newbie and I'm reading "iPhone programming" by Alasdair Allan. While reading, I found this code:
#interface RootController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
UITableView *tableView;
NSMutableArray *cities;
}
// warning: remember this tableView
#property (nonatomic, retain) IBOutlet UITableView *tableView;
The relative implementation starts this way:
#implementation RootController
#synthesize tableView;
Now: I learnt that #synthesize is a sort of shortcut to avoid boring getters and setters.
But I've some question:
in the code of the implementation tableView is never explicitly called but the dealloc releases it;
if it never gets called explicitly why the #synthesize?
Is it mandatory for IBOutlets to be synthesized?
From Memory Management of Nib Objects,
When a nib file is loaded and outlets established, the nib-loading mechanism always uses accessor methods if they are present (on both Mac OS X and iOS). Therefore, whichever platform you develop for, you should typically declare outlets using the Objective-C declared properties feature.
For iOS, you should use:
#property (nonatomic, retain) IBOutlet UIUserInterfaceElementClass *anOutlet;
You should then either synthesize the corresponding accessor methods, or implement them according to the declaration, and (in iOS) release the corresponding variable in dealloc.
in the code of the implementation tableView is never explicitly called but the dealloc releases it;
That is because when you do assign a value to the tableView, your controller retains it, and it will need to release it when it gets dealloc'd. Don't forget, #properties declared in an interface are publicly accessible. In your case specifically, the tableView you're declaring as IBOutlet is initialized by the view controller loadView method using the connections you define in Interface Builder between the File's Owner and the UITableView.
if it never gets called explicitly why the #synthesize?
You need to provide accessors for all declared #properties. They can be #synthesized, or you could write your own.
Is it mandatory for IBOutlets to be synthesized?
No, but it's way more convenient that way. The rule enforced by the compiler is that #properties must have corresponding accessors (synthesized or not) in the implementation.
For reference: From Xcode 4.4 and LLVM Compiler 4.0 on the #synthesize directive is no longer required as it will be provided by default for #properties defined in the interface.
If you type
#property (nonatomic, retain) IBOutlet UITableView *tableView;
you tell the compiler: "Listen, there will be a getter and a setter. If appropriate, use them!" And it will use them when loading the nib.
Therefore you have to implement the getter and the setter otherwise the compiler will complain.
The IBoutlet pseudo-type is just a marker so that the InterfaceBuilder "knows" that the mentioned class-file has a handle/outlet to the UITableView instance.
When compiling IBOutlet is being removed by the preprocessor (InterfaceBuilder parses (looks at) the source files). It's similar with IBAction: it is being replaced with void by the preprocessor.
That said, you could use the reference to said instance to do stuff programmatically (Like adding/changing values of the UITableView)
I have a custom UIWindow class that has an IBOutlet
#interface MyWindow
IBOutlet UIView * someView;
id <MyWindowDelegate> delegate;
// to inform a controller something happened to view
#end
#interface MyControllerThatContainsSomeView
IBOutlet UIWebView * theConcreteView;
#end
I have changed my Window in MainWindow.xib to MyWindow. Is there a way, through interface builder, in which I can reference someView from MyControllerThatContainsSomeView.xib
so, MainWindow.MyWindow.someView -> MyControllerThatContainsSomeView.theConcreteView
You can refer to it in a binding path but that's about it. Usually when you find that you need to refer from one view to another, it's time to rethink your design. Views should refer instead to model objects which provide data to the views.
In the following code what is the function of -(IBAction)setLabelPushed:(id)sender;
#import <UIKit/UIKit.h>
#interface BasicIPhoneAppViewController : UIViewController
{
IBOutlet UILabel *myLabel;
IBOutlet UITextField *myTextField;
}
-(IBAction)setLabelPushed:(id)sender;
#end
Actually it is a non-static method. IBAction means that it can be used as a event handler in Interface Builder (it can be linked to some action). You should provide more details, for example the body of setLabelPushed function.
get the value from textfield and show it in the label .I think so......
It is a method you can bind from within the Interface Builder...
http://mobile.tutsplus.com/tutorials/iphone/iphone-sdk-interface-builder-basic-training/
IBAction resolves to "void" and IBOutlet resolves to nothing, but they signify to Xcode and Interface builder that these variables and methods can be used in Interface builder to link UI elements to your code.
If you're not going to be used Interface Builder at all, then you don't need them in your code, but if you are going to use it, then you need to specify IBAction for methods that will be used in IB and IBOutlet for objects that will be used in IB. IBOutlet and IBAction
Sometimes I see the following code into two different formats:
Format 1:
#import <UIKit/UIKit.h>
#interface MyViewController : UIViewController {
IBOutlet UILabel *myText;
}
#property (retain, nonatomic) UILabel *myText;
-(IBAction)buttonPressed:(id)sender;
#end
Format 2:
#import <UIKit/UIKit.h>
#interface MyViewController : UIViewController {
}
#property (retain, nonatomic) IBOutlet UILabel *myText;
-(IBAction)buttonPressed:(id)sender;
#end
which is the correct format? Why?
To clarify what Hack Saw said, and more directly answer your question, it does not matter whether you put IBOutlet in your property declaration or your instance variable declaration.
What Hack Saw was trying to say is that IBOutlet and IBAction both mean nothing to the compiler (IBAction gets compiled into void). The only reason they are there is for Interface Builder to parse the file and make a list of all objects and methods that you the developer says it should care about.
IBOutlet is a marker for interface builder to find your declarations, and make them available in the drop downs in IB.
They are strictly only required if you want to have IB connect an IB object to a reference in your code, for instance, connecting a button to a UIButton * declaration.
So, the basic idea here is that Interface Builder has a list of objects it knows how to make. You could make those objects in code, but a lot of the time, you don't need more capability than what IB offers, which is actually quite a lot.
In those cases, IB takes care of that object entirely. It allocates it, and sets the various parameters, and takes care of displaying it.
However, you obviously need to be able to talk to it, as well, most of the time. In order to do this, your declare a pointer to the object, like UIButton *mybutton, but in order to let IB know you want to connect up with it, you add IBOutlet to the declaration.
IB lists the variable, you connect the button up to something in File's Owner, or sometimes firstresponder, and then IB saves that connection data, and sets everything up when the nib gets loaded.
I am stepping into the deep waters of IPhone development. I have the following header file.
//
// FirstProjectViewController.h
// FirstProject
//
// Created by Mohammad Azam on 6/25/10.
// Copyright HighOnCoding 2010. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface FirstProjectViewController : UIViewController<UITextFieldDelegate> {
IBOutlet UITextField *number1TextField;
IBOutlet UITextField *number2TextField;
IBOutlet UILabel *resultLabel;
}
- (IBAction) add: (id) sender;
#end
I want to hide the virtual keyboard when the user clicks the "Return" key. For this my controller implements the UITextFieldDelegate. I also went to the interface builder and hooked up the UITextField delegate to the File Owner using connections. But my header file is never updated. Should it not updated and add a method called textFieldShouldReturn.
I have implemented textFieldShouldReturn method in my implementation file (.m) and it works fine but if the header file never updates with the definition of the textFieldShouldReturn method then how should I ever know that my implementation file needs to implement textFieldShouldReturn method.
Thanks,
If you don't want to share the function with other accessors outside the class, there is no need to add the function to the header file. The delegate protocol of UITextField declares which methods are required to implement and which are optional
regards