Accessing variables from another ViewController - iphone

FirstViewController.h:
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController
{
NSArray *listData;
}
-(IBAction) GoToInsert: (id) sender;
#property (nonatomic, retain) NSArray *listData;
#end
FirstViewController.m:
-(IBAction) upisiRezultat:(id)sender
{
SecondViewController *secondView = [[SecondViewController alloc] initWithNibName: nil bundle: nil];
[self presentModalViewController: secondView animated: NO];
[secondView release];
}
- (void)viewDidLoad
{NSArray *array = [[NSArray alloc] initWithObjects:#"236", #"46",
#"147", #"8", #"56", #"69", #"114", #"2",
#"96", #"518", #"2", #"54", #"236", nil];
self.listData = array;
[array release];
[super viewDidLoad];
}
SecondViewontroller.h
#interface SecondViewController : UIViewController {
}
-(IBAction) insert;
#end
SecondViewontroller.m
-(IBAction) insert
{
/* Here should be the code to insert some number in listData from FirstViewController */
}
So when the app loads it loads FirstViewController.xib and shows the listData array on screen, when I click button "Go to Insert" another view is loaded (SecondViewController.xib) with button "Insert" which should add some number into the array and display the new array on the first view.
How to do that?

You can access the parent view controller with self.parentViewController. Therefore something along these lines (meaning I haven't tested this -- you should) should work:
FirstViewController *firstViewController = self.parentViewController;
NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:firstViewControl.listData];
[newArray addObject:#"42"];
[firstViewController setListData:[NSArray arrayWithArray:newArray]];
[newArray release];
However, since you want to add objects to listArray, it would be more natural to use an NSMutableArray instead. Also, you are currently adding NSStrings to the array, when it looks more like you want to have NSNumber objects.

Alternately, and maybe easier, you could have the variables in your main AppDelegate.
Put:
int myNumber;
in the projectname_AppDelegate.h file
Then in each of your view controllers, you can import your AppDelegate.h file and then do something like:
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
and then read or change:
appDelegate.myNumber
===
This is not something you should be doing all the time (you don't want your appDelegate to be a giant data repository) but it could give you a quick fix when needed...

I do not know if you have imported the SecondViewController.h , and I think I have an idea an what you are trying to do.

Related

pass NSMutableArray to another view giving null values

I'm new to iOS development and I want to pass an NSMutableArray from one viewcontroller to another but always gives me null values
FirstViewController.h
#interface FirstViewController : UIViewController
#property (nonatomic, retain) NSMutableArray *colorArray;
-(IBAction)btn:(id)sender;
FirstViewController.m
#implementation FirstViewController
-(IBAction)btn:(id)sender
{
SecondViewController* secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
secondViewController.animalArray = self.colorArray;
NSLog(#"%#",secondViewController.animalArray); // here its not null
[self.navigationController pushViewController:secondViewController animated:YES];
}
SecondViewController.h
#interface SecondViewController : UIViewController
#property (nonatomic, retain) NSMutableArray *animalArray;
SecondViewController.m
I only used NSLog(#"animalArray:%#",self.animalArray); in viewDidLoad to check the values but gives me null
is there anything I'm missing?
Edit :
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"indidLoad%#",self.animalArray);
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(#"inwillAppear%#",self.animalArray);
}
Replace with following method
-(IBAction)btn:(id)sender{
SecondViewController* secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
secondViewController.animalArray=[[NSMutableArray alloc]initWithArray:self.colorArray];
[self.navigationController pushViewController:secondViewController animated:YES];
}
:) +1
If you call your NSLog from (void)viewWillAppear:(BOOL) animated, you should see something.
In your code example the viewDidLoad method is called straight after initWithNibName :
[[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
and before you have a chance to set your property.
**FirstViewController.h**
#interface FirstViewController : UIViewController
{
NSMutableArray *SongArray;
}
#property(nonatomic,retain)NSMutableArray *SongArray;
**FirstViewController.m**
SecondViewController *secondView = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
secondView.SongArray = self.SongArray;
[self.navigationController secondView animated:YES];
**SecondViewController.h**
#interface SecondViewController : UIViewController
{
NSMutableArray *SongArray;
}
#property(nonatomic,retain)NSMutableArray *SongArray;
Do it like this your values arent being retained. Please also check Pass NSMutableArray to one view controller to another
Check the value in viewWillAppear instead of viewDidLoad.
It should work
-(IBAction)btn:(id)sender
{
SecondViewController* secondViewController = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
NSLog(#"%#",secondViewController.animalArray); // here its not null
[self.navigationController pushViewController:secondViewController animated:YES];
secondViewController.animalArray = self.colorArray;
}
Sometimes if you pass value before pushing the the view it will give null value in second view
Better way is to create your NSMutableArray in Appdelegate file like below...
#property (nonatomic, retain) NSMutableArray *animalArray;//define this in Appdelegate.h file
synthesize it in Appdelegate.m file like
#synthesize animalArray;
Create Appdelegate object in prefix.pch file like below.
#define AppDel ((AppDelegate *)[UIApplication sharedApplication].delegate)
and import your Appdelegate file in prefix.pch like below..
#import "AppDelegate.h"
now where you want to use that array...just write like below..
AppDel.animalArray=//you can do whatever you want with array....
By doing this no need to pass array to other view controller, you can use that global array in whole project ,you can insert object in that array in any class and can access in any class.
Let me know it is working or not!!!
Happy coding!!!!

How to change MutableArray from other view?

In my Application,
There are two different views ItemList And ItemSearch.
In ItemList file I have one NsMutableArray with name tblItem. I want pass data in tblitem from the Itemsearch page.
How can I do this?
You can make use of properties as follows:
1.Create a property in ItemList.h of tblItem as,
#property(nonatomic, retain) NSMutableArray *tblItem;
then synthesize it in ItemList.m,
#synthesize tblItem;
When you are navigating from ItemSearch to ItemList ie when you are initializing ItemList just provide tblItem the required values as,
ItemListObj.tblItem = theSearchedArray;
Declare an NSMutableArray as property in the SecondViewController and assign the array at the time you are pushing or presenting the SecondViewController from the FirstViewController.
#interface SecondViewController : UIViewController
{
NSMutableArray *aryFromFirstViewController;
}
#property (nonatomic,retain) NSMutableArray *aryFromFirstViewController;
#end
At the implementation, synthesize the property
#implementation SecondViewController
#synthesize aryFromFirstViewController;
#end
At the header of the FirstViewController import the SecondViewController
#import "SecondViewController.h"
At implementation of the FirstViewController, add the code like below in where you wrote the code to present or push the SecondViewController
#implementation FirstViewController
- (void) functionForPushingTheSecondViewController
{
SecondViewController *objSecondViewController = [[SecondViewController alloc] initWithNIBName: #"SecondViewController" bundle: nil];
objSecondViewController.aryFromFirstViewController = self.myAryToPass;
[self.navigationController pushViewController:objSecondViewController animated: YES];
[objSecondViewController release];
}
#end
Please don't forget to release the aryFromFirstViewController at dealloc method of SecondViewController, otherwise it will leak because we retained it. I'l feel good if i come to know that this helped you in someways. Enjoy.
It depends on your need. You can use Singleton class for sharing of your variables between different classes. Define all variable which you wants share in your DataClass.
in .h file (where RootViewController is my DataClass, replace name with your new class)
+(RootViewController*)sharedFirstViewController;
in .m file
//make the class singleton:-
+(RootViewController*)sharedFirstViewController
{
#synchronized([RootViewController class])
{
if (!_sharedFirstViewController)
[[self alloc] init];
return _sharedFirstViewController;
}
return nil;
}
+(id)alloc
{
#synchronized([RootViewController class])
{
NSAssert(_sharedFirstViewController == nil,
#"Attempted to allocate a second instance of a singleton.");
_sharedFirstViewController = [super alloc];
return _sharedFirstViewController;
}
return nil;
}
-(id)init {
self = [super init];
if (self != nil) {
// initialize stuff here
}
return self;
}
after that you can use your variable in any other class like this
[RootViewController sharedFirstViewController].variable
Hope it's help you:)

Pass NSMutableArray to another view controller - not working

I have a view controller PlayerViewController, I am trying to pass a NSMutableArray: stories, to the view controller PlaylistViewController
in the PlayerViewController.h file I have
#class PlaylistViewController;
in the PlayerViewController.m file I have
//stories is a NSMutableArray that does have content in it
PlaylistViewController *sVC = [[PlaylistViewController alloc] initWithNibName:#"PlaylistViewController" bundle:nil];
sVC.playSongArray = [[NSMutableArray alloc]init];
sVC.playSongArray = stories;
in the PlaylistViewController.h file I have
NSMutableArray *playSongArray;
and
#property(nonatomic,retain)NSMutableArray *playSongArray;
I also synthesize it in the .m file
But when I run the code, playSongArray in PlaylistViewController is empty. What am I doing wrong?
How are you presenting this view? I've seen multiple times where I had to present the view before setting properties like this in order for them to be applied properly. It seems the the view is not full initialized until it is presented/displayed and part of the initialization process sets the properties to nil.
Assuming you are presenting this modally try the following order instead.
//stories is a NSMutableArray that does have content in it
PlaylistViewController *sVC = [[PlaylistViewController alloc] initWithNibName:#"PlaylistViewController" bundle:nil];
[self presentModalViewController:svc animated:YES]; // if modal
[self pushViewController:svc animated:YES]; // if part of a uinavigationcontroller
sVC.playSongArray = [[NSMutableArray alloc]init];
sVC.playSongArray = stories;
Instead of :
sVC.playSongArray = [[NSMutableArray alloc]init];
sVC.playSongArray = stories;
Try
sVC.playSongArray = [[NSMutableArray alloc]initWithArray:stories];
If it's not working, in your PlaylistViewController controller, add playSongArray = [[NSMutableArray alloc]init]; in initWithNibName function then create a function :
- (void)setPlaySongs:(NSArray *)songs {
[playSongArray addObjectsFromArray:songs];
}
and load your view controller this way :
PlaylistViewController *sVC = [[PlaylistViewController alloc] initWithNibName:#"PlaylistViewController" bundle:nil];
[sVC setPlaySongs:stories];
I suspect you are checking the value of playSongArray too early. Your PlaylistViewController should look like:
#interface PlaylistViewContror {
NSMutableArray *playSongArray;
}
- (id)initWithPlaySongArray:(NSMutableArray *)array;
#property(nonatomic,retain)NSMutableArray *playSongArray;
#end
#implementation PlaylistViewContror
#synthesize playSongArray;
- (id)initWithPlaySongArray:(NSMutableArray *)array
{
if (!(self = [super initWithNibName:#"PlaylistViewController" bundle:nil]))
return nil;
playSongArray = array;
return self;
}
- (void)awakeFromNib
{
// do things with playSongArray here
}
#end
And then in your PlayerViewController, you just do:
//stories is a NSMutableArray that does have content in it
PlaylistViewController *sVC = [[PlaylistViewController alloc] initWithPlaySongArray:stories];

UITableViewController does not refresh

I have a tabBar application. In the app delegate i create one NSMutableArray, one UITableViewController and one class (lets say class B) that updates the NSMutableArray.
The tabBar contains
a) The tableViewController which shows the data in the *booksArray
b) Class B which adds data to the booksArray
The tableView works great when it is first loaded. The problem is that when the array updates, not any changes are fired in the UItableViewContoller (when I choose its tab again). Do I have to use delegation? Do I have to change my architecture?
AppDelegate:
visibleBooks = [[NSMutableArray alloc] init];
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:booksTableViewController];
UITabBarController *tabBarController = [[UITabBarController alloc] init];
NSArray *viewControllers = [NSArray arrayWithObjects:navController,qrViewController, nil];
[tabBarController setViewControllers:viewControllers];
In the UITableViewController .h:
#class BookDetailedViewController;
#interface BooksTableViewController : UITableViewController {
NSMutableArray *bookSource;
}
#property (nonatomic,retain) NSMutableArray *bookSource; // IS RETAIN OK?
- (id) initWithDataSource: (NSMutableArray *) source;
#end
In the UITableViewController .m:
- (id) initWithDataSource: (NSMutableArray *) source
{
[super initWithStyle:UITableViewStyleGrouped];
[self setBookSource:source];
[[self navigationItem] setTitle:#"Books"];
return self;
}
You need to invoke [self.tableView reloadData] in UITableViewController each time when your data source is updated, or when you're showing your tableView.
This can be done in viewWillAppear: inside your BooksTableViewController, or in tabBar:didSelectItem: inside UITabBarController.
for example, add this code snippet to BooksTableViewController:
- (void) viewWillAppear:(BOOL) animated
{
[super viewWillAppear:animated];
[self.tableView reloadData];
}

How to assign managedObjectContext to a dynamic viewController?

I have 4 buttons on main screen, each one sends me to a viewController. The third one, sends me to a view on which I wanna set the managedObjectContext. If I use the class name to create an instance, it's all right. But I'm looking for a way to use just one method that uses an array to retrieve the name of the Class for the needed viewController. But it's leading to an error message, like it doesn't exist on the destination viewController??? Anyone have any ideas about this aproach??? Thanks in advance!
Here is the code:
NSArray *viewControllers = [[NSArray alloc]
initWithObjects:#"nil",#"OpcoesView",#"nil",#"TheNames", nil];
NSString *viewName = [viewControllers objectAtIndex:[sender tag]]; //the taped button tag
UIViewController *viewController = [[NSClassFromString(viewName) alloc]
initWithNibName:viewName bundle:nil];
if ([sender tag] == 3) {
viewController.managedObjectContext = contexto;
}
You do not need to know the subclass at all. Because Objective-C is a dynamic language and messages are resolved at runtime, you can send the message without having to know anything about the subclass at all.
First I would refer to the subclass as an id (instead of UIViewController) and as long as you have its header imported you can call [viewController setManagedObjectContext:contexto] directly.
However if you don't want to or can't import the header then just use KVC as follows:
[viewController setValue:contexto forKey:#"managedObjectContext"];
I would keep MOC in my app delegate instead of assigning it down to every of my viewControllers:
And in my viewController .m file:
#import "MyAppDelegate.h" // Assuming you have a property called managedObjectContext in your MyAppDelegate
#interface MyViewController (PrivateMethgods)
#property (nonatomic, readonly) NSManagedObjectContext * managedObjectContext;
#end
#implementation MyViewController
#dynamic managedObjectContext
- (NSManagedObjectContext *)managedObjectContext {
MyAppDelegate *appDelegate = (MyAppDelegate *)[UIApplication sharedApplication].delegate;
return appDelegate.managedObjectContext;
}
So I can use it in my viewController like this:
if ([self.managedObjectContext hasChanges]) {
...
}
To set a property that is only in the subclass view controller (such as "managedObjectContext"), you can take advantage of the fact that you know the type like this:
NSArray *viewControllerNames = [[NSArray alloc] initWithObjects:#"nil",#"OpcoesView",#"nil",#"TheNames", nil];
NSString *viewControllerName = [viewControllerNames objectAtIndex:[sender tag]]; //the tapped button tag
UIViewController *viewController = [[NSClassFromString(viewControllerName) alloc] initWithNibName:viewControllerName bundle:nil];
if ([sender tag] == 3) {
TheNames *namesVC = (TheNames*)viewController;
namesVC.managedObjectContext = contexto;
}