I have a view controller and a class (I am using storyboards). How can I change the text of a UILabel (in the view controller) from the class? I have tried this, but to no avail:
ViewController *mainView = [[ViewController alloc] init];
[mainView view];
[mainView.progressBar setProgress:integer animated:YES];
NSLog(#"Updated Progress Bar");
NSString *progressLabelText = [NSString stringWithFormat:#"%# out of %i followers", userString, [self.followers count]];
[mainView.progressLabel setText:progressLabelText];
NSLog(#"Updated Progress Label Text: %#", progressLabelText);
The text does not change using this code. What should I be doing instead?
Edit: The progressbar and label in the ViewController's .h file look like this:
#property (nonatomic, strong) IBOutlet UIProgressView *progressBar;
#property (nonatomic, strong) IBOutlet UILabel *progressLabel;
And they are fully linked up in Interface Builder.
Use delegate for messaging between classes or viewcontrollers.
Refer The Basics of Protocols and Delegates link.
Try to use Notification for updating the Lable text.
in your viewController write this:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(updateLabel) name:#"lblUpdate" object:nil];
and selector is :
-(void)updateLabel
{
self.lblObject.text = #"Your updated text"
}
and now in your Class call this using Post notification:
[[NSNotificationCenter defaultCenter] postNotificationName:#"lblUpdate" object:nil];
remember use same notification name "lblUpdate"
just property synthesize the string and then set that string in viewWillAppear: method of ViewController.m class
just take NSString variable in ViewController.h file like bellow..
#property (nonatomic, retain) NSString *progressText;
and synthesize this in ViewController.m file like bellow..
#synthesize progressText;
after that in viewDidLoad: method just set text at starting to the progressLableText like bellow...
- (void)viewDidLoad
{
progressText = #"Your Text";
[progressLabel setText:progressText];
}
and also in viewWillAppear: set the text like above...
- (void)viewWillAppear:(BOOL)animated
{
[progressLabel setText:progressText];
}
and in your code just change something like bellow..
ViewController *mainView = [[ViewController alloc] init];
[mainView view];
[mainView.progressBar setProgress:integer animated:YES];
NSLog(#"Updated Progress Bar");
NSString *progressLabelText = [NSString stringWithFormat:#"%# out of %i followers", userString, [self.followers count]];
mainView.progressText = progressLabelText;
[mainView.progressText retain];
NSLog(#"Updated Progress Label Text: %#", progressLabelText);
i hope this helpful to you...
But use a delegate to do the callbacks.
In your spamchecker.h add:
#protocol SpamCheckerDelegate <NSObject>
-(void)updateText:(NSString*)newText;
#end
#property (nonatomic, weak) id <SpamCheckerDelegate> delegate;
In your spamchecker.m where you need it add:
[self.delegate updateText:#"newText"];
Then in your mainView.h add:
#interface MainView : UIViewController <SpamCheckerDelegate>
In your mainview.m add:
spamchecker.delegate = self;
And implement the method like:
-(void)updateText:(NSString*)newText
{
[self.progressLabel setText:progressLabelText];
}
Related
I have to pass a UITextField value from one view to other views(2nd,3rd...views).Actually in my 3rd ViewController I have a scrollView and I have to display value on it .But UITextField value is not getting passed.It is returning null.Couldn't get what might be wrong?
THis is the code I am working with:
In ViewController1.m:
-(IBAction)butonclick:(id)sender{
ViewController2 *view2=[ViewController2 alloc];
view2.id=name.text;
ViewController3 *view3=[ViewController3 alloc];
view3.id=name.text;
[view2 release];
[view3 release];
}
IN ViewConroller2.h :
#interface ViewController2 : UIViewController {
NSString *id;
UIlabel *displayId;
}
In ViewController2.m :
- (void)viewDidLoad
{
self.displayId.text=self.id;
}
In ViewController3.h:
#interface ViewController2 : UIViewController {
NSString *id;
UIlabel *dispId;
}
In ViewController3.m :
- (void)viewDidLoad
{
self.dispId.text=self.id;
}
But here the id value is not passed to ViewController3.It is returning null ..Where I m going wrong?
You are passing the values without initializing.
ViewController2 *view2=[[ViewController2 alloc]init];
view2.id=name.text;
ViewController3 *view3=[[ViewController3 alloc]init];
view3.id=name.text;
If you want to use object globally within your app, you can declare it in the appDelegate.
In AppDelegate.h
#interface AppDelegate : NSObject <NSApplicationDelegate>
{
NSString *idGlobal;
}
#property (nonatomic, retain) NSString *idGlobal;
In AppDelegate.m
#synthesize idGlobal;
In ViewController1.m:
-(IBAction)butonclick:(id)sender{
appDelegate.idGlobal=name.text;
}
In ViewController2.m: and
In ViewController3.m:
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
id=appDelegate.idGlobal;
Declare the string globally in the AppDelegate.h this will help in keeping the value of the string constant throughout the files. Also wherever you want to add the string or change its value or assign it import the AppDelegate.h .
Also check these links :-
passing NSString from one class to the other
Pass NSString from one class to another
I am just correcting the code you have written meanwhile the suggestions given above for using AppDelegate property is a good one.
The main problem with your code is that you are just declaring NSString object instead of making it a property. Check this:
-(IBAction)butonclick:(id)sender{
ViewController2 *view2=[ViewController2 alloc]init];
view2.str=name.text;
ViewController3 *view3=[ViewController3 alloc]init;
view3.str=name.text;
[view2 release];
[view3 release];
}
IN ViewConroller2.h :
#interface ViewController2 : UIViewController {
NSString *str;
UIlabel *displayId;
}
#property(nonatomic, retain) NSString* str; //Synthesize it in .m file
In ViewController2.m :
- (void)viewDidLoad
{
self.displayId.text=self.str;
}
In ViewController3.h:
#interface ViewController2 : UIViewController {
NSString *str;
UIlabel *dispId;
}
#property(nonatomic, retain) NSString* str; //Synthesize it in .m file
In ViewController3.m :
- (void)viewDidLoad
{
self.dispId.text=self.str;
}
I am not aware with your scenario but the most effective way of implementing such situations is using Delegates. Make a delegate of the class where your string is being set (ViewController1) and set delegate accordingly in your other view controllers.
hi i am new to iphone development.
I'm trying with sample where I need to copy a string from the textfield of viewController and display it on the next view with a Label.
On the first view there is button bellow the textfield.1
I am not able to fix some issues showing BAD ACESS can anyone help me in solving this.
Let me know what i'm doing Wrong.
Thank you.
//copystring.h
#interface CopystringViewController : UIViewController{
UITextField *myTextField;
NSString *somestring;
}
#property(nonatomic,retain)IBOutlet UITextField *myTextfield;
#property(nonatomic,retain)NSString *somestring;
-(IBAction)next:(id)sender;
//.m file
#synthesize myTextfield,somestring;
-(IBAction)next:(id)sender;
{
NextView * next = [[NextView alloc] initWithNewString: myTextField.text];
[self.navigationController presentModalViewController: next animated: YES];
}
NextView.h
#interface NextView : UIViewController{
UILabel *string2;
}
#property(nonatomic,retain)IBOutlet UILabel *string2;
- (id)initWithNewString:(NSString*)someString;
//.m file
#synthesize string2;
-(id)initWithNewString:(NSString*)someString {
string2 = someString;
return self;
}
Just replace method.it may run.
-(IBAction)next:(id)sender; {
NextView * next = [[NextView alloc] initWithNibName:#"NextView" bundle:nil];
next.string2=myTextField.text;
[self.navigationController presentModalViewController:next animated: YES];
}
hey string2 is a label so try string2.text = somestring;
-(id)initWithNewString:(NSString*)someString {
string2.text = someString;
return self;
}
It looks like the problem is that you're assigning an NSString (someString) to a UILabel (string2).
AppleVijay's answer should do the trick.
If you don't like dot-notation in ObjC you can also write it like this:
[string2 setText:someString]
U can declare ur somestring in to the delagate h/m file that way it wil be the global string. u can use it with appdaligateobj.stringname.
U dont evn need init u can directly add to viewdidload of next view.
string2.text = AppDalegateobj.stringName.
Delegation is the usual way to move data around like this. I wrote a very simple example project to show this in action.
You need init you view and retain you string:
-(id)initWithNewString:(NSString*)someString {
self = [super init];
if (self) {
string2.text = someString;
}
return self;
}
/
/AppDelegate.h
NSString *String1;
#property (nonatomic, retain) NSString * String1;
//AppDelegate.m
#synthesize String1
//ViewController1.h
AppDelegate * objAppDelegate;
UILable *lblstring;
#property (nonatomic, retain) UILable *lblstring;
//ViewController1.m
#synthesize lblstring
//On View Did Load.
objAppDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
lblstring.text = objAppDelegate.String1;
I defined a UITextField on my firstViewController as follow
// firstViewController.h
IBOutlet UITextField *PickUpAddress
#property (nonatomic, retain) UITextField *PickUpAddress;
//firstViewController.m
#synthesize PickUpAddress;
// Push secondView when the 'Done' keyboard button is pressed
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
if (textField == PickUpAddress) {
SecondViewController *secondViewController= [[SecondViewController alloc]
initWithNibName:#"SecondViewController"
bundle:nil];
secondViewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:secondViewController animated:YES];
[secondViewController release];
}
return NO;
}
Then I tried to retrive it in my secondViewController during viewWillAppear
- (void)viewWillAppear:(BOOL)animated {
BookingViewController *bookingViewController = [[BookingViewController alloc] init];
NSString *addressString = [[NSString alloc] init];
addressString = bookingViewController.PickUpAddress.text;
NSLog(#"addressString is %#", bookingViewController.PickUpAddress.text);
}
But it returns as NULL on my console. Why is that so?
Thanks in advance :)
in secondViewController.h add
NSString *text;
#property (nonatomic, retain) NSString *text;
-(void)setTextFromText:(NSString *)fromText;
in secondViewController.m add following
- (void)setTextFromText:(NSString *)fromText
{
[text release];
[fromText retain];
text = fromText;
}
in firstViewController.m
before
[self.navigationController pushViewController:secondViewController animated:YES];
add
[secondViewContoller setTextFromText:PickUpAddress.text];
Now let me explain the code.
You are adding an NSString to second view , where we will store the text from the UITextField. Then, we've written a method, which will set that NSString from some other NSString.
Before pushing secondViewController to navigationController, you're just calling that method to set our text from PickUpAddress.text.
Hope that helped.
Problem is in your code. You are creating new object, bookingViewController, to retrieve the textField value. So it will obviously provide NULL. Rather you should use one unique object application wide to access the value.
I'm new to Objective C and I'm having trouble getting delegates to work in my code.
I have a class called cViewController and in this class has a UIWebView to fetch webpages and a button above it that calls a popover class called prodMenu. What I'm having trouble with is that the function to call webpages from the prodMenu class and display it on the parent UIWebView isn't working.
cViewController.h
#import <UIKit/UIKit.h>
#import "prodMenu.h"
#interface cViewController : UIViewController <prodMenuDelegate>{
UIPopoverController *cpopover;
IBOutlet UIWebView *webImageDisplay;
}
#property (nonatomic, retain) UIWebView *webImageDisplay;
#property (nonatomic, retain) UIPopoverController *cpopover;
- (IBAction)cPopoverTapped:(id)sender;
- (void) fetchWebsite:(NSString *)website; //This is the delegate method I'm trying to call in the popover class.
#end
cViewController.m
- (IBAction)cPopoverTapped:(id)sender {
prodMenu *tp = [[prodMenu alloc] init];
cpopover = [[UIPopoverController alloc] initWithContentViewController:tp];
[tp release];
CGRect rect = CGRectMake(40, 0, 50, 50);
cpopover.popoverContentSize = CGSizeMake(250, 225);
[cpopover presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
- (void)fetchWebsite:(NSString*)website{ //This function is called by prodMenu class
NSLog(#"address: %#", website);
NSString *urlAddress = website;
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webImageDisplay loadRequest:requestObj];
[webImageDisplay release];
}
- (void)viewDidLoad {
[self fetchWebsite:#"http://www.yahoo.com"];
[super viewDidLoad];
}
prodMenu.h
#import <UIKit/UIKit.h>
#protocol prodMenuDelegate;
#interface prodMenu : UIViewController{
<prodMenuDelegate> delegate;
}
- (IBAction)radBtn:(id)sender; //This is the IBAction that calls the fetchWebsite function
#property (nonatomic, assign) id <prodMenuDelegate> delegate;
#end
#protocol prodMenuDelegate
- (void)fetchWebsite:(NSString *)website;
#end
prodMenu.m
#import "prodMenu.h"
#import "cViewController.h"
#implementation prodMenu
#synthesize delegate;
- (IBAction)radBtn:(id)sender{
[delegate fetchWebsite:#"http://www.google.com"]; //Here is the call to the method
}
Am I missing something here to call the delegate method? There aren't any errors or warnings. All I want to do is when the user presses a button on the popover view, the parent class underneath changes the webpage. Thanks in advance.
Just a quick idea. Have you tried declaring the delegate protocol like this
#protocol prodMenuDelegate <NSObject>
...
#end
? I often ran into troubles when omitting the < NSObject >. Also I think there is an 'id' missing in
#interface prodMenu : UIViewController{
<prodMenuDelegate> delegate;
}
Edit: Also, in the code you posted I do not see where you actually assign the prodMenu's delegate.
I know this question as been asked over and over but it's still quite obscure to me, so I guess making an example with my code instead will probably be easier .
I know that you can use :
A global variable, ( not good practice ).
Use a delegate
Use a singleton
Say I've got this piece of code here in my first view controller header :
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController {
IBOutlet UITextField *Te;
NSInteger evTe;
}
#property (nonatomic, retain) UITextField *Te;
#property (nonatomic) NSInteger evTe;
- (IBAction) makeKeyboardGoAway;
#end
and then this in my implementation file
#import "FirstViewController.h"
#implementation FirstViewController
#synthesize Te;
- (IBAction) makeKeyboardGoAway;
{
[Te resignFirstResponder];
evTe = [Te.text intValue];
}
How would I call evTe in my SecondViewController ? ( maybe using a delegate ?) .
This is what I've got in the second view Controller, header :
#interface SecondViewController : UIViewController {
NSInteger evTe;
}
#property (nonatomic) NSInteger evTe;
and implementation :
- (IBAction) makeKeyboardGoAway;
{
FirstViewController *first = [[FirstViewController alloc] init];
first.evTe = self.evTe;
NSLog(#"second value is %i",evTe);
}
Thanks a lot !
Edit for Tob
FirstViewController.m
- (IBAction) makeKeyboardGoAway;
{
evTe = [Te.text intValue];
NSLog(#"The value of integer num is %i", evTe);
NSDictionary *changedValues = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:evTe] forKey:#"evTe"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"evTeChanged" object:self userInfo:changedValues];
}
SecondViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(methodToCall:) name:#"evTeChanged" object:nil];
}
- (void)methodToCall:(NSNotification *)aNotification{
NSDictionary *changedValues = [[aNotification userInfo] objectForKey:#"evTe"];
NSString *dictionaryString = [changedValues description];
NSLog(#"Notification returning %d",dictionaryString);
}
Unfortunately I'm not getting any log from the SecondView ..
By creating a #property called evTe or whatever in both view controllers.
If the FirstViewController is responsible for creating the SecondViewController you could store the value of evTe in a property in FirstViewController and then after you have created the SecondViewController you set the evTe property there as well.
- (IBAction) makeKeyboardGoAway;
{
[Te resignFirstResponder];
self.evTe = [Te.text integerValue];
}
// other method where SecondViewController is created
SecondViewController* second = [[SecondViewController alloc] init];
second.evTe = self.evTe;
// do what ever
--Edit--
#interface FirstViewController : UIViewController {
IBOutlet UITextField *Te;
NSInteger evTe;
}
#property (nonatomic, retain) UITextField *Te;
#property (nonatomic) NSInteger evTe;
Have a look at NSNotification. You should send a notification that the particular value has changed and register for that notification in the second view controller.
- (IBAction) makeKeyboardGoAway;
{
[Te resignFirstResponder];
evTe = [Te.text intValue];
NSDictionary *changedValues = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:evTe] forKey:#"evTe"];
[[NSNotificationCenter defaultCenter] postNotificationName:#"evTeChanged" object:self userInfo:changedValues];
}
And in the viewDidLoad method of the other controller do:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(methodToCall:) name:#"evTeChanged" object:nil];
Now every time the first controller calls makeKeyboardGoAway the method - (void)methodToCall:(NSNotification *)aNotification will be called.
Implement this method and ask the aNotification for its userInfo which is the NSDictionary you created in the first controller before posting the notification. Get the evTe value out of it and do whatever you want to do with that value.