At the root of my project's world I have a UIViewController *viewController declared in the project's app delegate. I'm trying to get to the view controllers navigationController field so that I can find the top ViewController. However, every time I look at the navigationController field of my viewController it's nil. Clearly I've forgotten to do something. Ideas? Thanks...
Make sure you have a strong property to your navigation controller. (Like Below:)
#property (strong, nonatomic) UINavigationController *navcon;
Then synthesize it in your app delegate implementation file.
#synthesize navcon = _navcon;
And yes, then you can have:
self.navcon = [[UINavigationController alloc] initWithRootViewController:yourViewController];
[self.window addSubview:self.navcon.view];
(Assuming you have ARC enabled)
Related
I am using the storyboard to create my app. At the root of my app is a UITabBarController. How do I access my tabBarController from inside my Application Delegate? I manage to successfully implement the manipulations from inside one of my UIViewControllers. But I want to move the code to my app delegate. How might I accomplish this? I thought I could just drag and drop from storyboard to my app delegate and get something like
#property (nonatomic, strong) IBOutlet UITabBarController *tabBarController;
but that does not seem to be an option presently.
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
Bringing that code to AppDelegate does not seem like a good idea but if you wanted to do it you could add a weak property in the AppDelegate and set that property from your UITabBarController.
In ApplicationDelegate:
#property (nonatomic, weak) MyTabBarController *tabController;
In MyTabBarController awakeFromNib method:
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
delegate.tabController = self;
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]
}
i'm working with core data and navigation controllers. my story board consists of the following: (-> means connected)
UINavigationController -> UIViewController -> UITableViewController (master view controller) -> UITableViewController (detail view Controller)
Apple's Master-Detail Template offers the following in the appDelegate method application:didFinishLoadingWithOptions which actually work only if the storyboard contain
UINavigationController -> UITableViewController
UINavigationController *navigationController = (UINavigationController *) self.window.rootViewController;
SSViewController *controller = (SSViewController *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
this doesn't work in my case because navigation.topViewController will return the UIView Controller. So how can i reach the third view UITableViewController from the application:didFinishLoadingMethod ?
If by 'connected' you mean segues on the storyboard (which is the only logical way I can see to interpret your question), then the answer is that you can't directly.
Instead, you set the property on the UIViewController subclass (whatever the default master and/or detail VC is, as appropriate), and pass it on to UIViewController subclasses further down the chain in the prepareForSegue method.
It's often useful to implement this via a protocol, which appropriate VCs adopt:
#protocol ContextHolder <NSObject>
#property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
#end
In prepareForSegue, you can then do:
((id<ContextHolder>)segue.destinationViewController).managedObjectContext = self.managedObjectContext;
I was trying to redo an example of How to create UINavigationController based application from Beginning iPhone Development by Appress.
I'm getting the following exception:
Exception: Pushing a navigation controller is not supported
Exception: [NSException]:Pushing a navigation controller is not supported
ex.name:'NSInvalidArgumentException'
ex.reason:'Pushing a navigation controller is not supported'
It happens when user try to push a view that is already in the stack, Which is not true in my case.
My_3AppDelegate.h
IBOutlet UINavigationController * navController;
#property (nonatomic, retain) UINavigationController * navController;
My_3AppDelegate.m
[window addSubview: navController.view];
MainWindow.xib adds UINavigationController to the window an connected to the outlet.
The only difference in my code is RootViewController is not a subclass of UITableViewController. It's just UIViewController with 2 UIbuttons.
FirstViewController *fv = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
fv.navigationItem.title=#"First View Controller";
[self.navigationController pushViewController:fv animated:NO];
[fv release];
That error occurs with the initial run of the application, which make sure that, It's not like that, the view was already added to the stack and I'm trying to readied.
Its a very simple tutorial application that I'm stuck in and I'm not sure why?
Any idea?
I've solved the same problem by changing super class from UINavigationCotroller to UIViewController.
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...];