self.TableView not working for a TableViewController inside a ViewController? - objective-c

I am making a ViewController with 2 tableviews inside it. I am structuring it like
ViewController -> 2 x TableViewController classes. What I don't understand is that if I do [self.tableView reloadData] in the TableViewControllers it doesn't do anything.
If I do [tableViewA reloadData] in the ViewController it will execute the datasource methods in the TableViewController.
How do I call reloadData within the TableViewControllers?
Thanks,
Alan
Edit - This is how I setup the ViewController
if(self.reviewController == nil)
{
self.reviewController = [[ReviewerTableViewController alloc] init];
}
if(self.approverController == nil)
{
self.approverController = [[ApproverTableViewController alloc] init];
}
[self.reviewerTableView setDataSource:reviewController];
[self.approversTableView setDataSource:approverController];
[self.reviewerTableView setDelegate:reviewController];
[self.approversTableView setDelegate:approverController];
self.reviewController.view = self.reviewController.tableView;
self.approverController.view = self.approverController.tableView;
It seems like the datasource methods run once when I initialize them, but reloadData does not work inside.
I am basically just using the datasource methods in the UITableViewControllers and I am calling a method to pull data from the net. Once I get the data, I call reloadData, but the datasource methods are not executed.

Be sure the TableViewControllers' tableView properties are connected to the correct table views.

Are you calling reloadData from the rootViewController? if so, you call
[self.reviewerTableView reloadData];

I would create a UIVIewController that implements the UITableViewDataSource and UITableViewDelegate protocols. Create two outlets, one for each tableview and make sure to wire them up in the interface builder.
then call [tableView1 reloadData];

This seems very strange: you're trying to set the child UITableViewControllers' dataSource and delegates to be some local UITableViews declared (presumably) in your master view controller. It isn't supposed to work like this - the child UITableViewControllers are already the dataSource and delegate to their own implicit table views. There's no need to wired them up to separate UITableViews.
EDIT: I am assuming your "TableViewController" classes are UITableViewControllers. If not, then what you're doing may be valid, but I'd need to see all the code, headers included.

Related

How to make viewWillAppear to be called when we use a subclass of UITableViewController to handle table delegate?

I want to make my code more modular and flexible.
So rather than setting a the tableViewDelegate as the UIViewController, I have a subclass of UITableViewController as the tableView data source and delegate.
Basically, the original UIViewController provides the view for the subclass of UITableViewController.
That way similar tables can be used by several UIViewController's subclasses.
In some cases, UIViewController's provide the tableView and I just switch the tableView delegate at run time.
Works well.
Here is the code for BGTableViewDelegateMother that inherits from UITableViewController (that inherits from UIViewController.
#implementation BGTableViewDelegateMother
-(void) setDelegate:(id<BGTableViewDelegateMother>)delegate
{
_delegate=delegate;
self.view = self.delegate.tvDelegated; //So that viewWillAppear would work fine
[self view]; //load the view view didload is not called either
self.delegate.tvDelegated.delegate =self;
self.delegate.tvDelegated.dataSource=self;
}
Okay. The UITableViewController.view is used for one thing. Now that it points to the correct tableView, I expect viewWillAppear to be called. It's not
I think everytime the tableView will be shown, I should at least reloadData
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];//never called
[self.delegate.tvDelegated reloadData];
}
This code never called. Even though the view will indeed appear. Why?
viewDidLoad is also never called.
Make the table view controller a child view controller of your view controller while its view is linked (and it is the data source) and could be on screen. This tells the view controller hierarchy that the table view needs to know about the appearance callbacks.

Accessing an instance method of a ViewController From Another view controller

Let's say I have a view controller called vc1, which a synthesized property called property1, and i wants to access it from another view controller (vc2) and change it from vc2.
Now the methods created by the #syntisize to change and get properties are instance methods, so how can I get to them fro another view controller (do view controllers have instances in the app, and if so, what are they?)
Just to be clear I am using storyboards, so I never really instantiate the view controllers...
VC1.m:
-(void) yourMethod {
...
}
VC2.m
YOURViewController * vc2 = [[YOURViewController alloc]init];
[vc yourMethod];
[vc release];
Make sure to import your YOURViewController in your other view .m file
Something like that should work.
Or if you're having problems, try this tutorial here:
Tutorial on How-To Pass Data Between Two View Controllers
Hope this helps :)
While you can do it the way you describe, I think the common technique (assuming VC1 has a segue to VC2) is a bit different, where VC2 will have a property that will be set by prepareForSegue. See Configuring the Destination Controller When a Segue is Triggered in the View Controller Programming Guide.
You will need to link the storyboard views with the viewcontrollers so the view for vc1 would use the class vc1 etc for the rest (I assume you have done this because this is important when coding for different views)
Then all you need to do is where ever you are calling the properties so lets say the viewDidLoad method, declare the view controller like this:
- (void) viewDidLoad {
vc1 *viewController;
// Now you change the variable I'll presume its a UILabel so I'll change its text [viewController.property1 setText:#"I changed a different views UILabel"];
}
Let me know whether this works... Its worked for me before so should work

