I have 2 view controller:
Index
Second
In Index I have 2 textfield and button.
I fill this text field and press "next button" to second view, I need to "show" this two text field, by using Array (later I will send JSON data).
I Tried this:
Declare an #property in class Second as textArray. And then while pushing to Second from Index, you need to set this property.
In Second.h file,
#property(nonatomic, strong) NSArray *textArray;
In Index.m file,
Second *aSecond = [[Second alloc] init];
aSecond.textArray = #[textField1.text, textField2.text];
//write code to push from Index to Second
Now in class Second, you can use it as aSecond.textArray[0] and aSecond.textArray[1]
But if i switch page (click next) array has been nulled.
For switch page i use this:
SecondPage *SecondPage = [self.storyboard instantiateInitialViewController];
SecondPage = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondPage"];
[self SecondPage animated:YES];
How I can best realize? Please help! Best regards
Ivan.
Write your own designated initializer for second view controller something like.
-(id)initWithTextArray:(NSArray *)_textarray;
Now alloc init the second view controller
Second *aSecond = [[Second alloc] initWithTextArray:array];
in the viewDidLoad method of second view controller use your textarray to populate your views.
You need to do it like this if you are using it via storyboard,
SecondPage *aSecondPage = [self.storyboard instantiateInitialViewController];
aSecondPage = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondPage"];
aSecond.textArray = #[textField1.text, textField2.text];
[self aSecondPage animated:YES];
When you do this aSecond = [[Second alloc] init]; and then do aSecondPage = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondPage"];, it is creating a separate instance and not the same instances. You were setting this array on the first one and expecting it to be set on the second instance.
Hey had you tried for 'Global variable & Array with Delegate Method'. It'll not release till you'll remove. It'll be global till the application instance.
In Delegate Class,
.h File
NSMutableArray *obj;
.m file,
Synthesize & Alloc - init array.
Then,
In ViewContoller .m file
AppDelegate *app;
app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
then,
[app.obj addObject: text1.text];
In Second .m file, you can use it.
NSLog(#" Data : %#", app.obj);
Keep in mind, whenever you want this array, you should initialize 'app' object of 'Delegate' class.
It'll work & stores data globally.
Thanks.
I can think of two methods:
1) Either add a method in Second and after initializing call it and pass the value as an argument to a method. so in Second.m -(void) push :(NSArray *)array{} pass it with "&" before your NSArray name.
2) Create a getter in First. Since its NS, you have to use assign so in First.h you put #property(nonatomic, assign) NSArray *array1;
In First.m you add the #synthesize array1;
and call it with
self.array1 = [#"t", #"e", #"s", #"t"];
And then pass the reference to First class in Second and create a variable in Second.m and get it
NSArray *array1 = first.array1;
You can write your own getter, but not reasonable.
SecondPage *SecondPage = [self.storyboard instantiateInitialViewController];
SecondPage = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondPage"];
[self SecondPage animated:YES];
1) Your variable name and your class name are the same
2) I'm not sure XCode accepted that you wrote [self SecondPage animated:YES];
Finally, did you alloc your array ?
EDIT;
Oh and :
aSecond.textArray = #[textField1.text, textField2.text];
You should write:
[aSecond.textArray addObject:textField1.text]; // using NSMutableArray
There are lot of ways to transfer the value from one controller to an other, but for you I think this will be the most simple ever. Use NSUserDefaults
First Easy Ways
in first Controller
[[NSUserDefaults standardUserDefaults] setObject:#[textField1.text, textField2.text] forKey:#"listOfData"];
in 2nd Controller
NSArray *array = [[NSUserDefaults standardUserDefaults]objectForKey:#"listOfData"];
2nd Easy ways is
DetailVC *detailVC = [self.storyboard instantiateInitialViewController];
detailVC = [self.storyboard instantiateViewControllerWithIdentifier:#"DetailVC"];
detailVC.textArray = #[textField1.text, textField2.text];
Related
I have an app in which I am loading variable view controllers depending on where the user is in the app. This is my code.
-(IBAction)buttonPressed:(id)sender;{
if (mission <1) {
gameViewController *detailViewController = [[gameViewController alloc] initWithNibName:#"gameViewController" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
detailViewController.which2 = which;
}
else if (mission > 0) {
NSString *viewController = #"gameViewController";
NSString *missionViewController = [viewController stringByAppendingString:missionNo];
Class controllerClass = NSClassFromString (missionViewController);
id detailViewController = [[controllerClass alloc] initWithNibName:#"gameViewController" bundle:nil];
NSLog(#"missionViewController;%#",missionViewController);
[self.navigationController pushViewController:detailViewController animated:YES];
detailViewController .which2 = which;
}
}
everything work great except I want to pass a string from the first view controller to the second view controller which ever one that may be.
As you can see I have put in the code just above detailViewController.which2 = which;
I have created the property and synthesized NSString *which in my first view controller and NSString *which2 in all the subsequent view controllers. in the first instance where mission is <1 everything works ok and NSLog shows the string being passed. However with the second detailViewController (which is the variable view controller) I get the error Property 'which2' not found on object of type"_strong id' Does anyone have any suggestion on how to resolve this?
the other viewControllers are gameViewController1, gameViewController2, etc. Each is rather long and complex. But they all load into the same xib file gameViewController. There is a UIlabel that update to one higher once the user finishes that gameView so they can go on the the next on in the series or go back to the main menu. If they go back to the main menu the number is added to "gameViewController" so the correct one is loaded. So I can't specify which view controller is going to load since it depends on the user's place. Thus the missionViewController with the # of mission added to load the correct view controller. Each of the subsequent view controllers has a which2 created and synthesized. What if we pretend that all subsequent view controllers just had a UILabel that is going to display the string "which2 in it. All I want to do is pass the string "which" to the next viewController (whichever one that is) as "which2".
Dynamic binding allows you to send messages to an id as long as the selector exists in the project, but dot-syntax is not allowed.
Changing
detailViewController.which2 = which;
to
[detailViewController setWhich2:which];
should suppress the warning.
write this : `detailViewController .which2 = which;
just before you push navigation controller.`
UPDATE:
Use Protools to update the value.
#protocol MissionProtocol
#required
-(void) updateValue:(NSSTring*) value;
#end
Implement the protocols in your ViewControllers. i.e.
#interface MissionViewController:UIViewController<MissionProtocol>
....
#end
In your implementation file, implement the method updateValue.
-(void) updateValue:(NSString*) value
{
self.which2=value;
}
Then change your original code to:
NSString *viewController = #"gameViewController";
NSString *missionViewController = [viewController stringByAppendingString:missionNo];
Class controllerClass = NSClassFromString (missionViewController);
id<MissionProtocol> detailViewController = [[controllerClass alloc] initWithNibName:#"gameViewController" bundle:nil];
[detailViewController updateValue:which];
I am trying to pass a string back and forth between the view Controllers, so for example as soon as I click on a tab bar button (+) in the first View, second view opens (PresentModalViewController) and it has a Text Field. So anything I type, I take it into a string(this string is an object of the first view) and I am trying to append that string to a tableview loaded in the first View.
Note: My string object is declared like this
View1.h
NSString *string
#property (copy) NSString *string;
View1.m
#synthesize string;
And in the View 2 I am passing the textField Value like this
View2.m
View1 *view1 = [[View1 alloc] initWithNibName:#"View1" bundle:nil];
view1.string = [[NSString alloc] initWithFormat:#"%#", TextField.text];
Problem - When I NSLog this value inside the View2, it grabs the value from the Text Field but in order for me to load the previous view, I need to dismiss this View2. So as soon as this View2 is dismissed when I try to access the same string object in my view 1. It says the string object is null.
Question - Could someone tell me
1. How to get the text Field value from view 2 to view 1 after dismissing View 2 (does it really makes all its objects null when dismissed?)
2. How to append that string to the last index of a NSMutableArray?
This is a very good question that I also had trouble figuring out when I started coding for the iOS. Basically, you don't need to initialize a new view1 because the tabbar controller already holds the view1 object in its viewControllers property. Also, alloc/init'ing the string in not necessary in this situation.
Therefore, you would want to change this:
View1 *view1 = [[View1 alloc] initWithNibName:#"View1" bundle:nil];
view1.string = [[NSString alloc] initWithFormat:#"%#", TextField.text];
To something like this:
View1 *view1 = [self.tabbarController.viewControllers objectAtIndex:0];
view1.string = textField.text;
Or even:
((View1 *)[self.tabbarController.viewControllers objectAtIndex:0]).string = textField.text;
Part 2:
How to append that string to the last index of a NSMutableArray?
NSMutableArray *someArray = [[NSMutableArray alloc] init];
[someArray addObject:string];
[someArray addObject:#"anotherString"];
The answer from #chown will definitely work if the ViewController you're sending the string to is the base controller of a tabBarController.
If you were several levels deep into a NavigationController stack, then you'll need a different approach.
The approach I'd recommend would be to create a protocol. This is where you create a delegate of view2 to pass the string back down the stack before the view is dismissed.
There are loads of examples of this code both in the Apple Documentation and on the Internet (StackOverflow included) but here's a quick run down...
In View2.h
#import <UIKit/UIKit.h>
//define the protocol, so you can set the delegate to this type
#protocol View2Delegate;
#interface View2 : UIViewController
//other properties etc
#property (assign) id <View2Delegate> delegate;
#end
//put the actual protocol definition here so we can pass a reference to ourself back up too if needed...
#protocol View2Delegate
- (void)view2:(View2*)view passingStringBack:(NSString *)stringToPassBack;
#end
In View2.m you can call that delegate method where ever you like but here's an example:
- (void)viewWillDisappear:(BOOL)animated
{
if(self.delegate)
[self.delegate view2:self passingStringBack:#"String I'm passing back"];
[super viewWillDisappear:animated];
}
Then in View1.h
#interface View2 : UIViewController <View2Delegate>
and View1.m
- (void)view2:(View2*)view passingStringBack:(NSString *)stringToPassBack
{
NSLog(#"%#", stringToPassBack);
}
Another option would be to post a notification, but that is more a broadcast scenario than a targeted message so I won't bother posting example code for that.
Obviously, I'm new to iOS development, but I could really use somebody's help. I am building a tab bar application in which I am attempting to load .plists into drill-down table views. The problem is that I can't seem to get this method right, as I am trying to use the navigation controller for a tab in its ViewController. I'm positive that my error is in the second line.
A37dgAppDelegate *AppDelegate = (A37dgAppDelegate *)[[UIApplication sharedApplication] delegate];
AppDelegate.indNavControl *indNavControl;
Subsequently, I get some errors. Here is the code, and I'll point out where the errors are:
if([Children count] == 0) {
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:[NSBundle mainBundle]];
[self.indNavControl pushViewController:dvController animated:YES];//Property "indNavControl" not found on object of type "IndustriesViewController"
[dvController release];
}
else {
//Prepare to tableview.
IndustriesViewController *indViewControl = [[IndustriesViewController alloc] initWithNibName:#"IndustryView" bundle:[NSBundle mainBundle]];
//Increment the Current View
indViewControl.CurrentLevel += 1;
//Set the title;
indViewControl.CurrentTitle = [dictionary objectForKey:#"Title"];
//Push the new table view on the stack
[self.indNavControl pushViewController:indViewControl animated:YES]; //Property "indNavControl" not found on object of type "IndustriesViewController"
indViewControl.tableDataSource = Children;
[indViewControl release];
}
}
Just to be clear, I have imported the header file of my App Delegate. Any help would be greatly appreciated :)
The line AppDelegate.indNavControl *indNavControl; is wrong. I think you don't need this line at all. And while pushing new view controller you can directly use AppDelegate.indNavControl instead of self.indNavControl,
[AppDelegate.indNavControl pushViewController:...
Your theory that the problem is in the second line is correct.
AppDelegate.indNavControl *indNavControl;
that line isn't really doing anything. You need a class where AppDelegate.indNavControl is.
You have a couple of options:
1) if you want indViewControl to be a 'public' property
* in your IndustriesViewController.h, move the declaration of indViewControl there.
#interface
{
WhateverClass *indNavControl;
}
#property (retain) WhateverClass*indNavControl;
#end
2) if you want a private property then add an empty category at the top of your .m with the ivar and property declaration from above.
What the compiler is complaining about is trying to access a property that doesn't exist.
calling self.whateverIvar requires an #property definition.
first create the instance of the appdelegate like and then you can access, whatever variables you have declared in appdelegate as property,synthesize.There is no need to create seperate variable of indNavControl.
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]
I have an iPhone app with a tableviewcontroller. When you click a certain cell it opens a new uiviewcontroller with this code:
nextViewController = [[avTouchViewController alloc] initWithNibName:#"avTouchViewController" bundle:nil];
The uiviewcontroller above called avTouchViewController has a property that looks like:
IBOutlet SomeObject *controller;
SomeObject is an object with all relevant view properties.
I would like to pass an nsstring parameter from the tableviewcontroller I initialize the avTouchViewController with to someObject.
How can I do this?
I'm a little confused by your question; you say you're creating your avTouchViewControllers when a cell is tapped inside an existing UITableView, but your last part describes the inverse situation.
Basically, if you want to pass information to a view controller, just give it a property that can be set (which may already be the case), e.g.:
nextViewController = [[avTouchViewController alloc] initWithNibName:#"avTouchViewController" bundle:nil];
nextViewController.controller = theInstanceOfSomeObjectIWantToPass;
You also may want to rename your controller property. To a reader, it doesn't make sense that a view controller has a property called controller which is actually a SomeObject*. As well, your class names should be capitalized, i.e. use AvTouchViewController instead of avTouchViewController.
If I were doing this I would add my own initializer to my UIViewController subclass:
- (id)initWithController:(NSString *pController) {
if (self = [super initWithNibName:#"avTouchViewController" bundle:nil]) {
self.controller = pController;
}
return self;
}
And then just call the following (in tableView:didSelectRowAtIndexPath: or whereever):
NSString *controller = #"Sample String";
AVTouchViewController *nextViewController = [[AVTouchViewController alloc] initWithController:controller];
[controller release];
[self.navigationController pushModalViewController:nextViewController animated:YES];
[nextViewController release];
As a point of style, class names conventionally begin with uppercase letters (hence my change to AVTouchViewController).