why I can't transfer variables between two view controllers this way? - iphone

I have one view who calculates location and reverser geocode to get the zip code. Then it calls another view where I want to display weather results based on that zip code.
In the first view controller I do this once user clicks on the button to turn the page:
- (IBAction) showMyWeather : (id)sender {
WeatherApp *weather = [[WeatherApp alloc] initWithNibName:nil bundle:nil];
weather.zipcode = placemarkZip; //this one seems not to be doing the job
weather.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:weather animated:YES];
}
And at the WeatherApp I would like to read now zipcode, which is declared in this view controller .h:
#interface WeatherApp : UIViewController{
IBOutlet UIButton *done;
MKPlacemark *zipcode;
}
#property (nonatomic, retain) MKPlacemark *zipcode;
How can I use this code to transfer this zipcode to the WeatherApp? Thanks!

Yes, this is a fine way to pass information into your new object.
Alternatively, you could create a custom initializer for WeatherApp like
- (id)initWithZipCode:(NSString *)zip;
and then in the implementation file, it could be like this:
- (id)initWithZipCode:(NSString *)zip
{
self = [super init];
[self setZipcode:zip];
return self;
}
Finally, you could instantiate the class like so:
- (IBAction)showMyWeather:(id)sender
{
WeatherApp *weather = [[WeatherApp alloc] initWithZipCode:placemarkZip];
[weather setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentModalViewController:weather animated:YES];
[weather release]; // No longer needed with ARC... just sayin'
}
Finally, if you're going to continue to pass in information as you do above, I'd question why you're using initWithNibName:bundle:. If you're just going to pass nil to both, why not just use [[WeatherApp alloc] init]?

Related

objective C switching from a view to another

I am new to the objective C programming and I am in a position where I need to create an iPhone App really quickly.
I am using XCode 4.2
I have a problem transferring an NSString variable from one view to the other .
the two views are in two different sets of .h and .m classes
in the first class in the .h i have something like this
#interface firstview : UIViewController {
NSString *test;
}
-(IBAction)testbutton
#end
in the .m of the firstview I have
-(IBAction)testbutton{
secondView *second;
[second setText:text]; //set text is a function that will take an NSString parameter
second= [[secondView alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:second animated:YES];
}
in the .h of the secondView I wrote
#interface secondView : UIViewController{
-IB
}
You've got the right idea, but you're trying to call -setText: before second points to a valid object! Do this instead:
-(IBAction)testbutton{
secondView *second;
second = [[secondView alloc] initWithNibName:nil bundle:nil];
[second setText:text]; //set text is a function that will take an NSString parameter
[self presentModalViewController:second animated:YES];
}
Also, the interface you give for your secondView class looks both incorrect and incomplete -- I'm not sure what you're trying to do with the -IB part. And it'd help in the future if you follow the usual Objective-C naming convention and start class names with an uppercase character: SecondView instead of secondView. Finally, I'd advise against naming a view controller ending in "...View", since that makes it easy to confuse the view controller with a UIView. All together, it should look something like this:
#interface SecondViewController : UIViewController{
NSString *text;
}
#property (retain, nonatomic) NSString *text;
#end
Declaring text as an instance variable is optional there -- if you don't do it, the compiler will create an ivar if you synthesize the accessors for your text property.
Change your code to this:
-(IBAction)testbutton{
secondView *second;
second = [[secondView alloc] initWithNibName:nil bundle:nil];
[second setText:text]; //set text is a function that will take an NSString parameter
[self presentModalViewController:second animated:YES];
}
In your original version, you were initializing (i.e. instantiating) your second view after calling setText: on it. You need to initialize it and then set the text.
You need to set the text after you allocate and initialize.
-(IBAction) testButton {
secondView *second = [[[secondView alloc] initWithNibName:nil bundle:nil] autorelease];
[second setText:text];
[self presentModalViewController:second animated:YES];
}

how to copy a string from one view and display it in the next view?(iphone)

