Passing data from parent ViewController to child UITableViewController via Object - ios

I have a couple of delegates that work in my code already (not asking how to use them). I'm having a problem getting data from the parent ViewController (More Information in the storyboard belongs to class InputViewController) to the child TableViewController (AddressTableViewController) as I'm unable to reference the parent controller from this class.
Both TableViewControllers and the map are in InputViewController. I want to send data (the reverse-geolocated address from locationManager) from the map to AddressTableViewController to fill in the cell text. The TableViewControllers are tied to the InputViewController (main controller) via an Object (selected in the object library).
Code: https://gist.github.com/damionjn/c148a07a39b5c27e7f78
You'll see I'm trying to use the protocol at the bottom of InputViewController here:
https://gist.github.com/damionjn/c148a07a39b5c27e7f78#file-gistfile1-swift-L125
But I'm unable to use it as I have no access to InputViewController, thus mapAddressDataSource is always nil. I've tried creating an instance of it in AddressTableViewController's init() and creating an IBOutlet without any luck.

I'm having a problem getting data from the parent ViewController (More Information in the storyboard belongs to class InputViewController) to the child TableViewController (AddressTableViewController) as I'm unable to reference the parent controller from this class.
Why not?
Create a property on AddressTableViewController for your InputViewController but create it as weak and you can access it without causing any problems (retain cycles).
e.g.
#property (weak, nonatomic) InputViewController *parentInputViewcontroller;
Then you should be able to access any of the data on self.parentInputViewController from within your tableView subclass.

Related

How to access programmatically a tableview added with storyboard

I added a tableview to my viewcontroller using the storyboard. What is actually happening behind the scenes? If a UITableview object gets created how can I access this object programmatically? What is the name of the instance? Is it a property of my viewcontroller object?
More specifically, what I need to do is force my tableview to refresh (from inside of my viewcontroller). I read in other posts that I should be able to do something like this [self.tableview reloadData]. I can't do this because my viewcontroller does not have a property called "tableview" (or anything similar)
Control + click and drag your tableView into your header file to create an IBOutlet
Set the delegate and data source by control click and drag from your table view to your view controller - make sure both dots are seen. Now
In the interface .h file add the delegate and datasource as such:
#interface HomeTableViewController : UIViewController
<UITableViewDataSource, UITableViewDelegate>
Now your view controller should have access to the methods needed to use [self.tableView reloadData]
try this simple table view
and this work with custom tableview cell
try above tutorials and in your case to use [self.yourtablviewname reload]
you have to create an outlet of your table view and use it.
Remember that the storyboard defines a collection of objects which are created when you make an instance of say, a ViewController.
You are on the right track, you need to define variables in your view controller which are references to the objects in the storyboard. You mark them as IBOutlet in your code. You then 'connect' them to the objects in the storyboard. Right click on the viewcontroller in the storyboard and you will see the variables which have been designated as IBOutlet listed as 'outlets'. You can drag from the popup table to the objects in the storyboard to connect them. Now, when an ViewController is created, all the IBOutlet variables are set to point to the various objects (tables, text views etc) in the instance just created.
Remember that the 'connect' you do with the Interface Builder, happens at rum time when you create an instance of the object in IB.

iOS - Swapping View Controller's in a Container View and persisting the data

I have a container view that swaps to child view controllers. Upon swapping the view controllers though I lose the data the controller had when it is deallocated from memory.
How can I swap the child view controllers and keep the data the same way that a tab bar controller swaps them without losing deallocating data from memory?
You should have an outer (root) ViewController which persists, and which owns the containerView and the cycling child viewControllers.
So ideally this rootViewController (or some other object which outlives the individual child viewControllers eg appDelegate) would own the strong reference to the model, and the childViewControllers are only given a weak pointer to that model for their life cycle. It will be easier if these childViewControllers all inherit from some abstract superclass which has a weak property to point to this model object, so the rootViewController can just treat all the children as an instance of that superclass.
Edit/additional info....
make a new subclass of NSObject with properties for all of this data that you want to persist. Call it SomethingModel Now remove the variables/properties for this data from the childrenViewControllers and give them a #property (weak, nonatomic) SomethingModel *modelObject (Put this in a subclass on UIViewController, and then make your childrenViewControllers all subclasses of that... Give your outer(root) ViewController a similar property, but make its one strong rather than weak. Then when you create a new childController you need only set its modelObject property and you're done :)

How to write to child view controller's outlet from super view controller

