Not able to lock orientation for 1 VC - ios

I am trying to get device rotation right.
I am testing on iPad 8.x/9.x simulator
I have 4 VCs
VC1 - Both Portrait and Landscape
VC2 - Both Portrait and Landscape
VC3 - Only Portrait
VC4 - Both Portrait and Landscape
Goal: to have VC3 display PortraitView at all times (same as if app orientation was fixed to portrait).
I tried
#implementation RotationAwareNavigationController
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
UIViewController *top = self.topViewController;
return top.supportedInterfaceOrientations;
}
-(BOOL)shouldAutorotate {
UIViewController *top = self.topViewController;
return [top shouldAutorotate];
}
#end
In VC which is portrait
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
But it does not work meaning view not displayed in Portrait dimensions Am I missing something?
I am sure it can be done as when I use ImagePickerController provided my iOS, it is fixed to Portrait. I just dont know how to do it.

To support differing orientations in different view controllers, you will need to do a few things. First, you need to check all the checkboxes for orientations you want to support in your target's General settings tab.
Second, anytime you call presentViewController or dismissViewController in your app, the UIApplicationDelegate method application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask will be called. You can use this method to restrict (or allow) specific orientations each time a new view controller is presented or dismissed. Unfortunately, it isn't as simple as just returning a UIInterfaceOrientationMask here. You will need to find the view controller that is going to be showing on screen and return the orientations that it supports. Here is an example of this:
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
guard let window = window, let rootViewController = window.rootViewController else {
return UIDevice.currentDevice().userInterfaceIdiom == .Pad ? .All : .AllButUpsideDown // iOS defaults
}
// Let the view controller being shown decide what orientation it wants to support. This method will be called anytime a new view controller is presented on screen.
return findVisibleViewController(rootViewController: rootViewController).supportedInterfaceOrientations()
}
/// Searches the view hierarchy recursively and finds the view controller that is currently showing.
private func findVisibleViewController(rootViewController rootViewController: UIViewController) -> UIViewController {
if let presentedViewController = rootViewController.presentedViewController {
// Search for a modal view first.
return self.findVisibleViewController(rootViewController: presentedViewController)
} else if
let navigationController = rootViewController as? UINavigationController,
let visibleViewController = navigationController.visibleViewController {
// Then search navigation controller's views to find its visible controller.
return self.findVisibleViewController(rootViewController: visibleViewController)
} else if let splitViewController = rootViewController as? UISplitViewController {
// Then try the split view controller. This will be the true root view controller. Use the master here since the detail just shows web views.
return self.findVisibleViewController(rootViewController: splitViewController.viewControllers[0])
} else {
// Guess we found the visible view controller, because none of the other conditions were met.
return rootViewController
}
}
findVisibleViewController(_:) is an example from one of my projects and is tailored to the exact view controller hierarchy in my app. You will need to edit this for your own app in a way that makes sense for your hierarchy.
Third, you will need to implement supportedInterfaceOrientations() for most, if not all, of your view controllers.
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
return // portrait, landscape, or combinations of those.
}
Finally, this only handles situations where you presented or dismissed something modally. For show (push) segues, the orientation of the navigation controller will be used for every new view controller pushed onto the stack. If you need more fine grained control here, you will need to force the orientation to happen. Here is an example of that:
// Some other view had the screen in landscape, so force the view to return to portrait
UIDevice.currentDevice().setValue(UIInterfaceOrientation.Portrait.rawValue, forKey: "orientation")

Related

Prevent UIViewController from rotating when modal is rotating