In storyboard, how to assign a view controller's subview a different delegate/controller m file?

In my storyboard, I have a view (a subclass of UIScrollView called AQGridView) which is nested inside a view controller scene. I want to assign the AQGridView a controller delegate and datasource which is defined in a separate .m and .h file than the parent view controller. How do I do this? Storyboard only lets me drag connectors to AQGridView's parent view controller.
EDIT:
I've tried doing something in the parent view controller like this (where myGrid is an IBOutlet pointing to the AQGridView and myGridController is a property of the parent view controller):
- (void)awakeFromNib
{
// note: kzMyGridController is a subclass of AQGridViewController
myGridController = [[kzMyGridController alloc] init];
myGrid.delegate = myGridController;
myGrid.dataSource = myGridController;
}
But it doesn't appear to be working because none of its delegate methods are being called. What am I doing wrong?
If you are not allowed on the StoryBoard, just do it on the code. It makes more sense, because it actually forces you to have an object (the delegate) and set it when you need it.
It should be:
- (void)awakeFromNib
{
// note: kzMyGridController is a subclass of AQGridViewController
myGridController = [[kzMyGridController alloc] init];
myGrid.delegate = myGridController;
myGrid.dataSource = myGridController;
}
The answer was that I had to call reloadData on the AQGridView. The view is created before its delegate, so its initial data getting methods fire without a receiver.

Overriding UITableViewController's cellForRowAtIndexPath in Objective-C

I have a view controller MainVC which contains a view where I want to switch between various tables. I have an "abstract" class called InfoVC which extends UITableViewController and contains several methods that must be overridden or else they throw an exception. Finally, I have several classes which extend InfoVC and implement the "abstract" methods in InfoVC, along with methods that override tableView's numberOfRowsInSection and cellForRowAtIndexPath.
This is how I load a table in MainVC. In this case, TemperatureInfoVC extends InfoVC, self.subVC is of type InfoVC, and switchView is a view in MainVC:
TemperatureInfoVC *sVC = [[TemperatureInfoVC alloc] initWithStyle:UITableViewStylePlain];
self.subVC = sVC;
[sVC release];
[switchView insertSubview:self.subVC.view atIndex:0];
My problem is that the table always loads empty. From setting breakpoints, I can see that TemperatureInfoVC's numberOfRowsInSection is being called, but neither TemperatureInfoVC's or InfoVC's cellForRowAtIndexPath are being called. However, if I change the first line in the code above to:
InfoVC *sVC = [[InfoVC alloc] initWithStyle:UITableViewStylePlain];
then InfoVC's numberOfRowsInSection and cellForRowAtIndexPath are called properly. Does anyone know why TemperatureInfoVC's cellForRowAtIndexPath is not being called?
I assume, that you are not setting the delegate (UITableViewDelegate) and the datasource (UITableViewDatasource). Usually the delegate and the datasource implementation are with-in the custom UITableViewController, so (if not wiring up in IB), there need to be this somewhere:
tableView.delegate = self;
tableView.dataSource = self;
often within the -loadView or -viewDidLoad:
Oops, figured it out. I was loading data from an NSMutableArray in TemperatureInfoVC which was set in MainVC, but I was setting the data before I initialized subVC, so of course the table had no data in it.

Subclassing in objective c and viewWillAppear message delegates?

I might be confused here and asking the wrong question.
If I use a class like the UISplitViewController inside the appdelete.m, will the only message i will receive is the message the UISplitViewController calls and not any VIEW message? for example:
in my myappdelegate.m
....
UISplitViewController *mySplitViewController = [[UISplitViewController alloc] init];
mySplitViewController.viewControllers = [NSArray arrayWithObjects:leftside,rightside,nil];
...
mySplitViewController.delegate = self;
....
[windows addSubView:mySplitViewController.view];
....
-(void) viewWillAppear:(BOOL) animated {
}
in myappdelegate.h I included UISplitViewControllerDelegate
I expected viewWillAppear to fire but it is not. I assume if I had subclass UISplitViewControler it would have fire. right?
BTW: I am doing this without using IB. Do I need to set the target for the mySplitViewController?
What I want to do is setup the orientation of the splitviewcontroller when it rotates.
the viewWillAppear method and other view related methods will be called on the view or view controller themselves, not on the delegate.
That means that if you make a subclass of UISplitViewController called SplitViewControllerSubClass, the view... methods will be called on the instance of SplitViewControllerSubClass, not on the delegate object.
But considering you are creating the views and displaying them programmatically, you already know exactly when the view will appear (i.e., right before you add it to the window), so I believe you could do whatever setup you want at that point.