how to update label/textfield of storyboard uiviewcontroller from controller.m? - iphone

I am new to iphone development, and i'm currently using xcode 4.2.
I drew a UIViewController into the storyboard. I put some labels into the UIViewController. It is associated to a controller.m file.
How do I, from the viewdidload function of the controller.m file, update the text in the label?
I don't know how to get the variable name or handle name of the elements in the uiviewcontroller on the storyboard.

If you are creating things through storyboard, the easiest way is to create an IBOutlet property for each UI element. This creates an instance property for the UIElement which you can then reference in your code - to set state, get values, etc.
You can do this through Control-click-drag on the UIElement to your UIViewController.h file (split view: RETURN-Command-Option: to display counterparts). XCode will pop up a dialog enabling you to name it (the same gesture will also enable you to create IBActions - the function that is called when the UIElement gets interacted with). You can also Control-click-drag on the left sidebar listing of the UIElements in your ViewController if that is easier.
There are YouTube videos that show it better than my weak explanation. I was skeptical # storyboard/IB at first because I don't like UI magic and prefer to do things through code, or at least see the code that results from the magic, but it really does work pretty well and saves some of the tedium of UI coding.
One gotcha to be aware of: if you make an IBOutlet and then delete the UIElement, you will have code errors because of the errant reference. Those are easy to find and fix. The UIViewController object will also contain those references and will result in unpleasant crashes - so Control-click on the UIViewController object (or use the Inspector panel) and any element that has an orange triangle == broken.

Related

Need help in Xcode with "ViewController"

I'm new to Xcode programming and I've been watching a couple videos here and there but one thing I never find on mine which the videos have. They have a file called "ViewController" (.h/.m). I don't have that, instead I have AppDelegate, RootView, DataView, and ModelController (all are .h/.m)
Choose the Single View Application template that contains ViewController. Or press command+N to create a new Cocoa Touch Class and make it subclass of UIViewController.

Still fuzzy on creating objects in Code, IB, and combined

I'm still quite new to Xcode etc, so Im a bit fuzzy when it comes do creating/using objects in Xcode.
For example, I used a tutorial for creating a GestureRecognizer in code - it's pretty simple.
Right now I have only this in my .h:
#interface PlayPage : UIViewController <UIGestureRecognizerDelegate>
And this in my .m:
UITapGestureRecognizer *tapTwo=[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(doubleTap)];
[tapTwo setDelegate:self];
[tapTwo setNumberOfTapsRequired:2];
[tapTwo setNumberOfTouchesRequired:1];
[self.view addGestureRecognizer:tapTwo]; //adds it to view
Here are my question(s):
1) If I also want to see the GestureRecognizer in IB along with the above code (perhaps so I can change some settings since I'm not familiar with everything) how do I accomplish that?
2) How would you decide when to use all code vs. a mix of code/IB ? Is it strictly a matter of style/comfort/familiarity?
3) It seems declaring different objects requires different 'setup' code (UITextLabel vs GestureRecognizer vs UITextField,for example) - how do you know when to use which code?
Thanks for helping to clear this up.
In Xcode 4.x Interface builder there are UIGestureRecognizer objects that you can drag onto your views. So you would need to add the UIGestureRecognizer in Interface builder (if you need to do any more config in code then connect them up with an outlet as well).
I try and do anything I can in IB and drop to code when I have to but it is a matter of preference.
I'd rather eyeball the position of views and use the snap guides than spend a while figuring it out in code.
You can hide a lot of boiler plate code if you do it in IB
Start typing and look at the autocompletion options to jog your memory. But more importantly every time you use a class you have not used before you should at least skim the documentation to see what is suggested. Half of the questions on this site could easily be solved if the question poster actually bothered to look at the vast documentation available.
Update
You need to create the UIGestureRecognizer in Interface Builder not your code.
In Interface Builder ensure that the Utilities pain is visible and drag and drop a UIGestureRecognizer of the required class onto your view
This is what the UIGestureRecognizer class look like:
You then configure the object in the Utilities panel. If you want to be able to access this object in your code then you will need an IBOutlet.
In your classes header file add a new ivar for this
#property (nonatomic, retain) IBOutlet UITapGestureRecognizer *tapGestureRecognizer;
In the implementation file synthesize this
#synthesize tapGestureRecognizer = _tapGestureRecognizer;
Then back in Interface builder connect this up by ctrl + click + dragging from the File's Owner to the UIGestureRecognizer subclass. Then selecting your ivar from the window that appears:

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!

