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;
Related
This question already has answers here:
What's the best way to communicate between view controllers?
(4 answers)
Closed 9 years ago.
I have NSObject class that has a NSString called tweetTitle;
TweetDesc.h file
#import <Foundation/Foundation.h>
#interface TweetDesc : NSObject
#property (strong, nonatomic) NSString * tweetTitle;
-(void) setFullTweetTitle:(NSString *) fullTweetTitle;
#end
TweetDesc.m file
#implementation TweetDesc
#synthesize tweetTitle;
-(void) setFullTweetTitle:(NSString *) fullTweetTitle
{
self.tweetTitle = fullTweetTitle;
}
#end
I have three classes (View Controllers), FirstViewController, SecondViewController and ThirdViewController.
Here are the code of FirstViewController
FirstViewController.h
#interface TweetViewController : UIViewController <UITextViewDelegate>
#property (strong, nonatomic) NSString * tweet;
#property (weak, nonatomic) IBOutlet UITextView *tvTweetTitle;
- (IBAction)btnCreateTweet:(id)sender;
#end
FirstViewController.m
#implementation TweetViewController
#synthesize tvTweetTitle, tweet;
- (void)viewDidLoad
{
[super viewDidLoad];
self.tvTweetTitle.delegate = self;
}
- (IBAction)btnCreateTweet:(id)sender
{
tweet = [[NSString alloc]initWithFormat:#"%#", tvTweetTitle.text];
TweetDesc * td = [[TweetDesc alloc]init];
[td setFullTweetTitle:tweet];
SecondViewController * svc = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
[self.navigationController pushViewController:ivc animated:YES];
}
My Question is: How can I use tweetTitle in Second and third ViewController without creating new instance of TweetDesc class and set again the tweetTitle in every ViewControler.
In the second view controller I tried:
TweetDesc * td = [[TweetDesc alloc]init];
NSLog(#"%#", td.tweetTitle);
but I get null, it seems that it was released already or something else.
Thanks for the help in advance.
Just give SecondViewController a TweetDesc property, like this:
#interface TweetDesc : UIViewController
#property (nonatomic, strong) TweetDesc *tweetDesc;
...
Then, after you instantiate a SecondViewController, set its tweetDesc property:
SecondViewController * svc = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
svc.tweetDesc = td;
[self.navigationController pushViewController:svc animated:YES];
In your SecondViewController implementation, use self.tweetDesc to access the instance.
First thing you don't need a class for a single property use the string only. There are several ways of doing this.
First you can have a tweet property globally defined in AppDelegate.
You can pass the variable reference from one to another viewcontrolleres.
Or, you can use NSUserDefaults to set and get the text.
In your case first one is more useful. Just do as follows
In AppDelegate.h
Define a property as NSString *tweetText;
Now in you action
- (IBAction)btnCreateTweet:(id)sender
{
AppDelegate *appDelegate=(AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.tweetText=tvTweetTitle.text;
}
Then in any controller you want to access the value just use
AppDelegate *appDelegate=(AppDelegate *)[[UIApplication sharedApplication] delegate];
NSLog("%#",appDelegate.tweetText);
Same approach can be used for NSUserDefaults as to set value
[[NSUserDefaults standardUserDefaults] setObject:tvTweetTitle.text forKey:#"Tweet"];
[[NSUserDefaults standardUserDefaults] synchronize];
and to get
NSLog("%#",[[NSUserDefaults standardUserDefaults] valueForKey:#"Tweet"]);
Make sure you set the values before navigating to other controllers..
The above should solve your purpose..
Based on your comment I feel you want each of your view controllers to hold a TweetDesc object. For that you could have a base class like
#interface baseViewController:UIViewController
#property(strong, nonatomic)TweetDesc *td;
#end
All your viewcontrollers should derive from this base class. So that your controllers definition look like this -
#interface FirstViewController:baseViewController
...
#end
#interface SecondViewController:baseViewController
...
#end
#interface ThirdViewController:baseViewController
...
#end
U instantiate it in the FirstViewController -
TweetDesc * td = [[TweetDesc alloc]init];
[td setFullTweetTitle:#"whatever string you want"];
And pass it on to SecondViewController - //like in Rob Mayoff's answer
SecondViewController * svc = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
svc.tweetDesc = td;
[self.navigationController pushViewController:svc animated:YES];
INSIDE SecondViewController you may refer it as self.tweetDesc. And pass it on to whichever viewcontroller you want after this using the above code.
ThirdViewController *third= [self.storyboard instantiateViewControllerWithIdentifier:#"ThirdViewController "];
third.tweetDesc = self.tweetDesc;
[self.navigationController pushViewController:third animated:YES];
Pass it on the ANY viewcontroller just make sure it's base class is the baseClassViewController.
You need to use category of TweetDesc where you create method that adds your default title. Or you can create singleton of TweetDesc that will always hold one title.
In your ViewController create a method called initWithTweetDesc. The method will look like this:
- (id)initWithTweetDesc:(TweetDesc*)tweet
{
self = [super init];
if (self) {
_tweet = tweet;
}
return self;
}
Now, when you want to move to the new view controller, run this code:
TweetViewController *vc = [[TweetViewController alloc] initWithTweetDesc:tweetDesc];
[self.navigationController pushViewController:vc animated:YES];
You can use your AppDelegate for this.
eclare the property #property(nonatomic, strong) TweetDesc * td; in AppDelegate.h file.
And change the method like:
- (IBAction)btnCreateTweet:(id)sender
{
tweet = [[NSString alloc]initWithFormat:#"%#", tvTweetTitle.text];
TweetDesc * td = [[TweetDesc alloc]init];
[td setFullTweetTitle:tweet];
[[[UIApplication sharedApplication] delegate] setTd:td];
SecondViewController * svc = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
[self.navigationController pushViewController:ivc animated:YES];
}
And in your second and third view controllers you can get the value using:
TweetDesc *desc = [[[UIApplication sharedApplication] delegate] td];
NSLog(#"%#",desc.fullTweetTitle);
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];
}
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.
I have a function that returns a NSUrl, and i want to use it in another class. But when i tried to retrieve it in my other class, it gives me null.
This is my First Class
#interface UOEventDetailController : UIViewController {
NSURL *imgData;
}
#property(nonatomic, retain)NSURL *imgData;
-(NSURL *)imgData;
#implementation UOEventDetailController
#synthesize imgData;
The .m File
-(NSURL *)imgData{
UOEventPost *post = (UOEventPost *)self.event;
NSURL *url = [NSURL URLWithString:post.postImageURL];
return url;
}
I want to retrieve the URL in this class
#class UOEventDetailController;
#interface UOEnlargeImageViewController : UIViewController {
IBOutlet UIImageView *enlargedImage;
}
#property (nonatomic, retain) UOEventDetailController *controller;
#property (nonatomic, retain) IBOutlet UIImageView *enlargedImage;
the .m file
#implementation UOEnlargeImageViewController
#synthesize controller;
#synthesize enlargedImage;
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Enlarged Image";
controller = [[UOEventDetailController alloc]init];
NSURL *url = [controller imgData];
NSLog(#"%#",url);
}
#end
I can retrieve objects other than post.postImageUrl.
For Example
instead of post.postImageUrl, i put in string like #"omg", #"god"
it gets retrieved in my other class...
EDIT
-(IBAction)enlargeImg{
UOEventPost *post = (UOEventPost *)self.event;
UOEnlargeImageViewController *enlarge = [[UOEnlargeImageViewController alloc]initWithNibName:nil bundle:nil];
enlarge.temp = post.postImageURL;
[self.navigationController pushViewController:enlarge animated:YES];
[suggestPopupView removeFromSuperview];
[enlarge release];
}
this is because you are making a new object. and that of new object, relevent attributes are empty and hence url is also null.
The Object will be null as a new object is being created and it's not in same state as you want it , you must use protocol & delegate to pass the object to another class if flow is backward else ensure that you work on the same object.
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.