how can I display MSMutableArray data in UITableViewController? - iphone

I am getting data from NSTextField, and saving data in NSMutableArray. I want to show the same data in another class which in child of UITableViewController.
How can I show data of NSMutableArray to myTableView which is another class??
Help me out, please
Surely, I will appraise if I found proper way.

Your tableView is in a MyViewController class. You need to create a NSMutableArray *sourceArray attribute on that class, as well as the associated property, using for instance:
#property (nonatomic, retain) NSMutableArray *sourceArray;
Then when you instantiate this View Controller or whenever you make it appear, assign the results to sourceArray :
MyViewController *mvc = [[MyViewController alloc] initWith...];
mvc.sourceArray = theResult;
[self presentModalViewController:mvc animated:YES];
[mvc release];
Then use the sourceArray as the Table View datasource.

Make a property of NSMutableArray in app delegate class and assign the result of the source array to it as soon as you fetch any result, because you can access its instance all over your project.

Related

How many ways to pass/share data b/w view controller

im new to IOS and Objective-C and the whole MVC paradigm and i'm stuck with the following.
I am working on (replica) Contact app, also available in iphone as build in app. i want to pass data through another view controller and the data is pass (null) :(.
My Question is, How do I transfer the data from one view to another?
As most the answers you got, passing data between one controller and another just means to assign a variable from one controller to the other one.
If you have one controller to list your contacts and another one to show a contact details and the flow is starting from the list and going to detail after selecting a contact, you may assign the contact variable (may be an object from the array that is displayed in your list) and assign it to the detail view controller just before showing this one.
- (void)goToDetailViewControllerForContact:(Contact *)c
{
ContactDetailViewController *detailVC = [[[ContactDetailViewController alloc] init] autorelease];
detailVC.contact = c;
[self.navigationController pushViewController:c animated:YES];
//[self presentModalViewController:detailVC animated:YES]; //in case you don't have a navigation controller
}
On the other hand, if you want to insert a new contact from the detail controller to the list controller, I guess the best approach would be to assign the list controller as a delegate to the detail one, so when a contact is added the delegate is notified and act as expected (insert the contact to the array and reload the table view?).
#protocol ContactDelegate <NSObject>
- (void)contactWasCreated:(Contact *)c;
// - (void)contactWasDeleted:(Contact *)c; //may be useful too...
#end
#interface ContactListViewController : UIViewController <ContactDelegate>
#property (nonatomic, retain) NSArray *contacts;
...
#end
#implementation ContactListViewController
#synthesize contacts;
...
- (void)goToDetailViewControllerForContact:(Contact *)c
{
ContactDetailViewController *detailVC = [[[ContactDetailViewController alloc] init] autorelease];
detailVC.contact = c;
detailVC.delegate = self;
[self.navigationController pushViewController:c animated:YES];
//[self presentModalViewController:detailVC animated:YES]; //in case you don't have a navigation controller
}
- (void)contactWasCreated:(Contact *)c
{
self.contacts = [self.contacts arrayByAddingObject:c]; //I'm not sure this is the correct method signature...
[self reloadContacts]; //may be [self.tableView reloadData];
}
...
#end
#interface ContactDetailViewController : UIViewController
#property (nonatomic, assign) id<ContactDelegate> delegate;
...
#end
#implementation ContactDetailViewController
#synthesize delegate; //remember to don't release it on dealloc as it is an assigned property
...
- (void)createContactAction
{
Contact *c = [[[Contact alloc] init] autorelease];
[c configure];
[self.delegate contactWasCreated:c];
}
...
#end
Technically, you shouldn't!
The whole idea is not for "views" to control what happens to the data.
What you want to do is to pass data between controllers (which I imagine is exactly what you are planning to do anyway).
You can have shared model (an instance of an object that both view controllers would access) keeping the data you want to share,
You can use notifications to pass data (it is best suited for certain cases).
You can write something to disk and read it again later.
You can use NSUserDefaults.
You can use KeyChain.
...
The best way is:
declare the appropriate #property in the second view controller
when you create it, simply set the property with
viewController.property = valueYouWantToPass;
I'm a big fan of delegates and protocols.
And in some occasions use a Singleton pattern.
two ways to pass/share data between view controller
create an object and sent the data like this
QGraduteYr *tableverify=[[QGraduteYr alloc]initWithStyle:UITableViewStyleGrouped];
tableverify.mystring=myString
[self.navigationController pushViewController:tableverify animated:YES];
another method is stor it in the delegates and use it via shared delegates
MedicalAppDelegate *appdelegate=(MedicalAppDelegate *)[[UIApplication sharedApplication]delegate];
appdelegate.collnameStr=collStr;
and ust this appdelegates value whereever you need

pass data from mainView to a subview

I am building a utility-based application, the data is stored in the MainViewController, and now I know how to pass data to the FlipsideViewController (many regards to this thread BTW, Sending data from Mainview to Flipside?). But I am getting the data onto an subview (subclass of UIView) that I have added to the flipside view. How can I pass data to this subview? I saw there is already a delegate and protocol set up in the FlipsideViewController.h, I am really new to the delegate sort of things. Any help would be greatly appreciated!
Updates:
On the main view, I have a couple of text fields for users to input to create an object. All the objects are stored in an array. Namely, my data is created and stored in the MainViewController. Now on the flip side, I have a custom UIView subclass which allows me to do my own drawing based on the data in that array. What I need to do here is pass the data that stored in MainViewController to this subview. Here is my relevant code:
In the MainViewController.m
- (IBAction)showInfo:(id)sender {
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.delegate = self;
controller.receiver = data;//this is what I've done.
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
In the FlipsideViewController.h
#protocol FlipsideViewControllerDelegate;
#interface FlipsideViewController : UIViewController {
id <FlipsideViewControllerDelegate> delegate;
DataModel *receiver; //create a property to receive the data transferred from main view
}
#property (nonatomic, assign) id <FlipsideViewControllerDelegate> delegate;
#property (nonatomic, retain) DataModel *receiver;
- (IBAction)done:(id)sender;
#end
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
#end
In the above code, "data" is an DataModel object declared in the MainViewController.h file.
And I want to do my custom drawing in drawing class (subclass of UIView), how can I pass data from the FlipsideViewControllerto this subview? Do I need to make use of delegate declared in the FlipsideViewController.h file? Thanks in advance!
I have had a quick look at the template and think you are getting confused with what the delegate is being used for.
The delegate in this template is not transferring data. When you have clicked the done button it calls back to MainViewController and asks it to call the dismissModalViewControllerAnimated method so that it can remove the view controller. This seems a bit superflous as the documentation states
If you call this method on the modal view controller itself, however, the modal view controller automatically forwards the message to its parent view controller.
Therefore you don't really need to call the parent to do this.
In Interface builder you can see that the FlipsideView.xib has it's File's Owner set to FlipsideViewController.xib.
Now if you right click the File's Owner you will see that view is connected to View this basically means that view is the name of the property in FlipsideViewController and View is the element in Interface Builder.
Therefore we can access elements in the xib file from FlipsideViewController using outlets.
To say draw a label you will need to do a couple of things
First add a property in the .h and synthesize it in the .m like
// FlipsideViewController.h
#interface FlipsideViewController : UIViewController
#property (nonatomic, retain) IBOutlet UILabel *testLabel; // <----- Added this
#property (nonatomic, assign) id <FlipsideViewControllerDelegate> delegate;
- (IBAction)done:(id)sender;
#end
// FlipsideViewController.m
#implementation FlipsideViewController
#synthesize delegate = _delegate;
#synthesize testLabel = _testLabel; // <----- Added this
// More methods
- (void)dealloc
{
[_testLabel release]; // Always do you memory management
[super dealloc];
}
Then back in Interface Builder
Add a UILabel element to your view
ctrl + drag from File's Owner to the UILabel you added
Select the label in my example it is testLabel
Now these are hooked up correctly. The place where you want to be setting the value of the label is in viewDidLoad: which you can now do like this
- (void)viewDidLoad
{
[super viewDidLoad];
self.testLabel.text = #"It Works"; // You would use the data passed in from `MainViewController`
}
I find the easiest way to pass data from one view to another is by directly setting the data in the next view from the original view.
For example;
In your FlipsideViewController.h, declare a 'container' for the data you want to pass. It must be the same class on both sides to work properly, ie. NSArray to NSArray, NSMutableDictionary to NSMutableDictionary.
NSMutableArray *newData;
...
#property (nonatomic, retain) NSMutableArray *newData; // This allows you to access this object from outside this class.
and in FlipsideViewController.m
#synthesize newData;
...
[newData release];
Now we need to pass the data, so to speak. Let's say the data we want to 'send' is stored in a NSMutableArray called 'results'.
In our MainViewController.m, when we are instantiating our next view controller (in this case FlipsideViewController) we can directly reference the newData mutable array after we initalize the nib.
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.newData = results;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
Make sure you are importing your FlipsideViewController in your MainViewController.h file.
If the property is declared in your .h file, you can pretty much reference the contents of the object from anywhere within the view stack!
Hope that helps :D

Accessing NSMutableArray in an object from different object

How can I get access to a NSMutableArray that has been hydrated in different Class?
There is my sample code:
Class1.h : I have an iVar NSMutableArray *anArray;
And I #synthesize anArray; it in Class1.m
In the RootViewController I import the Class1.h and addd #Class "Class1";
The in the interface I add the Class1 *aClass1; in the RootViewController.m I #synthesize it and in the ViewWillAppear
aClass1 = [[Class1 alloc] init];
aClass1.anArray = [[NSMutableArray alloc] initWithObjects: #"string1",#"string2",nil];
NSLog(#"aClass1.anArray is Class1 %#",aClass1.anArray); // It works as I expected
Now in the new class I call it DetailsViewController
Same as the RootViewController.h I imported the .h and #class "Class1";.
Also in the DetailsViewController.m I have imported the "Class1.h"
So now in the DetailsViewController I try to do this in the viewWillAppear
NSLog(#"aClass1.anArray in DetailsViewController %#",aClass1.anArray); // PROBLEM: It comes back as null
I have added this sample project in this address: http://www.epicdesign.com.au/test2.zip
You just forgot to set the aClass1 ivar of the details view controller before you pushed it onto the navigation controller. Here is the code that should be in your didSelectRowAtIndexPath method:
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
// ...
// Pass the selected object to the new view controller.
detailViewController.aClass1 = aClass1; // this line was added
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
Once you add the line that I added above, your array will now show up correctly in the detail view controller.
You're accessing a property that you haven't declared yet in the Class1.h, so you must add there:
#property (nonatomic, copy) NSMutableArray *anArray;
Since it should work, I prefer not to pass any NSMutableArray as parameter. You should better declare a NSArray property in Class1.h to pass it to your methods and then mutableCopy it where you want to make modifications to the array (only inside the methods). And remember that mutableCopy and copy increase the retain count of your array, so you must release it when you are done.

The right way to hand over an object to a view?

i'm a bit new to iphone development. I made it to develop a nice App which loads XML Data from a feed, displays this data in a UITableView and if a user taps a row there should be a detail view which displays the data.
Thats where i got stuck a little bit. It's not clear for me how to hand over the data of the entry selected by the user to my detail view. The Detail-View is called via presentModalView...
I thought about:
Calling a "setDetails:(PostingData *)myPosting" function of the viewController of my detail view.
presenting the detailView to the user by calling presentModalViewAnimated.
The view is presented, but the setDetails: function crashes without any output to the debugger console.
MY QUESTION:
What is the right way to hand over Data (in custom objects as instance of a self written class) from my view Controller to a View Controller which should display detail data.
Any hint or help is appreciated. I can't pay you for your help, but i'm on my way becoming better and then helping others too :-).
Method 1: Pass it in custom init method
In your Header File declare a property
#property (nonatomic, retain) id myDataObject;
And in your implementation use a custom init like this
-(id)initCustom:(id)myObject;
if(self = [super init]) {
myDataObject = [myObject retain];
}
return self;
}
Method 2: Use a property
Use #property in your Header
and #synthesize in your .m Implementation File
[CustomUIViewController* newViewController = [[CustomUIViewControlleralloc] init];
newViewConroller.myDataObject = myObject;
[view addSubview:newViewController.view];
[newViewController release];
define the custom object in your class. #property(nonatomic, retain) MyClass * myClass;
load the feed into a NSMutableDictionary and provide that to your class
[YOUR_VIEW_CONTROLLER *yourViewController = [[YOUR_VIEW_CONTROLLER alloc] init];
yourViewController.PROPERTY_DEFINED_BEFORE = yourObject;
[view addSubview:yourViewController.view];
[yourViewController release];
cheers

NSMutableArray Vs UIView iphone

I have an NSMutableArray in my MainViewController classes.. I added 10 Objects to NSMutableArray.When i Click subview button in my MainViewController classes, I push SubviewController (UIViewController)classes.... In subviewcontroller classes i want to use MainViewController Values of NSMutableArray. And also i Want to add or remove objects from that NSMutableArray...
My aim is I want to use the NSMutableArray Values to all UIViewController classes to my project with an same name of the variable.
If I understand you right - you want to access the NSMutableArray in MainViewController from all your (subview) controllers?
You can store the handle to your MainViewController in all you subviews and access the array using that handle.
I think better idea would be move the data to some globally accessible instance (e.g. to ApplicationDelegate class or wrap it into singleton class)
What you want to do is add a Cocoa property in your main view controller that references the NSMutableArray instance which you instantiate and populate with elements.
In the header:
#interface MainViewController : UIViewController {
NSMutableArray *myMutableArray;
}
#property (nonatomic, retain) NSMutableArray *myMutableArray;
#end
In the implementation, add the #synthesize directive and remember to release the array in -dealloc:
#implementation MainViewController
#synthesize myMutableArray;
...
- (void) dealloc {
[myMutableArray release];
[super dealloc];
}
#end
You also want to add this property to view controllers that are subordinate to the main view controller, in the exact same way.
In your main view controller, when you are ready to push the subordinate view controller, you set the subordinate view controller's property accordingly:
- (void) pushSubordinateViewController {
SubordinateViewController *subVC = [[SubordinateViewController alloc] initWithNibName:#"SubordinateViewController" bundle:nil];
subVC.myMutableArray = self.myMutableArray; // this sets the sub view controller's mutable array property
[self.navigationController pushViewController:subVC animated:YES];
[subVC release];
}
Likewise in your subordinate view controller, it will need to set its subordinate's mutable array property accordingly, when it pushes its own view controller.
By setting references in this way, each view controller is pointed at the same mutable array, containing the desired elements.
To use the array, just call self.myMutableArray, e.g. [self.myMutableArray addObject:object].