hi everyone i am new to iphone development.
Actually i am trying with some sample app where i have a textField in the Viewcontroller and a Button,when i enter a string in the textfield and press the button it should display the same string in NextView.so can anyone help me out in doing this.
i worked with transition between one view to another view,but i need copy string from Viewcontroller1 to NextView
#ViewController1
-(IBAction)next
{
NextView *Nview = [[NextView alloc]initWithNibName:#"NextView" bundle:nil];
[self.view addSubview:Nview.view];
}
Set an ivar in your NextView called "newString" for example, then pass a string to that ivar form your first controller.
For Example, not tested (and this is one of many ways you can do this):
FirstView
NextView * next = [[NextView alloc] initWithNewString: myTextField.text];
[self.navigationController presentModalViewController: next animated: YES];
NextView
#synthesize newString
-(id)initWithNewString:(NSString*)someString
{
newString = someString;
return self;
}
Then throughout your NextView, just call upon newString wherever you want to get the value of the previous views textField.
-(IBAction)next
{
NextView *Nview = [[NextView alloc]initWithNibName:#"NextView" bundle:nil];
Nview.string_Object=string_to_copy;//declare string_Object in NextView.h
[self.view addSubview:Nview.view];
}
Try this:
In your first view while naviagting:
NextView *nav = [[NextView alloc] init];
nav.textFieldValue = textField.text;
[self.navigationController pushViewController:nav animated:YES];
And in your NextView's .h file create a property:
#property(nonatomic, retain) NSString *textFieldValue;
And in .m file synthesize it like:
#synthesize textFieldValue;
Now you can use textFieldValue in NextView class
P.S: Don't forget to release it :)
As you are a beginner, this will be a good guidance for you to understand the exact flow and it will make you learn how to pass values from one class to another.
Here is an approach (haven't tested, but should work)
Give your textField a tag value like
textField.tag = 1;
and in NextView access it like
UITextField *parentViewTextField = (UITextField*)[self.superview viewWithTag:1]

how to Pass values between views in popViewControllerAnimated?

I want to know how to pass values between views in popViewControllerAnimated .
Here is my scenario:
I have a view which contains tableview on selecting the cell we go to another view where i need to enter value in textbox and i click a button to go back to the previous view where i need to display the textbox value in the table view cell.
How can i do this ?
This what i have done:
NewContact *nc = [[NewContact alloc] initWithNibName:#"NewContact" bundle:nil];
// ...
// Pass the selected object to the new view controller.
nc.name=[firstName text];
//[self.navigationController pushViewController:nc animated:YES];
[self.navigationController popViewControllerAnimated:YES];
[nc release];
In ViewControllerB, declare delegate and set action for popViewControllerAnimated:
#interface ViewControllerB : UIViewController {
id delegate;
}
#property (nonatomic, retain) id delegate;
#synthesize delegate;
- (id) init ... {
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(didBack:)] autorelease];
}
- (void) didBack:(id)sender {
if ([delegate respondsToSelector:#selector(setProperty:)]) {
[delegate setProperty:property];
}
[self.navigationController popViewControllerAnimated:YES];
}
In ViewControllerA, provide a function to set the local property and set delegate:
ViewControllerB controllerB = [[ViewControllerB alloc] init...];
[controllerB setDelegate:self];
[self.navigationController pushViewController:controllerB animated:YES];
[controllerB release];
You need to store value in one of the global variable for example you can declare in appDelegate file. See this post for that
If you are using UITextField then you can store value in above variable from UITextField in below delegate method.
- (BOOL)textFieldShouldReturn:(UITextField *)textField;
Hope this help.
You could use NSNotificationCenter for this, passing an object along with the call.
Howto: Send and receive messages through NSNotificationCenter in Objective-C?
Based on your requirement in your comment,
Say you navigate from ViewControllerA instance to ViewControllerB instance and you wish to call ViewControllerA's methods, you can do it like this,
ViewControllerA * viewControllerA = (ViewControllerA *)self.parentViewController.
[viewController methodToCall];
To use this to address the requirement in the question, you can use a property.
viewControllerA.name = firstName.text; // Bits from your code snippet
However in a table view I would expect you to have a mutable array powering the data source. You can refer to it, assuming that it is an property.
[viewControllerA.dataSourceArray addObject:firstName.text];

Value from parentViewController

This class is a subclass of UITabBarViewController.
In my init parent view controller file I have this:
UIBarButtonItem *button1 = [[UIBarButtonItem alloc]
initWithTitle:#"Button1"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(button1:)];
self.navigationItem.rightBarButtonItem = button1;
[button1 release];
And the method:
-(IBAction)button1:(id)sender {
if (self.nvc == nil) {
ChildViewController *vc = [[ChildViewController alloc] init];
self.nvc = vc;
[vc release];
}
[self presentModalViewController:self.nvc animated:YES];
I want to get an value from the parentviewcontroller in my childviewcontroller class, which also is a UITabBarViewController subclass.
How do I do this, I have tried several hours, and I only get a nil-reference.
The object I want to get(which is a property in the parent) is a NSString.
Thanks in advance
The cleanest way would probably be to create a ChildViewControllerDelegate protocol that the parent view controller implements. This is a common idiom in iOS development.
#protocol ChildViewControllerDelegate
- (NSString *)getSomeNSString;
#end
Then you should make ChildViewController have this delegate as an instance variable and be assignable via a property
#property (nonatomic, assign) id<ChildViewControllerDelegate> delegate;
Now from within ChildViewController you can use this delegate to access methods on the delegate which in your case will be ParentViewController. This will allow you to retreive the string you want.
[delegate getSomeNSString]
This may seem like a lot of work for something simple but it avoids the problems inherit with storing a back reference from ChildViewController to its parent ParentViewController.
There are a lot of ways to do this. The easiest would be to add a property to ChildViewController that points to your parent view controller. You could call it delegate. Then the method will look like:
-(IBAction)newbuilding:(id)sender {
if (self.nvc == nil) {
ChildViewController *vc = [[ChildViewController alloc] init];
vc.delegate = self;
self.nvc = vc;
[vc release];
}
[self presentModalViewController:self.nvc animated:YES];
}
Then from the ChildViewController instance you can access self.delegate.someProperty.
There are also ways to get the parent view controller without your own explicit reference (typically self.tabBarController, self.navigationController depending on context), but the above method is fool-proof, understandable and easy to debug.

presentmodalviewcontroller not working properly in Application Delegate in iPhone

I'm using two UIViewController in Application Delegate and navigating to UIViewController using presentmodalviewcontroller. But Problem is that presentmodalviewcontroller works for first time UIViewController and when i want to navigate to second UIViewController using presentmodalviewcontroller then its showing first UIViewController.
The following is the code:-
-(void)removeTabBar:(NSString *)str
{
HelpViewController *hvc =[[HelpViewController alloc] initWithNibName:#"HelpViewController" bundle:[NSBundle mainBundle]];
VideoPlaylistViewController *vpvc =[[VideoPlaylistViewController alloc] initWithNibName:#"VideoPlaylistViewController" bundle:[NSBundle mainBundle]];
if ([str isEqualToString:#"Help"])
{
[tabBarController.view removeFromSuperview];
[vpvc dismissModalViewControllerAnimated:YES];
[viewController presentModalViewController:hvc animated:YES];
[hvc release];
}
if ([str isEqualToString:#"VideoPlaylist"])
{
[hvc dismissModalViewControllerAnimated:YES];
[viewController presentModalViewController:vpvc animated:YES];
[vpvc release];
}
}
Can Somebody help me in solving the problem?
You're making a new hvc and vpvc each time you run this function.
The first time through, I assume you call removeTabBar:#"Help", it makes a hvc and vpvc and then shows the correct one.
The second time you call it removeTabBar:#"VideoPlayList", you are making a new hvc and vpvc. This means that when you call hvc dismissModalViewController:YES]; you're not removing the one you added before, you're removing the new one that you just made which isn't being displayed at all!
To solve this you need to make your two controllers as properties in your app delegate and create them in the applicationDidFinishLaunching method.
Add these into your app delegate's .h file:
#class MyAppDelegate {
HelpViewController *hvc;
VideoPlaylistViewController *vpvc;
}
#property (nonatomic, retain) HelpViewController *hvc;
#property (nonatomic, retain) VideoPlaylistViewController *vpvc;
#end
and in your app delegate's .m file :
- (void)applicationDidFinishLaunching:(UIApplication *)application {
...
self.hvc = [[[HelpViewController alloc] initWithNibName:#"HelpViewController" bundle:nil] autorelease];
self.vpvc = [[[VideoPlaylistViewController alloc] initWithNibName:#"VideoPlaylistViewController" bundle:nil] autorelease];
...
}
and remove the first two lines in removeTabBar