My App is basically a portrait only app. So nothing is rotating. But not there is ONE exception. The user can add photos and when viewing those photos full-screen, this ViewController SHOULD be allowed to rotate.
So I thought that if my ViewController that is presenting has supportedInterfaceOrientations return .portrait and also shouldAutorotate return false, that this should be enough, to prevent that one from rotation?!?
Turns out, that when I rotate while having the full-screen image presented, the one underneath is rotated as well.
To summarize:
RootViewController should NEVER rotate
PresentedViewController can rotate, but his rotation should no rotate the RootViewController
Is there a way to achieve that?
Probably too late, but in case if somebody will be faced with the same issue, i would provide my solution.
Actually suppress rotation of underlying window is possible if set modalPresentationStyle = .fullScreen for presented controller, then if you take a look of "View UI Hierarchy" then you can notice that controller which represents controller in fullscreen will be removed from controllers hierarchy. But at the same time modalPresentationStyle = .overFullScreen keep everything as is, what causing rotating underlying controller even it set by default supported orientation to portrait, i.e. UIWindow who manages and routes system events over hierarchy respect settings of the toppest controller in case of modalPresentationStyle = .overFullScreen. So according to the facts, and if it is necessary to have e.g. custom presentation, i would suggest to use additional UIWindow which will be responsible for the presenting controller in fullscreen.
i have implemented test project for the solution: here
You can give an exception like in AppDelegate:
//auto rotate
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
//landscape for perticular view controller
let navigationController = window?.rootViewController as? UINavigationController
if let activeController = navigationController?.visibleViewController {
if activeController.isKind(of: VGVideoVC.self) {//Pass your VC here
// print("I have found my controller!")
return UIInterfaceOrientationMask.all;
}else{
return UIInterfaceOrientationMask.portrait;
}
}else{
return UIInterfaceOrientationMask.portrait;
}
}
And in the Rest of the VC where you want it to be forcefully portrait, you can use like this:
//MARK:- Screen Orientation
override var supportedInterfaceOrientations: UIInterfaceOrientationMask{
return .portrait
}
override var shouldAutorotate: Bool{
return true
}
Hope this helps.
I would say disable the orientation change for the complete app and listen to device orientation change in Photos view controller and update the UI of photosVC on device orientation change.
Something like this:
NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: Notification.Name("UIDeviceOrientationDidChangeNotification"), object: nil)
#objc func orientationChanged() {
if(UIDeviceOrientationIsLandscape(UIDevice.current.orientation)){
print("landscape")
}
if(UIDeviceOrientationIsPortrait(UIDevice.current.orientation)){
print("Portrait")
}
}
Be careful with the upside down and other orientations which you don't need.
Try this code below. I followed This tutorial and it works for me. What's going on is:
Step 1. Assuming inside General your Device Orientation is set to Portrait only:
Step 2. The code below that you add inside AppDelegate loops through the navigation controllers and then looks inside their top view controllers. If any of those vcs have a function with the name canRotate then that specific vc will change the device orientation from Step 1. by returning: return .allButUpsideDown
Add these 2 functions to the bottom of your AppDelegate:
// add this first function
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
// if the navigationController's root vc has a function inside of it named canRotate
if let rootViewController = self.topViewControllerWithRootViewController(rootViewController: window?.rootViewController) {
if (rootViewController.responds(to: Selector(("canRotate")))) {
// Unlock landscape view orientations for this view controller
return .allButUpsideDown;
}
}
// Only allow portrait (standard behaviour). vcs that don't contain a function with the name "canRotate" can't rotate and stay in portrait only
return .portrait;
}
// add this second function
// loop through tabBarController or any navigationControllers
private func topViewControllerWithRootViewController(rootViewController: UIViewController!) -> UIViewController? {
if (rootViewController == nil) { return nil }
if (rootViewController.isKind(of: UITabBarController.self)) {
return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UITabBarController).selectedViewController)
} else if (rootViewController.isKind(of: UINavigationController.self)) {
return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UINavigationController).visibleViewController)
} else if (rootViewController.presentedViewController != nil) {
return topViewControllerWithRootViewController(rootViewController: rootViewController.presentedViewController)
}
return rootViewController
}
Step 3. Inside the modal vc you should add a function named: #objc func canRotate(){}. You don't have to call it anywhere or add anything inside it's curly braces. The code from Step 2 is looking for this function with the name canRotate. If the other vcs don't contain a function with that name then they can't rotate.
Inside the modal viewController that you want to rotate add the canRotate() function anywhere outside of viewDidLoad and inside viewWillDisappear add the code to set everything back to your regular Portrait only :
override func viewDidLoad() {
super.viewDidLoad()
}
#objc func canRotate(){}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// add this so once leaving this vc everything will go back to Portrait only
if (self.isMovingFromParentViewController) {
UIDevice.current.setValue(Int(UIInterfaceOrientation.portrait.rawValue), forKey: "orientation")
}
}

