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;
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 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;
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)
This might be a simple question, but I moved one of my apps from a view based application to a window-based application. In the original app, I had one view with a view controller and a map. I had a class that parsed some data and sent it to the view controller. I used the following code from ClassA to send data to ClassB which added an annotation.
AnnotationProblemAppDelegate *appDelegate = (AnnotationProblemAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.viewController loadOutAnnotations];
I cannot alloc the view controller because it will create a new instance of the view controller. I need to pass a reference to the view controller when creating ClassA.
Now that the map view is nested within a UITabBArController, I am not sure exactly how I pass the reference from ClassA to the ClassB with the map. Do I need to add a new delegate method or initiate a protocol? I hope this is enough information. Let me know if I can clarify any further.
Thank you in advance!
I figured it out myself. To call [[UIApplication sharedApplication] delegate], I had to some coded to connect everything up in my window-based application. I completed the following steps to hook everything up:
I referenced the class in MyAppDelegate.h before #interface
#class MyClass
Declare an IBOutlet for my class
IBOutlet MyClass *myClass;
Make my IBOutlet a property
#property (nonatomic, retain) IBOutlet MyClass *myClass;
Synthesize the property (make sure to also release it)
#synthesize myClass;
Connect the IBOutlet to the view controller in Interface Builder. In my app which had a Tab Bar Controller and a Navigation Controller inside the Tab Bar Controller, I had to make sure the IBOutlet went to the view controller which was nested with in the navigation controllers.
Finally, to reference myClass in any of my other classes, I called UIApplication sharedApplication with the following code:
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.myClass methodBeingCalled];
I hope this helps if you come across the same problem!