UIView (subview) does not send IBActions to AppDelegate

I'm having this problem because I originially made everything in the main NIB, but then after reading learned that it is better to use subviews.
I've got my IBActions in the AppDelegate, and I've successfully connected and loaded my subviews. However, when I try to connect my buttons in the subviews to the IBActions in the AppDelegate, the IBActions appear under the "First Responder". They seem to connect fine, but when running the application they do not trigger the IBActions (I've confirmed this with some NSLogs, it's not an error in the code within the IBActions). What am I doing wrong?
Thanks!
The AppDelegate should only be used for very specific items such as implementing the UIApplicationDelegate protocol (i.e. methods like applicationDidFinishLaunching) or in some cases storing global variables.
You should keep IBActions and other outlets in their respective view controller files (i.e. if you created MyViewController.h and MyViewController.m which are linked with MyViewController.xib where you have some buttons, images, etc.). They can then be hooked up via dragging the inspector control you want (i.e. TouchUpInside) to the File's Owner.
Something you should read to better understand view controllers: http://developer.apple.com/iphone/library/featuredarticles/ViewControllerPGforiPhoneOS/Introduction/Introduction.html
Typically it is best to create a unique view controller for each view you will present to the user. For instance, if I had a main screen and then an "about" or a settings screen, I would make each of those their own view controller. It helps organize things better than using one view with a whole bunch of subviews that you hide/show and will also improve loading times and general performance.
Update for your 2nd question in the comments about accessing the app delegate:
First, you need to import the .h file (i.e. #import "AppDelegate.h") for the app delegate into whichever view controller .m file you wanna use to access whatever variables, arrays, etc you have stored in the app delegate files. Make sure you synthesize whichever objects you create in the app delegate's .h file in the app delegate's .m file so the getters and setters are created (so you can access them).
Then in the view controller .m file, in whichever method you are using:
-(void)someMethod {
// here we just create a shortcut to the app delegate called "theAppDelegate"
YourAppDelegateFileNameHere *theAppDelegate = (YourAppDelegateFileNameHere *)[[UIApplication sharedApplication] delegate];
// now you can use the dot notation if you wanna access a variable
int SomeNewInteger = theAppDelegate.someIntegerYouHaveStored;
// or some array you have stored
return [theAppDelegate.someArrayYouCreated count];
}
Hope that helps!

how to load a view using a nib file without using view controller

i am new to this objective-c
i want to load a view using nib file i created when i press a button .without using any view controller..
This is generally considered a bad idea if you don't know what you're doing, but if you really want to do this then there's 2 places to look, depending on what version of the OS you're developing for.
iOS 4
Look at UINib in the documentation. You can use this to load a nib fairly easily.
iOS 3.2 and earlier
Use NSBundle. There is a category, documented under the name "NSBundle UIKit Additions Reference", that adds a method -loadNibNamed:owner:options:. You can also use this on iOS 4.0 if you so desire.
In both cases, the owner object fills in the role of "File's Owner" in the nib, useful if you have actions or outlets specified on the owner. The method also returns an NSArray of all the top-level objects in the nib. Be careful, if you use this array you need to retain any of the objects that you want to keep, as the array (and all the objects) are returned autoreleased.
Try this. Should show you how to implement your UIView subclass.
http://markuzweb.blogspot.com/2011/05/subclassing-uiview-with-nib-file.html