My application includes very similar album pages that draw pictures from web server. Every page has an album title and a table to show pictures. Only difference between pages is http request parameters.
I collected common behaviours (and data) into a super class "CommonViewController" and then I created child classes (FoodsViewController, BeveragesViewController) inherited from CommonViewController. I'll call child view controllers using their "story board id" from menu and then pass http request parameters to super class CommonViewController.
I placed child view controllers to story board and created outlets to labels and table views for each child view controller using mouse (cntrl+left click).
Child view controllers fill their request parameters to a struct that is defined in CommonViewController then it fetches the pictures from server.
The outlets is located in child view controllers but data is producing in super class.
CommonViewController doesn't know that which outlet will be written. How could I write data to outlets which is located in child view controllers from super class?
Once you have collected your data in CommonViewController call a method such as [self processData:receivedData]; where receivedData is the structure you want to process in the child - I will just use an NSData instance for this example.
You can simulate an abstract method by having the following in your commonViewController implementation of processData:
CommonViewController.m:
-(void) processData:(NSData *)receivedData
{
NSAssert(NO,#"Override processData in your subclass");
}
Then in each of your subclasses, override the method to perform whatever is required:
FoodsViewController.m:
-(void) processData:(NSData *)receivedData
{
//TODO put the data into the right controls
}
Update
If the mapping of data to the visual controls is the same (i.e. there is always a "title Label" and a "item picture" for example, but their placement on the screen changes, then you can define the control properties in your superclass.h -
#property (weak,nonatomic) IBOutlet UILabel *titleLabel;
#property (weak,nonatomic) IBOutlet UIImageView *itemPicture;
Then when you create use a subclass as your UIViewController in InterfaceBuilder you can just drag the connection from the control to the IBOutlet. If you are creating your controls programatically rather than in IB, then you can just assign them to the property in the subclass -
[self.view addSubView:myTitleLabel];
self.titleLabel=myTitleLabel;
In this case you can omit the IBOutlet

Passing a variable from modal tableview to parent view

I have a detailView which has a button on it to bring up a tableView as a modal view to help the user giving a selection of names. I'm trying to figure out a simple way of passing the selected name to a textField on the parent detailView.
I have been building this project using Storyboard, but I am totally stuck at this point.
There are several ways to approach this kind of problem:
shared object: The parent view controller provides some object to the child that contains the state that the child is expected to work with and possibly modify. In this case, it might be a dictionary that contains an array of names to display and the index of the selected person.
child's properties: Often, the child view controller itself is the shared object. The parent instantiates the child, sets some of the child's properties (e.g. people and selectedPerson), and presents it. When the child is finished, the parent gets the properties of the child that it cares about (e.g. selectedPerson) before releasing it.
delegation: Sometimes the child view controller will need to interact with the parent in order to do its job. This is a good time to use delegation: establish some protocol that the child knows about and the parent implements, add a delegate property to the child, and have the parent set the child's delegate property to itself before presenting it. This way, the child can talk to the parent without depending on the parent class.
For the case you describe, where you just want to convey some piece of data back to the parent when the child is done, the second strategy above is the simplest.
Note: DetailViewController below should be replaced with whatever the class is of your detail view controller.
1) If you don't already have a subclass of UITableViewController, create one. This will allow you to add a property to the table view controller. Change the class of your modally presented controller in your Storyboard to this new subclass.
2) Add a property to your table view controller subclass like this:
#property (weak, nonatomic) id mydelegate;
3) In prepareForSegue in your DetailViewController, set the mydelegate property of the destination view controller to self which is a pointer to your parent detailView.
4) In your DetailViewController, create a method to receive the selected name:
- (void)userDidSelectName:(NSString *)name;
5) In the tableView:didSelectRowAtIndexPath method of your tableViewController subclass, get the name from the tableViewCell and call the userDidSelectName method on the delegate:
[self.mydelegate userDidSelectName:selectedName];
6) The correct way to to this would be to define a protocol that has a method userDidSelectName and then make the delegate pointer in step 2 require a class that implements that protocol. The quicker and dirtier thing to do is to make the delegate pointer in step 2 of type DetailViewController * instead of id. This will allow you to call userDidSelectName without the compiler complaining.

Unable to link UIViewController IBOutlets with StoryBoard

I have two UIViewControllers (A and B) in storyboard. The A view controller has a property
#property (nonatomic, retain) IBOutlet UIViewController *viewController;
that I want to link via storyboard to B.
The outlet shows under the the IBOutlets section in storyboard menu but I'm unable to link.
It might seem strange why I'm trying to do that but I need it. Someone knows how to do that?
IBOutlets are connections within a single view controller. Create references to objects inside the view controller so you can use those objects in code.
You cannot create IBOutlets from one view controller to another one. A property is the correct way to go, but you have to assign the property in code. Normally when one view controller creates another one, it might set a reference to itself.
OtherViewController *otherViewController = [OtherViewController alloc] init];
otherViewController.masterViewController = self;
// at this point "otherViewController" has a reference to the current view controller
Now I understand what I need to do. I need to create a custom segue to achieve the same result as when you link a UINavigationController to other ViewController and mark as RootViewController. It is done by segue and not by IBOutlet.
I am a bit late to the party however I put together a segue class to help with this job. View the git repository to see the class in action: https://github.com/datinc/DATOutletSegue.
Basically it uses the identifier of the segue to connect to the parent controller

Resources