iOS Size Classes: Restrict to Single ViewController - ios

With Landscape Left and Landscape Right enabled in an app all of the "screens" for the ViewControllers rotate. Is there a way to restrict rotation to a single ViewController in an index of UITabBarViewController in Objective-C?

By default UITabBarController will allow not defer calls to the various rotation methods of UIViewController to it's children. It is possible to subclass UITabBarController and override these methods with an implementation that calls the method on the currently selected view controller so it can restrict rotation.
Having said that, if you only want a single view controller to be restricted, you run into the issue of the user rotating the screen on a different tab and then selecting the one you want to be locked into a particular orientation. Since there is no supported way to change orientations arbitrarily (you can only attempt a change to the physical device orientation), there's no good solution to this problem.

Related

Support split view and control iPad orientation at the same time

I want to disable rotation on a certain UIViewController in iPad, yet at the same time retain split view in the app.
I am aware that we can check 'Requires full screen' in the General tab to trigger the delegate methods supportedInterfaceOrientations, shouldAutoRotation etc to be called, and I can toggle the rotation here.
But I realized that once I check this, split view is no longer supported in the app. Is there a way to keep split view and control the orientation in certain UIViewControllers at the same time?

iOS 9 Split View App Resizing Strategy

I have an app that I'd like to enable split view on. The UI varies slightly for iPhone vs iPad (compact vs regular width).
In compact width mode, I have a UITableView with a list of items the user can select, and when they do I push a new View Controller onto the navigation stack. However, in regular width, the UITableView list is shown on the left, and then I have some other views to the right (not implemented in a UISplitViewController). So I've implemented these 2 different screens in 2 different ViewController classes.
If my user is using an iPad with regular width and then enters split view with my app and causes the app to change to compact width, I need to change which ViewController I'm showing to the user. What is the best strategy for this?
Note: I'm not using storyboard.
Thanks!
There's 2 ways I see a solution to this. One, you can take a look at UISplitViewControllerDelegate, specifically the section on Collapsing and Expanding the Interface.
Another solution is to override your size collections so that the display is the same on iPhone and iPad, as in nothing collapses and expands, the two views are always "there". You can set the split view controller's preferredDisplayMode to Overlay which looks nice on iPhones. All you need to do is add
UITraitCollection* horizTrait = [UITraitCollection
traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
UITraitCollection* vertTrait = [UITraitCollection
traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassRegular];
UITraitCollection* childTraits = [UITraitCollection
traitCollectionWithTraitsFromCollections:#[horizTrait, vertTrait]];
[self setOverrideTraitCollection:childTraits forChildViewController:self.childViewControllers[0]];
to the parent class of your UISplitViewController (If there is no parent class, you must create one. This can just be a simple navigation controller)
Edit: I should mention that the above code simply sets the traits of the device to regular-regular for all devices.
Thanks for the responses. I was thinking maybe I was supposed to be using state restoration, but then restoring a different View Controller depending on my trait collection.
Instead, I think I'll just create a view controller container and then, in willLayoutSubviews, I'll decide which view controllers to show depending on the current view's trait collections.
Thanks!

UIView in iOS 5 using Storyboards does not rotate content on iPad device rotation

I'm just getting started with Storyboards and iOS 5.1. The application I'm building uses a navigation controller as its root controller, and is designed to be used in landscape orientation (it's an in-house enterprise application).
I created a single view, which worked properly: The content rotates properly to stay "right side up" when the simulator changes orientation.
I then added a new view, and that one doesn't rotate at all; the content stays in portrait orientation (and thus is sideways) when the device rotates.
I've looked through the settings for the two UIViewControllers and UIViews, and can't see any difference between them. Any thoughts as to where I should look?
First of all each UIViewController in the storyboard must have a class sosiated with it. Create a new class which inherits from UIViewController and then, in the storyboard, click on the uiviewcontroller, and at the bottom of that controller, click on the right box and in the class inspector, replace UIViewController with the name of the new class your created.
Then, make sure that in every view controller class that you create, you implement the method
-(BOOL)shouldAutoRotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
Just make this deleate method to return YES in EVERY view controller to make sure that all their views rotate in any orientation. Have you done this?
This has bothered me as well. My app rotated in iPad simulator but not on an actual iPad. Weird enough. I had an UITabBarController with three tabs. All three controllers hooked up to the tab bar did have the method shouldAutoRotateToInterfaceOrientation, but just two of them (5 steps later on drilling through navigation controller) didn't. I've added the method to those as well and now it rotates.
Just my 2ยข.

How to create UISplitViewController's portrait behavior in landscape orientations?

I'm trying to find a solution I've seen implemented in some iPad apps where what appears to be a UISplitViewController does not display the master view docked to the left in landscape orientation. Instead, the behavior is exactly the same in landscape as in portrait, with a UIBarButtonItem on the left side of a UIToolbar at the top of the screen bringing up a UIPopoverController with the master view controller's view. This presents some menu options that, when selected, appear to launch new UIViewController-derived classes into the detail view.
The app I'm working on needs to take advantage of as much screen real estate as possible and having the master view with the menu options docked to the left side doesn't add much value; it actually hinders the app.
So actually what I'm trying to do is two-fold:
Suppress the docked master view in landscape orientation
Have the selection of a row (menu option) in the master view load a new UIViewController-derived class into the detail view.
I've seen examples of each by themselves, respectively:
http://vimeo.com/13054813 (Hiding the Root View of a UISplitViewController)
http://bit.ly/aypcr0 (MultipleDetailViews code example from Apple)
However, I can't seem to get both of these working together.
The reason for using this approach is that I have multiple UIViewController-derived classes that I want to display when the appropriate menu option is selected. I could just instantiate them and add their views to the existing detail view and they would display fine. The problem is that none of the UIViewController lifecycle methods ever get called besides viewDidLoad (e.g. viewWillAppear:, viewDidUnload, etc.). This also includes orientation changes, and this is a big problem for the app. It seems that the only times a UIViewController-derived class acts like a UIViewController is when it is added as a subview of the app's UIWindow, or to a container class (like UINavigationController or UISplitViewController).
Am I going down the right path with the UISplitViewController, or is there a better solution?
Thanks for all of your help in advance!
Justin
This is a good UISplitViewController replacement that has the features you want (and more). It is a direct "drop in" replacement for the real UISplitViewConroller.
http://mattgemmell.com/2010/07/31/mgsplitviewcontroller-for-ipad

UISplitViewController detailView

I have an UISplitViewController base project.
I want to have a different detail View depending the orientation of the app.
Exemple :
In landscape when I select a row in the TableView, I want the detailView to be an UIWebView.
But in portrait I want the detail view to be a complex custom view.
Is it possible ?
Thanks.
See the MultipleDetailView sample project for the basics.
The easiest way to shift views based on orientation is to use a navigation control to push an pop the each orientations custom views in response to changes to orientation. Put the nav code in willRotateToInterfaceOrientation:duration: and the view controllers will pop their views and push the other when the device rotates.
I would say, however, the using two different types of views for the same detail but different orientation will most likely confuse the user. That is not what the interface grammar teaches them to expect. In every other app, it is the same basic view with the same info just adjusted for the change in display dimensions.
You might want to think twice about whether this is a good UI design before spending the time to implement it.

Resources