For those that use the iOS Calendar a lot, you know that when you change the orientation of the phone, another view is presented. I am not sure oof this is changing to a subview, a new UIViewController, size classes or some programatic voodoo that Apple has spun.
I can do some of the features with a subview that changes constrains on orientation change, but that is about it. It looks crude and I thought there might be a better way to imitate the Calendar App.
It most likely uses UISplitViewController to achieve this effect. This lets you display two child view controllers side by side.
You can change its preferredDisplayMode property to show or hide secondary (or primary) view controller or set it to .automatic to let it choose the most appropriate layout for the available space.
Related
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!
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.
I need to show UIVIew when i will swipeup on UIViewController in ios with animation like it is coming from that UIVIewController,and i need to place that UIVIew in specific portion in UIVIewController not to cover on entire area.But my problem is i need to create this one in storyboard,normally storyboard means its for showing over all project flow so ,how to do that in storyboard.Please help me as soon as possible.I am new to iphone development i can do by programatically but i am not getting how to do with xib.
Thanks & Regards
Harshitha
You're going to want to look at custom View Controller transitions, introduced in iOS 7. There were a couple of WWDC 2013 sessions on this, including one called "Implementing Engaging UI"
The fact that you're using a storyboard doesn't matter, storyboards are just a way to define your view controllers and navigations via segues. If you're doing a custom animation, your View Controller still segues as normal, it just does so with a custom animation (instead of one of the stock ones, like a Navigation Controller "push" or the various Modal VC presentations), which you provide via an animation controller - an object that conforms to UIViewControllerAnimatedTransitioning.
Storyboard, or XIB? They are different.
The simplest thing to do is probably to create your view and get it set up in it's final position inside the view controller. Hook up an outlet to your view in your view controller.
Note the Y coordinate of the view when it is at the location you want it. Then use the size inspector to change the y coordinate of the view to the bottom of the view. (768 for a landscape iPad app, 1024 for a portrait iPad app, etc.)
Then attach a swipe gesture recognizer to your VC's content view, and in action for the swipe gesture, use a UIView animation method (animateWithDuration:animations: or a similar method to move the view's frame.origin.y up to the y desired y coordinate.
What is the general pattern for supporting a different display on a VC rotation?
Would I create a new VC in interface builder, design it, etc.. Then on willRotate, segue to it? Or what is the proper way to handle this?
Example, tableview in portrait.
Rotate left, and now show a graph
I eneded up adding a different view controller designed sideways. Then I used the rotation delegate methods to figure out when something rotates to make the move.
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