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
Related
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.
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)
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've got this mock up:
As you can see, it's a sort of navigation-menu. It's functionality should be the same as a segmented control, and i am going to change the tableView based on the item active.
What would be the easiest way to implement this?
I have started makin my UIView-subclass, but found out that i had to then make a delegate, watch for tap-events and stuff.
Is this the best way to do it? Should i subclass UISegmentedControl?
Any other advice?
Please, point me in the right direction. I feel confident in Obj-c, but making these kinds of stuff makes my mind goes crazy.
Conceptually, UISegmentedControl seems like a good choice for this, but I don't think it's quite flexible enough to create the effect you're going for here.
Have you considered putting three UIButton controls inside a custom view? You can customize the images for each button using setBackgroundImage:forState: to get the border style in your mockup. Set the selected property of the pressed button to YES, and UIButton will handle the drawing for you.
You can set up an action method to detect which button was pressed by calling
[button addTarget:self action:#selector(nameOfMethodToHandleButtonPress) forControlEvents:UIControlEventTouchUpInside])]
A delegate is just any class that conforms to a protocol you create. So you would create a delegate protocol in your header like this:
#class MyControl; // this is a forward reference to your class, as this must come before the class #interface definition in the header file
#protocol MyControlDelegate <NSObject>
#optional
- (void)myControl:(MyControl *)control didSelectButton:(int)buttonIndex; // replace this method with whatever makes sense for your control
#end
And the delegate is just a property in your MyControl class:
#property (nonatomic, assign) id <MyControlDelegate> delegate; // you use 'assign' instead of 'retain' to prevent retain cycles
And in your button press handlers, for example:
- (void)methodThatHandlesButtonPress { // this is the method you set up in the first code example with addTarget:action:forCotnrolEvents:
if ([self.delegate respondsToSelector:#selector(myControl:didSelectButton:)])
[self.delegate myControl:self didSelectButton:0]; // replace as appropriate
}
Now, you just have to have the view controller that contains your control adopt the protocol:
#interface MyViewController : UIViewController <MyControlDelegate> { // etc...
And implement the method:
- (void)myControl:(MyControl *)control didSelectButton:(int)buttonIndex {
// handle the button press as appropriate
}