IBAction and IBOutlet Clarification - iphone

I am new to Xcode and I am wondering, what does IBAction and IBOutlet do? I've tried doing simple task like 'hello world' but it seems I stuff it up. I am making app that involves a questionnaire that links to a database.

IBAction is used for Methods which performs as a result of any Action for example Button Press.
-(IBAction) buttonPress : (id) sender;
IBOutlet is used for UI related objects like Button,label, View etc.
IBOutlet UILabel *nameLabel;
Note: If you are using XIB for development, you should make use of IBAction and IBOutlet. Otherwise you will not able to map objects and methods on XIB. If you are developing everything by coding then IBAction and IBOutlet are optional.

As mentioned in the answer linked above: "IBAction and IBOutlet are macros defined to denote variables and methods that can be referred to in Interface Builder."
However in layman's terms and a simple way to think of them -
IBActions mark the methods that will be called when an event (e.g. touch down) is triggered on one of your interface builder controls (e.g. button, switch etc).
IBOutlets mark the variable references for your interface builder controls.
Outlets allow you to programatically interact with controls you layout on interface builder.

Related

How can I access various UIViews within a Nib, programmatically?

First, I am super-new to Objective-C/iOS development and, in fact, this question is for my first, test project. Also, I come from a C#/WinForms background so I'm coming into iOS development with certain pre-conceived notions of user interface design and application state. Please bear with me and help clear up my confusion.
I just created my first iOS application project which, consists of a Single View. I allowed Xcode to create all the files for me through the Single View project wizard. When it was finished, I opened my new applications, single UIView Nib file in the designer and I dropped three sliders onto the view.
The desired purpose of this application is very simple-- each slider corresponds to either the R, G or B values associated with the background color of my view.
I have figured out how to set the background of my view but I can not figure out how to access the values of each slider objects. Yes, I can hook-up and respond to an IBAction for each slider, but my plan is that each time a slider's value changes, I want the IBAction to call a refactored method that accesses the values of all three sliders and then set's the views Background Color based of the values associated with each one.
How can I access the values of my sliders? Specifically, how can I access the value of the sliders that I created by dragging and dropping them into the Nib designer window? I've seen code explaining how to programatically add a UISlider to your UIView and then access the value, but how do you access the value of a UISlider that's added to the Nib and, I assume, will be automatically "wired" in at compile time?
Hopefully this makes since? If I'm missing an intermediate step or critical concept, please let me know.
You create UISlider ivars/properties and make them IBOutlets:
#property (nonatomic, retain) IBOutlet UISlider* yourSlider;
You synthesize it in your .m file and the connect the IBOutlet in interface builder. The yourSlider pointer is then a reference to the object you connected it to. Note that it will only be loaded with the view of the UIViewController and therefore will be nil until viewDidLoad is called. You also must set it back to nil
self.yourSlider = nil;
in your viewDidUnload method (so that it is released). In Xcode 4 you have a convenient way of doing all the above steps in one action (see the "Interface Builder is Built-in" of What's new in XCode 4)
Similar to CTRL+dragging from the UISlider to the .m file to create the IBAction, you can CTRL+drag the UISlider from your .nib designer to the associated .h file and have it create a property for you. Then, from your .m file, you can access self.mySlider (or whatever you name the property).
There's a video on this page that shows binding to a UISlider specifically.
Another approach is to use the tag property of a view.
#property(nonatomic) NSInteger tag
- (UIView *)viewWithTag:(NSInteger)tag
You can set the tag property of a view in the interface builder and later reference that view in your controller.
UIView *myViewFromTag = [self.view viewWithTag:theNumberYouSetInIB];
In general, it's better to stick with IBOutlets. However, there are certain situations where it makes more sense to use tags.
Good luck!

Controlls are not displaying in interface builder?

i am facing a problem with IBOutlet,please Respected developers help me out, as i am fresher in iphone
for eg.
i declared buttons or controls with IBOutlet in .h file ,but many times interface builder is not showing the controls so i use to exit the application and reopen it again and i found it
so is there any thing i am missing.
thanks in advance...
Did you save your files? A mistake a lot of people new to iOS/Mac development don't realize is that Interface Builder will not show the IBOutlets unless you have saved the files first. So anytime you add an IBOutlet, make sure you save your header file before diving into Interface Builder.
How are you declaring your outlets? Also, what do you mean by "interface builder is not showing the controls"? If you have the following code:
#interface MyViewController : UIViewController {
IBOutlet UIButton *myButton;
IBOutlet UISlider *mySlider;
}
// Properties
// Methods
#end
In IB's connection inspector the outlets should show up and allow you to connect them to valid UI objects. Could you please clarify your issue?

iPhone: Proper use of View and View Controller