Changing rootViewController for Nav causes UISplitViewController to show detail on Compact portrait orientation

I'm running into an issue where after changing the rootViewController on my UINavigationController and changing it back to my original UINavigationController, a UISplitViewController begins to show both it's master and detail view in a phone device on compact/portrait orientation (so not only on plus size phones, but also others).
Basic overview of architecture:
A TabBarController houses several tabs. One of these tabs is a UISplitViewController. I currently override the following to ensure that the MasterViewController is shown on compact orientations:
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
// this prevents phone from going straight to detail on showing the split view controller
return true
}
This works fine and displays the master on portrait as expected. At any point pressing a button on another tab can create a new UINavigationController instance and display it, in which I'm doing the below to change the rootViewController to the newly created UINavigationController to display:
let appDelegate = UIApplication.shared.delegate
appDelegate?.window??.rootViewController = newNavVC
On dismiss, I'm just swapping the UINavigationController back to the original one through the same code above. However, once I do this one time (create nav/display/dismiss), and I switch my tab back to the one with the UISplitViewController, it changes itself to show a side-by-side master detail view. I didn't know this was possible in portrait mode for compact sizing. I tried changing to any of the 4 preferred display modes in the UISplitViewController, but that didn't fix it.
Below is what it looks like (iPhone 6 simulator), am I missing delegates or misunderstanding collapsing?
Before:
After:
You can replace the the logic that assigned the rootViewController with the code snippet found at this link:
Leaking views when changing rootViewController inside transitionWithView
Basically you just create an extension for the UIWindow class that will set the root view controller correctly.
extension UIWindow {
/// Fix for https://stackoverflow.com/a/27153956/849645
func set(rootViewController newRootViewController: UIViewController, withTransition transition: CATransition? = nil) {
let previousViewController = rootViewController
if let transition = transition {
// Add the transition
layer.add(transition, forKey: kCATransition)
}
rootViewController = newRootViewController
// Update status bar appearance using the new view controllers appearance - animate if needed
if UIView.areAnimationsEnabled {
UIView.animate(withDuration: CATransaction.animationDuration()) {
newRootViewController.setNeedsStatusBarAppearanceUpdate()
}
} else {
newRootViewController.setNeedsStatusBarAppearanceUpdate()
}
/// The presenting view controllers view doesn't get removed from the window as its currently transistioning and presenting a view controller
if let transitionViewClass = NSClassFromString("UITransitionView") {
for subview in subviews where subview.isKind(of: transitionViewClass) {
subview.removeFromSuperview()
}
}
if let previousViewController = previousViewController {
// Allow the view controller to be deallocated
previousViewController.dismiss(animated: false) {
// Remove the root view in case its still showing
previousViewController.view.removeFromSuperview()
}
}
}

Allow only 1 view controller to be in landscape or portrait

my app is portrait what i wanna do is allow 1 view controller to be portrait or landscape i tried using this code in AppDelegate but i am getting an error
func application(_ application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow) -> Int {
let currentViewController: UIViewController? = self.topView
// Get topmost/visible view controller
var currentViewController: UIViewController? = self.topViewController
// Check whether it implements a dummy methods called canRotate
if currentViewController?.responds(to: #selector(self.canRotate)) {
// Unlock landscape view orientations for this view controller
return .allButUpsideDown
}
// Only allow portrait (standard behaviour)
return .portrait
}
}
Does anyone know how to do that in swift?
I took the following approach in my app.
Create a custom UINavigationController with the following code & make sure that your root navigation controller is updated to use this as its class.
import UIKit
class NavigationController: UINavigationController {
override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
if let _ = presentedViewController as? MyPortraitViewController {
return .portrait
}
return .allButUpsideDown
}
}
You can replace MyPortraitViewController with the class name of the view controller you wish to deviate from the global setting.
While I use .portrait in this example, you are free to use other options.
One implementation example would be to replace the class of your base navigation controller in your storyboard which is shown below.

