I have an app which displays a simple tableview and I wanted to add the SWRevealViewController as well.
In my appDelegate, before I added the SWReveal VC, I was setting my tableViewController like so...
In didFinishLaunchingWithOptions:
STRTableViewController *tableViewController = [(UINavigationController *)self.window.rootViewController viewControllers][0];
self.delegate = tableViewController;
and then again in the below method:
- (void)loadTableViewData
{
UINavigationController *navVC = (UINavigationController *)self.window.rootViewController;
STRTableViewController *tableVC = navVC.childViewControllers[0];
[tableVC loadTableData]
}
Obviously when I put the SWRevealViewController to the front of the line, this no longer works as it is now trying to call loadTableData from the wrong view controller.
I've tried several ways and keep coming up short. How do I go about accessing the tableViewController now that it is not the first view controller?
If you need more code or logs or anything I'll be happy to post additional info. I have a feeling the answer is right there, I just don't have the experience to see it.
Also, just to be clear, now in the storyboard it goes from Reveal View Controller to Navigation Controller (the tableview's nav VC/ sw_front) and also to the sw_rear VC. Before it simply started with the Navigation Controller.
Thanks!
There's a bunch of ways you can go about keeping a reference to this.
The simplest would be just to keep a reference to the view controller in the AppDelegate.m
So you add a property
#property (nonatomic, strong) STRTableViewController *tableViewController;
Then, whenever and wherever you are instantiating and setting that table view controller, just do something like:
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
delegate.tableViewController = justCreatedTableViewController;
You'll need to #import "AppDelegate.h" to access the app delegate in other classes where you want to do this.
Then to access it you can just do something like:
- (void)loadTableViewData
{
[self.tableViewController loadTableData]
}
Related
I need to get in AppDelegate one parameter of some ViewController.
It not root for AppDelegate.
What is faster way to do it? Delegation?
Make it a property on your VC and then your AppDelegate can access it as needed.
First something is terribly wrong with your design otherwise there shouldn't be any need for you to do something like this.
Second, you haven't provided any relevant information about your VC hierarchy and there is no general solution for this.
However , here are few workarounds / patches:
1) If you are using storyboard you can use :
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"mystoryboard"
bundle:nil];
UIViewController* vc = [sb instantiateViewControllerWithIdentifier:#"ExampleViewController"];
2) You can make make view controller singleton and access it directly from AppDelegate
3) Hacky Method: In AppDelegate have a #property (nonatomic, retain) UIVIewController *hackyViewController;
In hackyViewController.m do this
-(void)viewDidLoad{
// call super
YourAppDelegate *appDelegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
YourAppDelegate.hackyViewController =self;
}
Ideally , you should navigate through viewcontroller hierarchy using parentViewController and childViewcontroller property of UIVIewcontroller to get the instance. You can also make a recursive function which navigates through all childViewcontroller and check instance using iSKindOf to identify the viewcontroller you are looking for but this method does not work with all iOS configurations.
I make a Tabbed Application using storyboard template, two view controllers are embedded.
This is what I want to do: in the first viewController, let TabBar to select the second viewController programmatically.
The first viewController is a tableViewController, shows a list of items, and each item will push to a detailViewController. In the detailViewController, I edit some information and save the item. Then I want app to show the second ViewController, which is a tableViewController shows saved item.
Usually, we can use [TabBarController setSelectedIndex:1]; to select the second viewController.
However, since this is a storyboard template application, so many code are hidden behind. So I cannot get the TabBar instance in the first viewController, and use setSelectedIndex method.
This is what confuses me...
And now, I have found the solution for this problem. My answer is below.
I have figured out how to solve this problem.
First I add new a class: MyTabBarController.
Then, in storyboard, select the Tab Bar Controller, in identity inspector panel, set the custom class to this new class.
For the first viewController class, add a property
#property (nonatomic, weak) UITabBarController *tabBarController;
Then add - (void)viewDidAppear:(BOOL)animated in MyTabBarController class:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UINavigationController *navigationController = [self.viewControllers objectAtIndex:0];
FirstViewController *firstViewController = (FirstViewController *)navigationController.topViewController;
firstViewController.tabBarController = self;
In this way, I pass the tabBarController instance to the firstViewController, so, in the firstViewController, I can call [tabBarController setSelectedIndex:1];
Storyboard gives me a visual interface, however, it hides so many things behind.
I'm a new guy in this field
and i have a problem when i addSubView in AppDelegate
i have a Custom Controller look like this:
#interface mainViewController : UIViewController <UITableViewDelegate>
{
UITabBarController *myTad;
UITableView *myTable;
aModel *myModel
// ......
}
//Some methods and #property
All i want is make a View Controller that gets other Controller also connect to the model.
this is the place work all the things
and in AppDelegate i added in proper way.
[window addSubview: myController.view];
[window makeKeyAndVisible];
return YES
but its just didn't work ?
The Problem is loadView, the method i overWrite in mainViewController implement not do anythings. It's just go through
didn't i miss something?
You need to push your new view controller onto the stack, like so:
[self.navigationController pushViewController:myController];
Use a UINavigationController to control and 'connect' your views. This will allow you to push them properly and navigate back via back button.
I've got a project setup using a Storyboard that contains a UITabViewController as the initial root view. One of the tabs loads a NavigationController that in turn loads a custom view controller class.
From the custom view controller, I have a navigation bar button that I want to trigger an action that returns the root UITabViewController to it's first index. I've been able to do this using a traditional xib structure by adding the appDelegate class to the xib and linking a method to the button that way.
Effectively, I want the button to trigger code that looks something like this:
#implementation AppDelegate
#synthesize window = _window;
#synthesize tabBarController=_tabBarController;
-(IBAction)handleHome:(id)sender{
//How do I send a message to the tabBarController?
[self.tabBarController setSelectedIndex:0];
}
Is it possible to do this with the Storyboard approach? I looked at Segue's but that doesn't seem to be what I'm trying to do (there is no way for me to talk to the root UITabViewController from what I can see).
I've got the handeHome method being triggered using the Responder approach, so really all I need to know is how to access the instantiated tabViewController in the Storyboard.
Hopefully this question makes sense, let me know if there is anything I should expand on.
Why not just do this in your custom view controller?
- (IBAction)handleHome:(id)sender {
self.tabBarController.selectedIndex = 0;
}
The tabBarController property is built in to UIViewController.
I figured it out. I updated the quoted block of code to this:
#implementation AppDelegate
#synthesize window = _window;
-(IBAction)handleHome:(id)sender{
UITabBarController *tabViewController = (UITabBarController *) self.window.rootViewController;
[tabViewController setSelectedIndex:0];
}
Sigh... need more coffee before asking questions on SO
When I try to push a UIViewController subclass (MissionViewController) onto a UINavigationController from within my root view controller, the viewDidLoad method is only called if I reference the underlying view after initializing the view controller. However, even with the method called, the screen is not updated.
Both the view controller and the navigation controller are not nil. The file owner in MissionView.xib is set to MissionViewController. The view property of the file owner points to the nib view. I've verified that the topViewController property of the navigation controller points to the MissionViewController object.
If I change MissionViewController to be the root view controller, the view loads fine. Saw several similar posts but still having problems.
rootViewController.h
#interface TreeGraphController : UIViewController
{
MissionViewController *missionViewCtrlr;
}
#property(nonatomic, retain) MissionViewController *missionViewCtrlr;
rootViewController.m
#import "MissionViewController.h"
...
if (!missionViewCtrlr)
{
MissionViewController *ctrlr = [[MissionViewController alloc] initWithNibName:#"MissionView" bundle:nil];
ctrlr.view.hidden = NO;
self.missionViewCtrlr = ctrlr;
[ctrlr release];
}
myAppDelegate *del = [[UIApplication sharedApplication] delegate];
[del.navigationController pushViewController:missionViewCtrlr animated:NO];
What about using
[self.navigationController pushViewController:missionViewCtrlr];
in the rootViewController? I assume rootViewController has been pushed to a UINavigationController and that the navigation controller's view was added as a subview of self.window in the app delegate?
Btw, you may simplify part of your code by just saying
if(!missionViewCtrlr)
self.missionViewCtrlr = [[MisionViewController alloc] init...];