Get the presented Viewcontroller from ReactNative rootviewcontroller - ios

In React Native project I want to access the Presented Viewcontroller from iOS npm module. I'm able to access the rootviewcontroller of the RN project using the below code
UIViewController *vc = [UIApplication sharedApplication].delegate.window.rootViewController;
But I want the current VC that is presented on top of RootVC so that I should be able to present native(iOS) UINavigationController on top of it.
Note:[UIApplication sharedApplication].delegate.window.rootViewController.presentedViewController returns nill.

I know this was asked a long time ago, but I was running into the same problem today ([UIApplication sharedApplication].delegate.window.rootViewController.presentedViewController returns nil) and couldn't find the solution for a while, so I'll leave this here for anyone still looking.
There's a function in the React Native source code that allows you to determine the presented view controller. It seems like they use this for their ActionSheetIOS module (see this line). To use this in your own native module, add the following:
// Put this near the top of the file
#import <React/RCTUtils.h>
...
// Put this where you need access to the presented view controller
UIViewController *presentedViewController = RCTPresentedViewController();

Related

Present full screen modal from anywhere, without reference to current ViewController

I would like to present a full screen ViewController without any knowledge about the current ViewController hierarchy. My current solution to find the ViewController on which I can always present my full screen ViewController is the following:
+ (UIViewController*) topMostController
{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
return topController;
}
The background why I need this: our app uses a lot of
[[UIApplication sharedApplication]openURL:[NSURL urlWithString:#"http://www.someurl.com"]];
calls which open Safari externally. Apple started to reject this, because they think it's detrimental to the user experience, and we should use SFSafariViewController instead. But unlike openURL this requires a reference to a ViewController on which we can present SFSafariViewController. I don't want to change the code to acquire the appropriate ViewController at dozens of places, instead a universal method would be nice which gets the appropriate ViewController. The code I listed works every single time in our app, but I am unsure if it's really universal.

Stacked UINavigationController

I'm new in iOS and I'm working with Storyboards.
I have an application with some views.
My rootViewController (1) is a UINavigationController that connects to other views. At one point in the application (2), I include a component (SWRevealViewController, Facebook Side Menu Style) that is an instance of UINavigationController, so I have two UINavigationControllers nested within each other. I want to remove or change the first UINavigationController by the new one (2), and just have only one. All views are accessed via custom segues.
Detailed Image Here
I think the solution is to change the rootViewController before loading the view (2), and set the second UINavigationController as the main of the application.
Detailed Image Here
I tried to solve it accessing by:
[UIApplication delegate].window.rootViewController = myController;
but I only have nil or a empty window.
I read many post that the solution could be in my AppDelegate in the method
- (void) applicationDidFinishLaunching: (UIApplication *) application I can't understand how to apply it to my structure, because that method is called when the application is launched.
I think that my workflow application is wrong.Any feedback or help is welcome!
Thanks in advance.
It's fine to change the root view controller from another controller, but your code is wrong. It should be:
[UIApplication sharedApplication].delegate.window.rootViewController = myController;
If you're doing this action from a controller whose view is currently on screen, you can do it this way instead:
self.view.window.rootViewController = myController;
This should work as long as myController has been properly instantiated.
You could possibly remove (1) or off load it into another view controller that is hidden and once the user goes back to a point where you want (1) back you can load it back in. This could be done in the - (void) applicationDidFinishLaunching: (UIApplication *) application.

What is self.window in iOS app delegate

I have a question regarding window and viewcontroller in iOS. I just have a look at the app delegate of iOS project that I am working on today and found that it is required to have...
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
in my app.
Here are the questions:
Does this means that navigationController is the root view controller of my app? NavigationController is a subclass of UIViewController, but its task is only for providing navigation function at the navigation bar, correct?
What is self.window? I think I understand the concept of 'view' and 'viewController' but I do not quite understand what a 'window' is... An iPhone has one screen, but MacPro could have 2 monitors; Are these windows in terms of iOS and OS X?
Possibly. self.window.rootViewController will return the root view controller of the window, I presume, in this case, from the storyboard. The fact that this line casts the object returned to a navigation controller doesn't make it one -- it will be whatever it is in the storyboard (the controller with that left arrow that's not connected to anything else). Assuming that the cast is correct, this allows you to write things like navigationController.topViewController and not have the compiler complain about it. As for the navigation controller's function, it does provide the function for the navigation bar, but it also shows the view of its content controllers, with its topViewController's view being the one that you will see at start up.
A window in iOS, is a UIWindow, which is a subclass of UIView, so it's not the same as a window in OS X. Look at the Overview section of the UIWindow Class Reference for a discussion of what it does.

IOS 5 Opening a specific ViewController from the AppDelegate

I am really new to IOS so I apologize if this questions is not worded clearly. I have tried searching around but I have not found exactly what I am looking for.
basically in my AppDelegate applicationDidBecomeActive method, I am making a call to my webservice to make sure that the user is still a valid user, and to pull down some refrehsed data, or kick them back to the login page if they are no longer valid.
The part that I am having trouble with is the second part. How can I load and show and specific ViewController(in this case the loginViewController) when the user is found to be invalid? I want to let the normal viewController flow happen when they are valid, which is is doing fine, but I can not figure out how to launch a specific viewController when I need to from AppDelegate.
Any ideas?
I think I got it! I used this code in the AppDelegate to display the ViewController I needed.
UIViewController *loginController = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:#"LoginViewController"];
UINavigationController *loginNavController = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:#"LoginNavController"];
UIViewController *currentVC = self.window.rootViewController;
_window.rootViewController = loginNavController;
[currentVC presentViewController:loginNavController animated:NO completion:nil];
For simplicity, lets say you have a one view app (not nav controller, not tab bar controller - the solution scales but easier to explain). When you get the appDelegate message that the app launched, then make a UIImageView the root view and show your launch image (user thinks you are still booting up). Try to log in, and do this in some other object (not a view controller). If you succeed, you make your desired view the rootView, and users sees it. If the login fails, then you makea login window the rootView. The key here is to have an object that is driving this and can interact with the appDelegate. You could also add this functionality to the appDelegate itself.

SplitVIewController Application with multipleDetailViews

I am just starting with iPad App development. I want to use splitViewController in my app. I want to use different viewControllers. These will be loaded on rightHandView of an ipad when user selects appropriate on tableviewcontroller present on left hand.
I am using iOS SDK 5.0 without storyboard. I have seen apple's example of multipleDetailView and tried to follow similar procedure but its not working with iOS 5.0 sdk and Xcode4.2, I can not able to access MainWindow.Xib in my project as there is not one when you create project with XCode4.2 and master detail template.
Can anyone tell me how to approach this problem or direct me to appropriate resources ?
Regards,
Sumit
It seems that compared to previous versions, XCode 4.2 generates the relevant code in the "AppDelegate.m" instead of somewhere in the .xib file. I'm not sure about how to work with a MainWindow.xib here, but you could easily push other view controllers in the detail view navigation controller programmatically:
Use the following code for example on a button touch up action:
- (IBAction)buttonClick:(id)sender {
MySecondViewController *vc = [[MySecondViewController alloc] initWithNibName:#"MySecondViewController" bundle:nil];
[self.navigationController pushViewController:vc animated:TRUE];
}
To dismiss the top controller and get back you can use either
[self.navigationController popViewControllerAnimated:TRUE];
in the new top-of-the-stack controller (here MySecondViewController) or just the Back button in the navigation bar.

Resources