Lock only one ViewController's orientation to landscape, and the remaining to portrait

I want to lock orientation in all ViewControllers to portrait, except on one of them, when it is pushed always to be in landscapeRight.
I've tried many solutions, using extensions for UINavigationController, overriding supportedInterfaceOrientations and shouldAutorotate but no luck.
I've found the solution, which for now it is working.
On every view controller you should put this code for supporting only the desired rotation (landscapeRight in the example):
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.landscapeRight
}
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .landscapeRight
}
On the other implement the same methods but with portrait orientation.
Create an extension for UINavigationController
open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return (self.topViewController?.supportedInterfaceOrientations)!
}
open override var shouldAutorotate: Bool {
return true
}
Note: Also in Project's target enable all desired supported
orientations.
The only one controller that I wanted to show in landscape mode i presented modally.
You will run into confusion if you use the navigation controller to present views. For example, we usually leverage the navigation controller to handle adding views by calling navigation controller instance functions like performSegueWithIdentifier:sender: or pushViewController:animated:.
Pushing is not going to work like you want it to.
And segues will probably not work either, especially if in IB you created the segue off the navigation controller!
Anyway, if you somehow succeeded in overriding the "parent" navigation controller's orientation, you risk running into edge cases down the line and you are probably using something sketchy that may lose support with any update.
That said, the workaround I have found is:
Step 1
Use presentViewController:animated:completion: to present landscapeRight view controller:
// assuming you're using IB and Main bundle
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let landscapeViewController = storyboard.instantiateViewController(withIdentifier: "LandscapeViewControllerStoryboardID")
self.present(landscapeViewController, animated: true, completion: {
print("landscapeViewController presented")
})
Step 2
Adding the following override to your landscapeViewController actually works now:
/* override the preferredInterfaceOrientationForPresentation for a view controller
that is intended to be presented full screen in a specific orientation.
https://developer.apple.com/reference/uikit/uiviewcontroller */
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .landscapeRight
}
Step 3 (Optional)
With all this working, there is still some weirdness when you dismiss your landscapeViewController: It is in landscape orientation now as well.
This is because the navigation controller is playing nice. In other words, now it's the navigation controller's turn to try to force an orientation change, force it back to the way it was.
In order to do this, you need to store the orientation of the device before you present the landscapeViewController. In the view controller from which you present the landscapeViewController, I stored it in an instance variable:
let ratio = self.view.bounds.width / self.view.bounds.height
if (ratio > 1) { // horizontal/landscape
self.currentOrientationIsPortrait = false // read by navigation controller when dismissing full screen view player
} else {
self.currentOrientationIsPortrait = true // read by navigation controller when dismissing full screen view player
}
Then, I test that view controller instance's value in my navigationController class' preferred orientation override. Let's say the view controller from which I present the landscapeViewController is called presentingViewController:
// execution order: during visibileViewController's dismissal
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
get {
if visibleViewController != nil {
// check if landscapeViewController is being dismissed
if (visibleViewController as? LandscapeViewController) != nil {
// check if the top view controller is one that tracks its orientation (currently only presentingViewController)
if let presentingViewController = self.viewControllers.last as? PresentingViewController {
if presentingViewController.currentOrientationIsPortrait {
return .portrait // TODO should we not support portraitUpsideDown?
}
}
}
// otherwise, return whatever
return visibleViewController!.preferredInterfaceOrientationForPresentation
}
// otherwise, return whatever
return super.preferredInterfaceOrientationForPresentation
}
}
And, bingo. (Hopefully)
EDIT
Also don't forget to put this code in others ViewControllers:
override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
return .portrait
}