I've recently been doing a lot of Objective-C programming, and just got back into doing more iPhone development. I've done a lot of programming using MVC in other languages/frameworks, but I just want to make sure I'm using MVC properly in my iPhone Development.
I created a new iPhone Utility Application, which creates two views: MainView and FlipsideView. Both have a controller (FlipsideViewController and MainViewController) and XIB file of their own.
What I've been doing is putting the IBOutlet UIControl myControl variables in my MainView.h or FlipsideView.h files and then tying the controls in Interface Builder to those variables. Then I put any IBAction SomeAction myAction methods in the MainViewController.h and FlipsideViewController.h files and tying the events to those methods in Interface Builder.
This seems to be conceptually correct, but seems to cause problems. Say I have a button that when clicked it changes a label's text. So the Controller doesn't have a clue of what the variable name of the label is in the OnTouchUp event handler for my button. So I make a #property for it. But since the MainViewController.view property isn't of type MyView, I get warnings or errors whenever I try to access those properties from the view controller.
I am doing this correctly? Is there a better way to do this? If this is correct, how do I properly work with those variables without getting warnings or errors?
Thanks
Here's some code showing what I'm doing:
MainView.h
#import ...
#interface MainView : UIView
{
IBOutlet UILabel* label;
IBOutlet UIButton* button;
}
#property UILabel* label;
#property UIButton* button;
#end
MainViewController.m
-(void) buttonTouchUp:(id) sender
{
self.view.label.text = #"The button was pressed!"; //This gives error because label is not in the view structure or union
[self.view label].text = #"The button was pressed!"; //This gives a warning
}
I know I can cast the view to be of the right type, but that seems like a hack job.
I know I can live with the warning, but a warning says to me that I'm doing something that I probably shouldn't be doing. I don't believe the SDK would set me up to do have to do something like that all the time.
I must just be misunderstanding what the View is supposed to be and I'm using it incorrectly.
Most code I've seen and written myself keeps all the outlets and the actions on the controller. The button sends a message to the controller (via IBAction), then the controller updates the label (via IBOutlet). In other words, putting outlets on your views is unusual.
Views shouldn't be connected to other views unless they have some special relationship, like maybe back/forward buttons that target a UIWebView... but even then, you find out you need a controller to enable/disable the buttons as appropriate.

IBOutlet keyword strictly required?

I am pretty new to iphone programming therefore I apologize if my question could result trivial or obscure.
In many examples and tutorials I have seen that in the declaration of the outlets within Xcode (interface section of the view controller) the keyword "IBOutlet" is used or it is not, in conjunction with the class the outlet belongs to, apparently without a relevant difference.
e.g.
IBOutlet UIButton * myButton;
or
UIButton *myButton;
I have seen by myself in my experiments that both ways seem to work the same (provided that in both cases I set the proper connections in IB, and declare the property and synthesize it)
Anyone could tell me if there is a relevant difference and different behavior between the two statements?
Thank you
IBOutlet is defined the following way:
#define IBOutlet
So it has no impact on the running code, and its only purpose is to allow Interface Builder automatically determine it while parsing class header. Without IBOutlet keyword in header you will need to declare it in IB Inspector's Identity tab to make it avaliable to be connected to interface elements.

Arbitrary objects to handle actions?

My question may be a bit stupid, but why can't any object instantiated in IB handle, say, button click? I mean I'm able to add my own object to a xib, and link outlets to cotrols and control actions to object's method, but once I press the button everything just crashes (uknown selector).
Do you guys have a hint around that?
EDIT: The code, as requested:
#interface TextController {
IBOutlet UILabel * textLabel;
IBOutlet UITextField * textField;
}
-(IBAction)buttonClicked:(id)sender;
#end
#implementation TextController
-(IBAction)buttonClicked:(id)sender {
textLabel.text = #"Ololo";
}
#end
Connections in IB are ok, just believe me. It's really hard to get them wrong with all this drag'n'drop stuff :)
EDIT 2: TextController is not a file owner (in this case it works fine). However, I just want to understand why I can't wire up an action to some object (may be even not a subclass of UIViewController).
You can wire outlets and actions to any object in the nib-file. Drag an NSObject form the library palette onto your nib-file, in Interface Builder. Then go to the Identity tab of the information palette and set the Class of your object.
This way you can instantiate any object of any class from your nib. If the target you want to hook to is statically created from the nib-file. Make sure that the file's owner have at least one reference to your object, or else it will be deallocated as soon as it has been created. Targets are not retained by the sender.
If the object you want to hook up should not be statically created from your nib, then implement awakeFromNib in a class that is instantiated from the nib-file and hook up the targets in code.
Last option is if you do not have any sub-class of your own in the nib-file at all. Then implement initWithNibName:bundle: in your UIViewController subclass, and hook up your targets in code after calling the super implementation.
post code, this usually means you dont have your connections wired up correctly. Is file's owner TextController in IB?