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.
Related
I have a viewController A which will both added into viewController hierarchy by being pushed by view B(presented) and being pushed by view C(pushed).
ROOT->...-(-present-)->B-(-push-)->A
ROOT->...-(-push-)->C-(-push-)->A
And now I have a button in viewController A which needs to change the window.rootViewController, but I cannot make it functions correct in both conditions.
When I use [self.navigationController popToRootViewControllerAnimated:<#(BOOL)#>];, it will not dismiss the presented view B.
Also [[[UIApplication sharedApplication] keyWindow].rootViewController dismissViewControllerAnimated:YES completion:<#^(void)completion#>]; is not the solution, because when there is no presented view completion block will not be called.
If I combine those two methods, I think it will work only when I pass a parameter to every viewController in the hierarchy.
So is there a rough way to clear the viewController hierarchy?
Or is there any other solution?
You can set rootViewController from anywhere in application like,
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];
appDelegate.window.rootViewController = #"desired root VC"; // instatntiate your VC and set as root VC of your window
And don't forget to implement AppDelegate.h in that class.
I'm really new to Objective C and I've got an application with a storyboard with a ViewController with the MyViewController class. I then have CDVPlugin (for my cordova application). From one of the methods in my cordova application I want to be able to reference the Active ViewController and call one of the functions from it. I have imported the MyViewController.h header and I was thinking maybe there is a way to make one a delegate for the other but I feel like this is the wrong way to approach this?
Any ideas?
You can get the current root view controller for the application using:
[UIApplication sharedApplication].delegate.window.rootViewController
The root view controller might be the active view controller, or it might be a navigation controller, in which case you might want something like:
UIViewController *active = ((UINavigationController *)[UIApplication sharedApplication].delegate.window.rootViewController).visibleViewController
if [active isKindOfClass: [MyViewController class]] {
MyViewController *myViewController = (MyViewController *)active
// Call any methods you need to on myViewController
}
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 am trying to set the delegate of a view controller from my app delegate.
But it does not work.
AppDelegate.m:
UIStoryboard* sb = [UIStoryboard storyboardWithName:#"MainStoryboard"
bundle:nil];
SFLoginViewController * LoginVC = (SFLoginViewController *)[sb
instantiateViewControllerWithIdentifier:#"Login"];
LoginVC.delegate = self;
SFLoginViewController.m
- (IBAction)Login:(id)sender {
NSLog(#"%#",self.delegate); //returns nil (!!)
//It should call the delegate method here
[[self delegate] LoginSucceeded];
}
any help?
Why not set your delegate in the ViewController like this:
self.delegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
Then you'll be able to handle delegate events in your AppDelegate.
Looking at the instantiateViewControllerWithIdentifier documentation...
Discussion You use this method to create view controller objects that
you want to manipulate and present programmatically in your
application. Before you can use this method to retrieve a view
controller, you must explicitly tag it with an appropriate identifier
string in Interface Builder.
This method creates a new instance of the specified view controller
each time you call it.
I don't think the code you have in your appDelegate is returning the ViewController that is presented via the storyboard
By doing this
(SFLoginViewController *)[sb instantiateViewControllerWithIdentifier:#"Login"];
you are creating a new instance of SFLoginViewController.
I assume that you already have an instance of this viewcontroller created from the storyboard.
The instance from the storyboad is the one who call its method login:(id)sender and not the one you assigned the delegate.
Try #hw731 answer or you need to add the delegate to the instance created from the storyboard (not to the one you'are creating in your appdelegate).