Problem setting Value for UILabel (iPhone SDK) - iphone

I'm reasonably new at the iPhone SDK, so please forgive me if this answer's ridiculously obvious.
I have a ViewController connected to a .xib file (they are called FirstViewController)
I also have a custom class called MyCustomClass. In this class, I have a method like this:
- (void)setTheText {
[myLabel setText:#"foo"];
}
I want to call this method to set the text in a label in FirstViewController.xib
So far, I have done this:
Dragged in an "Object" into Interface Builder, and set the class to: MyCustomClass
Connected up the IBOutlet 'myLabel' from MyCustomClass to a UILabel in the view.
However, when I run the program, and press the button to set the label (which is in FirstViewController.m), something like:
- (IBAction)doSomething:(id)sender {
MyCustomClass *customClass = [MyCustomClass alloc] init];
[customClass setTheText];
}
This doesn't set though. NSLog(#"%#",[myLabel text]); returns (null)
Xcode shows no errors or warnings, what could be wrong?
Thanks,
Michael
Additional Info:
Interface to MyCustomClass.h:
#import <UIKit/UIKit.h>
#interface MyCustomClass : NSObject {
UILabel *myLabel;
}
#property (nonatomic, retain) IBOutlet UILabel *myLabel;
- (void)setTheText;
#end

