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.
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 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];
I have a RootViewController that calls an AddQuoteViewController and there is a variable "subject_id" that I set in the RootViewController that does not show up in AddQuoteViewController and I need help understanding why and how to fix it.
Subject *sub = [self.tableDataSource objectAtIndex:indexPath.row];
self.subject_id = sub.subject_id;
[self addQuote_Clicked: sub];
...
- (void) addQuote_Clicked:(id)sender {
if(aqvController == nil)
aqvController = [[AddQuoteViewController alloc] initWithNibName:#"AddQuoteView" bundle:nil];
if(addNavigationController == nil)
addNavigationController = [[UINavigationController alloc] initWithRootViewController:aqvController];
[self.navigationController presentModalViewController:addNavigationController animated:YES];
}
Then in my AddQuoteViewController I try to access this variable like this:
RootViewController *rv = [RootViewController alloc] ;
NSLog(#"rv.Subject_id = %d", rv.subject_id);
But get nothing. There must be a simple way to do this.
First of all, there's an error in your third block of code. This:
RootViewController *rv = [RootViewController alloc] ;
Should be this:
RootViewController *rv = [[RootViewController alloc]init];
But strictly speaking that's not why you aren't seeing your instance variable.
If I understand correctly, the first two blocks of code are in RootViewController, and they instantiate an AddQuoteViewController and present it. Then, from your third block of code, which is in AddQuoteViewController, you want to access a member variable (subject_id) of the RootViewController that brought it up.
The approach of instantiating a RootViewController from within the AddQuoteViewController wouldn't work, because you're creating a different instance of RootViewController. What you're after is the value in the instance you just came from.
Perhaps the easiest way to do it is to create a corresponding property on AddQuoteViewController and set it when it's created:
- (void) addQuote_Clicked:(id)sender {
if(aqvController == nil)
aqvController = [[AddQuoteViewController alloc] initWithNibName:#"AddQuoteView" bundle:nil];
if(addNavigationController == nil)
addNavigationController = [[UINavigationController alloc] initWithRootViewController:aqvController];
aqvController.subject_id = self.subject_id;
[self.navigationController presentModalViewController:addNavigationController animated:YES];
}
You'll need to create the subject_id property on AddQuoteViewController the same way you did on RootViewController.
There are various ways of doing this, but a short answer - You can set a reference to the RootViewController as a property on your AddQuoteViewController
i.e.
in AddQuoteViewController.h
RootViewController *rvc
...
#property (nonatomic,assign) RootViewController *rvc;
and corresponding synthesize and release in your implementation class. (AddQuoteViewController.m)
Then when you create your AddQuoteViewController inside your RootViewController, also set this property:
- (void) addQuote_Clicked:(id)sender {
if(aqvController == nil)
aqvController = [[AddQuoteViewController alloc] initWithNibName:#"AddQuoteView" bundle:nil];
aqvController.rvc = self;
... etc.
Then you can access any property of the root view controller inside your AddQuoteViewController via this property:
NSLog(#"rv.Subject_id = %d", self.rv.subject_id);
As a side note there are a few things you are doing in your question that are a bit unusual, like trying to get a reference to an object by allocating a new one, and also creating a new navigation controller and presenting it as a modal view controller typically you would do one or the other (and wouldn't need to create a new navigation controller). i.e. you would either create a view controller and present it modally, or you would create a view controller and push it onto your current navigation controller stack.
You can't access variables across view controllers like that.
Have a look at creating a singleton class which will be globally accessible.
One exception I think is you can access them in the AppDelegate, but it's not advisable to have global vars.
I am a new programmer of Iphone Application. I work dynamically not use nib files.
I want to pass values from one view controller to another.
in firstView.m
these two values
cell.textLabel.text
cell.detailTextLabel.text
i want to pass in the TabBarSearchThirdView init method..
TabBarSearchThirdView *thirdView=[[TabBarSearchThirdView alloc]init];
[myView addSubview:thirdView.view];
in TabBarSearchThirdView.m file.
-(id)init
{
firstVariable=..........
secondVariable=..........
}
Hope you understood my question. Give me little code or suggestions if possible
and give me a link of easy and good table view tutorial. If possible
Thanks in advance
You should declare a new init method like this one
- (id)initWithText:(NSString *)aText andDetail:(NSString *)aDetail{
self = [super init];
if(self){
firstVariable = aText;
secondVariable = aDetail;
}
return self;
}
For passing data between viewcontrollers my answer at the below link will help.
How to pass a tableview cell value to another page(uiviewcontroller)?
for passing values from 1 controller to another controller, you have to define 2 variables in AppDelegate class, with property and synthesis . example NSstring *firstVariable and NSString *secondVariable and mention its property and synthesis.
and after your code
TabBarSearchThirdView *thirdView=[[TabBarSearchThirdView alloc]init];
MyAppnameDelegate AppDel = (MyAppnameAppDelegate*)[[UIApplication sharedApplication]delegate];
//MyAppnameDelegate is your appdelegete class, so change it by your appDelegate class
AppDel.firstVariable =cell.textLabel.text;
AppDel. secondVariable = cell.detailTextLabel.text;
[myView addSubview:thirdView.view];
process to access values in Third class is
In viewDidLoad{
MyAppnameDelegate AppDel = (MyAppnameAppDelegate*)[[UIApplication sharedApplication]delegate];
//MyAppnameDelegate is your appdelegete class, so change it by your appDelegate class
nsstring *accessfirstVariable =.AppDel.firstVariable
nsstring *accesssecondVariable =AppDel. secondVariable
}
and use this where ever u likeā¦ cheers
I'm new to iOS development and have a question regarding variables. I'm attempting to write an application with a tab bar and navigation controller, the tab bar being the rootViewController. I've set up my application to include a .plist that includes my table view's behaviors, a UITableViewController, and a detail view controller. I continue to get one error in the implementation file of my initial table view controller as I defined the navigation controller in my App delegate.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//Get the dictionary of the selected data source.
NSDictionary *dictionary = [self.tableDataSource objectAtIndex:indexPath.row];
//Get the children of the present item.
NSArray *Children = [dictionary objectForKey:#"Children"];
if([Children count] == 0) {
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:dvController animated:YES];
[dvController release];
}
else {
//Prepare to tableview.
IndustryTableViewController *industryTableViewController = [[IndustryTableViewController alloc] initWithNibName:#"IndustryTableViewController" bundle:[NSBundle mainBundle]];
//Increment the Current View
industryTableViewController.CurrentLevel += 1;
//Set the title;
industryTableViewController.CurrentTitle = [dictionary objectForKey:#"Title"];
//Push the new table view on the stack
[self.indNavControl pushViewController:industryTableViewController animated:YES];
industryTableViewController.tableDataSource = Children;
[industryTableViewController release];
}
}
I get the error when I push the new table view on the stack. I am importing the header file of my app delegate, but it still will not work, giving me the error, "Variable not defined in TableViewController.h". Is there a way for me to summon this variable, or is there a more effective way for me to solve this issue?
Thanks in advance, I can really use any help you give me.
You can get a pointer to your appDelegate and then get your variable like so:
YourAppDelegate *appDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
Another way would be to use dependency injection and inject the reference into your controller when you create it. So basically define an ivar in your controller to hold a reference and then do this:
[myController new];
[myController setController:otherController];
You are referring to navigationController with self.navigationController.
This implies that navigationController is a variable defined in your TableViewController class.
You should define this variable in your class and modify your init method of the tableviewcontroller to receive that variable.