How to restrict single UIViewController in iOS 10 universal app to portrait layout? - ios

I have an iOS 10 universal app (supports both iPad and iPhone). In the application .plist I have specified that the app supports both portrait and landscape mode. Now I would like to restrict a single UIViewController to portrait only mode. That view controller is presented by the same navigation controller that presents other view controllers. What is the best (easiest) way to restrict a single, specific view controller to portrait in iOS 10. (Note that there are lots of published solutions, but as far as I can tell the answer to this problem is is different for different versions of iOS. I only need a solution that supports iOS 10.)

Now I would like to restrict a single UIViewController to portrait only mode. That view controller is presented by the same navigation controller that presents other view controllers
In iOS 10, there is no supported way to do what you're describing. A navigation controller cannot have some of its children in one orientation and other children in another.
The only supported way to have a view controller force a different orientation is to make it a presented view controller (modal), not a pushed view controller in a navigation controller stack.

Related

iOS Custom modal presentation ignores supportedInterfaceOrientation

I'm currently using a custom subclass of UIViewControllerTransitioningDelegateto create a custom modal presentation. The problem I'm facing is when the presenting and presented view controllers support different interface orientations.
My situation is pretty simple. View Controller A supports all orientations. View Controller B only supports portrait. When A presents B while in landscape, B is presented in landscape.
This behavior can be fixed by switching from a custom modal presentation to a default presentation, which would imply that there is a way for the transitioning delegate to fix this behavior without some of the hacks that have been accepted on other answers.
What is the correct way of supporting different view controller orientations when creating custom modal animations?

iOS ViewController only support portrait but popup support all orientation

Is it possible to support all orientation for popup (UIAlertController) which pops from the view controller, which is only supporting portrait right now?
Now I have viewcontroller support only portrait but the popup for this viewcontroller not to be landscape.
Help me.
If you have added UIAlertController to the portrait only view controller then i don't think this alert controller only can support all orientations since its added as a child of that view controller so it has to abide the parent.
Whereas if UIAlertController common to Application level then there may be possibilities to support any orientation.
Correct me if my understanding is wrong.

UISplitViewController - set always visible master controller when

I've studied examples of split view (like this one) and it works great. I just need one change of behavior. I would like to have both master and detail controller visible when user have iPad in portrait. It should work just like FB Messenger or Skype. Both controllers side-by-side and without able to hide master controller. How is it possible to do that? Thanks for help
Bonus question: Is it possible to somehow set behavior for iPad portrait be same like iPhone portrait? If I would change my mind and I would like to have detail in fullscreen and after tap on left navigation bar button I would have master view in fullscreen and without detail visible. Is i possible or split view decides that and there is not much what I can do about it?
A UISplitViewController has a property called preferredDisplayMode. You can set this to any one of these values:
UISplitViewControllerDisplayModeAutomatic
UISplitViewControllerDisplayModePrimaryHidden
UISplitViewControllerDisplayModePrimaryOverlay
UISplitViewControllerDisplayModeAllVisible
You are looking for UISplitViewControllerDisplayModeAllVisible.
[self.splitViewController setPreferredDisplayMode:UISplitViewControllerDisplayModeAllVisible];
UISplitViewControllerDisplayModeAllVisible
The primary and secondary view controllers are displayed side-by-side onscreen.
Available in iOS 8.0 and later.
You can read more about the display modes here on Apple's documentation.

UISplitViewController - hiding master view in iPad landscape

I'm using the iOS SDK 8.1.
In landscape mode, is it possible to make the master view animate left to hide and then animate right to display again? I don't want it to overlap the detail view like in portrait mode.
Would I have to create my own custom split view controller for that functionality?
No, it is not possible to hide/unhide master in landscape mode.
There are many opensource libraries for creating custom splitView controller available.
This is one good library : https://github.com/mutualmobile/MMDrawerController

UISplitViewController inside tab bar

I have an app which has a login screen and when the user logs in, a tab bar controller is pushed. I currently have some views that would benefit from the fact that apple now allows using the split view controller in all iOS devices, so I was preparing to implement this when I read that the UISplitViewController must always be the root view controller. So I was wondering if it is possible to make the view in one of the tabs become a master-detail view using a UISplitViewController or will I need to implement this manually?
In case it is not possible to show the split view as a tab, could it be pushed from the tab bar controller? (e.g. the user taps a row in a table view and the master-detail view appears).
UISplitViewController in iOS 14 gained new API including a new column style that behaves differently from the unspecified style which is the "classic" interface. Using the modern column-style API, if you try to embed a UISplitViewController in a UITabBarController, it may not behave as you'd expect. For example, at least as of iOS 15, only the secondary view controller may be visible when you'd expect the primary and secondary be shown side-by-side. The documentation does note the following:
When you build your app’s user interface, the split view controller is typically the root view controller of your app’s window. ... Although it’s possible to install a split view controller as a child in some other container view controllers, doing so is not recommended in most cases.
I have however shipped multiple apps that put a split view controller in a tab bar controller using that classic API (via storyboard and programmatically), and they continue to work as of iOS 15. But it may be wise to move away from this as it's seemingly not an officially supported configuration.
Original answer pre-iOS 14:
You can definitely embed a UISplitViewController inside a UITabBarController. I've done just that for an app I released on the App Store. It has 3 tabs and each one is a split view controller.
Just drag out a tab bar controller into your Storyboard, delete the two controllers it added, then drag out a split view controller. Control drag from the tab bar controller to the split view controller and select the "view controllers" relationship segue.
On Xcode versions less than Xcode 8, you may see black or white bars at the top and bottom of the split view controller in the Interface Builder canvas, but these will not appear when the app is run on a device.
Here is the app running to show the split view embedded inside the tab bar controller on iPhone 6s Plus:
When you put a UISplitViewController inside a UITabBarController and the tab bar is set to be opaque you have an issue where your UISplitViewController content is shifted up the size of the tab bar:
To fix this issue you have to check the Under Opaque Bars checkbox on your UISplitViewController in your storyboard:
And now the UISplitViewController view size is correctly computed:
There is also a problem using this approach in iPhone (>IOS8) where the splitviewcontroller is in collapsed mode. When we push the list view to the details view we cannot hide the tabbarcontroller using the conventional "hidesBottomBarWhenPushed". So I have added the TabBarcontroller as root viewcontroller of a navigationcontroller. Now when I push to details view, I send the message to the root navigation controller and push the view to the details view instance in collapsed mode whereas in regular mode I just push it using showDetailsViewController()
For me, this worked.
XCode 13.2.1
iOS 15.2
splitViewController.extendedLayoutIncludesOpaqueBars = true

Resources