You don't want to create a new instance of your custom class in your action method.
There are a couple of ways to do what you want.
Option 1 is to give your view controller a reference to your custom object. To do this, create an outlet of type MyCustomClass * in your view controller, connect that outlet to the new object that you created in your XIB file, and then get rid of the allocation in your action method:
- (IBAction)doSomething:(id)sender {
[customClass setTheText];
}
Option 2 is to let your CustomClass handle both the label and the action method. To do this, you can simplify things even further. Put an outlet for the UILabel into your CustomClass, and then simply convert your setTheText method into an action:
- (IBAction)setTheText:(id)sender {
[myLabel setText:#"foo"];
}
Now, connect that action up to your button, and everything should work like a charm.
Note: You should probably use a method name that does not start with "set", since those are commonly used for property setters as part of Cocoa's KVC/KVO system. Instead, I would call it something like changeLabel, or equivalent.

Your instance of customClass here is completely unrelated to the NIB. You've instantiated a new object using +alloc. If you want to modify the specific MyCustomClass in your NIB, then FirstViewController needs an IBOutlet that points to it.

UILabel also have a property called text to set the value, you might find that easier.
myObject.myLabel.text = #"Your text";

well you called your label two things, first a non-ibaction then an ibaction in the property.

Related

Any number that i put in the textfield it appears in the label as 0

i've been doing a thing here using objective-c, but i'm a beginner in this language, and that's what i did:
there is a class, named "firstviewclass", that is in the control of my first view, in this view there is a textfield that the user puts a number. the textfield is in the firstviewclass.h named "setNumber". There is another class, named "secondviewclass" that is in control of the second view, in this view there is a label that is in the secondviewclass.h, and i want that this label recive the value that the user put in the textfield from the first view, but when i test it on the iOS simulator any number that i put in the textfield it appears in the label as 0... I really don't know what to do!
My codes:
firstviewclass.h:
#import <UIKit/UIKit.h>
#interface firstviewclass : UIViewController
#property (strong, nonatomic) IBOutlet UITextField *setNumber;
- (IBAction)gotonextview:(id)sender;
#end
secondviewclass.h:
#import <UIKit/UIKit.h>
#import "firstviewclass.h"
#interface secondviewclass : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *labelthatrecivesthetextfieldvalue;
#end
secondviewclass.m:
#import "secondviewclass.h"
#import "firstviewclass.h"
#implementation secondviewclass
#synthesize labelthatrecivesthetextfieldvalue;
-(void)viewDidLoad{
[super viewDidLoad];
firstviewclass *object = [[firstviewclass alloc] init];
NSString *string = [[NSString alloc] initWithFormat:#"%i", [object.setNumber.text intValue]];
labelthatrecivesthetextfieldvalue.text = string;
}
#end
First of all, I would strongly recommend not naming a property or instance variable setSomething. It will cause headaches for anyone reading your code because it will always look like you're trying to call a setter. Also, please do capitalize your class names.
Your actual problem is that in viewDidLoad you're creating an instance of firstviewclass, and then trying to get the value from setNumber. That is before the user had any chance to enter anything.
Also, the setNumber outlet in firstviewclass will probably be going nowhere anyway, since you're instantiating that class yourself, instead of loading the NIB.
Edit (ah, Storyboard, d'oh):
For Storyboard, you need to pass the setNumber text field's value to the second view.
First of all, remove the firstviewclass *object = [[firstviewclass alloc] init]; line.
Then, in your first view controller's prepareForSegue method, you can pass the value of the setNumber text field to a property in your your second view controller, and use it from there (e.g. in configureView).
I recommend working through Apple's Storyboard tutorial, it shows exactly what you need to do, step by step. The step you're having issues with right now, passing data to your next view controller, is here.
How are you initiating the setting of the label? From viewDidLoad? If so, then 0 would be correct because you have not set object.setNumber.text to anything. Also, you aren't carrying over the data from your first viewController. You need to let the second viewController know what the number is. Try setting this value in your NSUserDefaults, then in your second viewController, load that value from your defaults.
in the viewDidLoad of secondviewclass, you are creating a new instance of firstviewclass, and then accessing the property of the label. Since you haven't set that to be anything, it will always return zero.
Can you post the implementation of the gotonextview method?
EDIT:
I think you need to be setting the label property from the first view controller. so in your gotonextview method, add this line:
secondviewclass.labelthatrecivesthetextfieldvalue.text = self.setNumber.text;
I admit I'm a little lost in your naming scheme but that might work.

Common views in viewControllers - Code re-usability

I have few common views in most of my viewControllers. What I noticed is that I can reuse single code for all viewControllers which is absolutely wise. For this I decided to create a class Utils which has static methods like
+(void)createCommonViews:(float)yAxis:(NSString*)text;
In my case common views are three labels and two images.
Problem : I am not able to add these views from Utils. I am wondering how can I send self as a parameter so that I may add the views from Utils. It may be wrong to add views outside the viewController. In that case what can be the solution? Taking all these views in a UIView, setting return type of Utils method as UIView and then adding UIView to viewController (after calling method from viewController) might solve my problem. But what I am looking for is some other solution.
+(void) createCommonViews:(float)yAxis withText:(NSString*) text toTarget:(UIViewController*) target
{
//create views
[target addSuview:view];
}
But I think returning a Uiview and then adding it in the UIViewController afterwards, is a far better solution.
The method you're attempting is to have your view object as a singleton. This is uncommon at best, at worst a crash waiting to happen. Better design is for each of your view controller classes to have its own instance of your custom view, like so:
#interface MyCommonView : UIView
// ...
#end
#interface MyViewController_A : UIViewController {
MyCommonView *commonView;
}
#property (strong, nonatomic) IBOutlet MyCommonView *commonView;
#end
// Meanwhile somewhere else...
#interface MyViewController_B : UIViewController {
MyCommonView *commonView;
}
#property (strong, nonatomic) IBOutlet MyCommonView *commonView;
#end
Create a viewController that acts as a parent view for all your common stuff, call it CommonViewController then implement this in all the viewcontrollers you want it to appear
-(void) viewDidLoad
{
[self.view addSubView:[[CommonViewController alloc] initWithRect:..];
}
Or alternatively using xib files

how can i give input for UILabel in iPhone

i have 2 classes . in my first class i have one label. now i have to give input for that label from my second class.
here is my code.
IBOutlet UILabel *label1;
#property(nonatomic, retain) IBOutlet UILabel *label1;
#synthesize label1;
I call this label like this.
I import my class1 and create object like classone.
I checked(NSLog print)class and that method will be called but that input won't come.i checked that label its also connected to my class.because i give same input in my viewDidLoad that time its working fine.
NSString *ram= #":13123123312";
classone.label1.text= ram;
guide me where i'm doing wrong.
Setting values of previous views is trickier than this. What it the view has been removed by the OS under memory pressure?
The proper way of setting these values is to use the MVC pattern that is used throughout the Cocoa frameworks. Your second view controller sets a property of the previous view controller. And when the previous view needs to be shown, it takes its value from this property.
The usual way to correctly hook up a view controller to talk back to a another view controller lower in the stack is to use a delegate protocol.
I wrote an example of this, DelegationExample,a while ago which shows how a textfield in the first view is populated by a textfield's value in the second view controller using a delegate protocol. You might find it useful to see how I have done this as an example.
Update
I've updated the link to a new project for iOS6 with ARC and Storyboards
Take one NSString variable in AppDelegate class and synthesize it properly. And store the value of the second class's variable to that like:
appDelegate.strLbl = [NSString stringWithformat:#"%#",strVal];
and then copy that value to the label in first class like:
lblVal.text = [NSString stringWithformat:#"%#",appDelegate.strLbl];
Hope that helps you. Thanks.
Actually you should have the reference of the first class in the second class. You should not allocate a new instance. If you create new instance, then the instance for which you have set the label value is different from the actual one which you will see on clicking back.
I guess you got this.
Aadhira was right, when u create a new instance of class1 in class2 its wrong,
You have to get the original instance of class1, this can be achieved by creating a static function which returns current instance of class1, as shown below
static classone* sInstance;
#implementation classone
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization.
}
sInstance = self;
return self;
}
+(classone*) getInstance {
// NSAssert (sInstance!=nil, #"classone:getInstance: called when singleton was not initialized!");
return sInstance;
}

How to get UITextField String from ViewController to NSObject

Hi i am trying to pass the value from my UITextfield that is declared and being used in my ViewController over to an NSObject I have created that needs the value in it to perform an operation. I'm just not sure what I have to do, I have tried this
I have declared the UITextField in my ViewControllers header file and created an IBOutlet for it.
Then I have #imported this into my NSObject and tried to call it like this
NSString *tempTextField = regTextField.text;
and its getting a error 'regTextField not defined'.
If regTextField is defined in your ViewController subclass, then you probably want to set the text field in your NSObject from your view controller. I would import your NSObject into the view controller and then have an NSString property in your NSObject that you can set from the viewController.
myClass.fieldIWantToSet = self.regTextField.text;
Hope this helps.

Objective C terminology: outlets & delegates

I'm having issues understanding the concept of outlets how the iPhone deals with events. Help! Delegates confuse me too. Would someone care to explain, please?
Outlets (in Interface Builder) are member variables in a class where objects in the designer are assigned when they are loaded at runtime. The IBOutlet macro (which is an empty #define) signals Interface Builder to recognise it as an outlet to show in the designer.
For example, if I drag out a button, then connect it to the aButton outlet (defined in my interface .h file), the loading of the NIB file at runtime will assign aButton the pointer to that UIButton instantiated by the NIB.
#interface MyViewController : UIViewController {
UIButton *aButton;
}
#property(nonatomic, retain) IBOutlet UIButton *aButton;
#end
Then in the implementation:
#implementation MyViewController
#synthesize aButton; // Generate -aButton and -setAButton: messages
-(void)viewDidAppear {
[aButton setText:#"Do Not Push. No, seriously!"];
}
#end
This eliminates the need to write code to instantiate and assign the GUI objects at runtime.
As for Delegates, they are event receiving objects used by another object (usually a generalised API class such as a table view). There's nothing inherently special about them. It's more of a design pattern. The delegate class may define several of the expected messages such as:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
...and the API object calls this message on the delegate when it wants to notify it of the event. For example:
-(void)update:(double)time {
if (completed) {
[delegate process:self didComplete:totalTimeTaken];
}
}
And the delegate defines the message:
-(void)process:(Process *)process didComplete:(double)totalTimeTaken {
NSString *log = [NSString stringWithFormat:#"Process completed in %2.2f seconds.", totalTimeTaken];
NSLog(log);
}
Such use might be:
Process *proc = [Process new];
[proc setDelegate:taskLogger];
[proc performTask:someTask];
// Output:
// "Process completed in 21.23 seconds."
A delegate is a object that another object can forward messages to. In other words, it's like when your mom told you to clean your room and you pawned it off on your little brother. Your little bro knows how to do the job (since you were too lazy to ever learn) and so he does it for you.