Lock orientation of a UIViewController on iOS 8 [duplicate]

I have this app I am working on and I need ALL my view controllers but one to be in portrait.
The single one view controller that is special I need it to be able to rotate to whatever orientation the phone is in.
To do that I present it modally (not embedded in a NavigationController)
So (for example) my structure is like this:
window - Portrait
root view controller (UINavigationController - Portrait)
home view controller (UIViewController - Portrait)
details view controller (UIViewController - Portrait)
.
.
.
modal view controller (UIVIewController - All)
Now when ever I dismiss my modal view controller in a landscape position my parent view controller is ALSO rotated even though it doesn't support that orientation.
All UIViewControllers and UINavigaionControllers in the app inherit from the same general classes which have these methods implemented:
override func supportedInterfaceOrientations() -> Int
{
return Int(UIInterfaceOrientationMask.Portrait.toRaw())
}
My modal view controller overrides this method once again and it looks like this:
override func supportedInterfaceOrientations() -> Int
{
return Int(UIInterfaceOrientationMask.All.toRaw())
}
Update 1
It looks like this is happening only on iOS8 Beta.
Does someone know if there is something that changed regarding view controller's rotation or is this just a bug in the beta?
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if ([self.window.rootViewController.presentedViewController isKindOfClass: [SecondViewController class]])
{
SecondViewController *secondController = (SecondViewController *) self.window.rootViewController.presentedViewController;
if (secondController.isPresented)
return UIInterfaceOrientationMaskAll;
else return UIInterfaceOrientationMaskPortrait;
}
else return UIInterfaceOrientationMaskPortrait;
}
And for Swift
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow) -> Int {
if self.window?.rootViewController?.presentedViewController? is SecondViewController {
let secondController = self.window!.rootViewController.presentedViewController as SecondViewController
if secondController.isPresented {
return Int(UIInterfaceOrientationMask.All.toRaw());
} else {
return Int(UIInterfaceOrientationMask.Portrait.toRaw());
}
} else {
return Int(UIInterfaceOrientationMask.Portrait.toRaw());
}
}
For more details check this link
I'm having the same issue with an app and after days of experimentation I came up with a solution which is not very nice but it works for now. I'm using the delegate method application:supportedInterfaceOrientationsForWindow: within the appdelegate.
I created a test project and put it here on github (including a GIF which shows the result...)
// note: it's not in swift but I hope it helps anyways
After much experimentation, I am convinced that this is a "feature" of iOS 8.
If you think about it, this makes perfect sense, because it has been coming for a long time.
In, say iOS 4, it was possible to force app rotation when changing view controllers in a tab bar controller and a navigation controller, as well as when presenting/dismissing a controller.
Then in iOS 6 it became impossible to force app rotation except when presenting/dismissing a view controller (as I explained in many answers, such as this one).
Now, in iOS 8, I conjecture that it will be impossible to force app rotation at all (except at launch). It can prefer a certain orientation, so that once it is in that orientation it will stay there, but it cannot force the app to go into that orientation.
Instead, your view controller is expected to "adapt". There are several WWDC 2014 videos concentrating on "adaptation", and now I'm starting to understand that this is one reason why this is so important.
EDIT: In seed 4, it looks like this feature (forcing rotation on presentation and dismissal) is returning!
We have an app deployed that has a landscape controller which presents a portrait-only view controller. Was reviewed by Apple on iOS 8. We are only overriding supportedInterfaceOrientations.
It's worth noting that we found lots of differences between betas 3,4,and 5. In the end we had to wait for the GM before making a concerted effort to update our app for iOS 8.
You need to be very careful in iOS 8 to make sure that you don't do this:
[self dismissViewControllerAnimated:YES completion:nil]
[self presentViewController:vc animated:YES completion:nil]
If the outgoing vc is portrait, and the incoming one is landscape, some view frames can end up very messed up. Present the incoming vc in the completion block of the dismiss call instead.
[self dismissViewControllerAnimated:YES completion:^{
[self presentViewController:vc animated:YES completion:nil]
}];
This is actually easier and can be done without any additional properties (here's an example with AVPlayerViewController):
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
if ([self.window.rootViewController.presentedViewController isKindOfClass: [AVPlayerViewController class]])
return self.window.rootViewController.presentedViewController.isBeingDismissed ?
UIInterfaceOrientationMaskPortrait : UIInterfaceOrientationMaskAll;
else
return UIInterfaceOrientationMaskPortrait;
} else {
return UIInterfaceOrientationMaskAll;
}
}
Awesome question and awesome answer provided by #ZaEeM ZaFaR! Combining his answer with this led me to a great and more generic solution.
The drawback of the first answer is that you have to manage the variable isPresented in every view controller that allows rotations. Furthermore, you have to expand the check and cast in supportedInterfaceOrientationsForWindow for every vc that allows rotation.
The drawback of the second answer is that it doesn't work; it also rotates the presenting vc when dismissing the presented vc.
This solution allows rotation in all vc where you put canRotate(){} and doesn't rotate the presenting vc.
Swift 3:
In AppDelegate.swift:
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if let rootViewController = self.topViewControllerWithRootViewController(rootViewController: window?.rootViewController) {
if (rootViewController.responds(to: Selector(("canRotate")))) {
// Unlock landscape view orientations for this view controller if it is not currently being dismissed
if !rootViewController.isBeingDismissed{
return .allButUpsideDown
}
}
}
// Only allow portrait (standard behaviour)
return .portrait
}
private func topViewControllerWithRootViewController(rootViewController: UIViewController!) -> UIViewController? {
if (rootViewController == nil) {
return nil
}
if (rootViewController.isKind(of: UITabBarController.self)) {
return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UITabBarController).selectedViewController)
} else if (rootViewController.isKind(of: UINavigationController.self)) {
return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UINavigationController).visibleViewController)
} else if (rootViewController.presentedViewController != nil) {
return topViewControllerWithRootViewController(rootViewController: rootViewController.presentedViewController)
}
return rootViewController
}
In each view controller where rotation should be allowed:
func canRotate(){}
In the root view controller, try adding:
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
Worked for me.
Swift 3.0 OR Above,
Just check "isBeingDismissed" property of presented view controller.
Below is sample code, This is will rotate presenting view controller to portrait mode immediately after presented view controller is dismissed.
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if let rootViewController = self.topViewControllerWithRootViewController(rootViewController: window?.rootViewController)
{
if rootViewController.canRotateVC == true
{
if baseVC.isBeingDismissed == false
{
return .allButUpsideDown
}
}
}
return .portrait}
you can get topController by below code:
private func topViewControllerWithRootViewController(rootViewController: UIViewController!) -> UIViewController?{
if (rootViewController == nil) { return nil }if (rootViewController.isKind(of: (UITabBarController).self))
{
return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UITabBarController).selectedViewController)
}
else if (rootViewController.isKind(of:(UINavigationController).self))
{
return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UINavigationController).visibleViewController)
}
else if (rootViewController.presentedViewController != nil)
{
return topViewControllerWithRootViewController(rootViewController: rootViewController.presentedViewController)
}
return rootViewController }
I had the same issue, finally found a solution to open the modal view controller in another UIWindow, and it worked smoothly.
Stack -
iOS8 - prevent rotation on presenting viewController
For code:
https://github.com/OrenRosen/ModalInWindow

Resources