Apple provide the split view only for landscape but not for the portrait mode. Is there any way to achieve the splitview in portrait mode also?
[splitViewController setHidesMasterViewInPortrait:NO];
This will work. But this API is not documented(private).
Thanks,
Manjunath
For iOS5+,
Go to your detailViewController. Your detailViewController should have UISplitViewControllerDelegate. And simply just drop this code in:
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation{
return NO;
}
This will do the trick. And it is public API.
My little contribution here.
Byte's answer is correct up until iOS 7. Starting in iOS 8 you should use preferredDisplayMode
For example, to show both view controllers in portrait mode do the following:
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
Hope this helps!
update in iOS 8 xcode 6+
if let splitVCExists = self.splitViewController{
splitVCExists.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible
}
doc:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UISplitViewController_class/index.html#//apple_ref/occ/instp/UISplitViewController/preferredDisplayMode
One thing I did notice is that it will try to layout the splitviewcontroller based on the preferredDisplayMode as long as there is enough space. otherwise it will choose the display mode to fit the content right. I have used it and it lays the VCs out how I want in both portrait and landscape.
Take a look at this MGSplitViewController.
It is a customized split view controller with various useful enhancements. Certainly that you can show master view in portrait.
Have a look at APSplitViewController.
Sometime back I tried to achieve a similar thing. After trying Matt's code, and unsucessfully trying to create a category I realized that the only way to do this(in a way that Apple doesn't reject your app) is to use two custom views. Refer this question.
Related
I need a ridiculously simple thing - in one of the detail views of my UISplitViewController I have a button. Clicking it should show/open master view. That's it. Is it even possible?
P.S. it should work for all the layouts (iphone & ipad) and orientations. Even if the detail view part is a navigation and I am deep inside several pages, just want to open master view. You can assume iOS8+.
EDIT: Just to clarify what I meant by "deep inside several pages". Here is my storyboard screenshot:
Suppose I have a button in Detail Page 2 which should show the master. Setting the preferredDisplayMode works only for non-compact sizes, like iPad. On iPhone 6, for example, nothing changes after setting it. The back button points on Detail Page 1 so even swiping doesn't open master, it goes to previous page in detail navigation. I noticed that in this mode there is no split view at all, it is simulated by a navigation controller. So the questions is: is what I need possible at all or am I wrong trying to conceptually treat it as a "left drawer" which can be opened in any case and device?
At iOS8+ you can change visibility of the master view using
an animatable property preferredDisplayMode
#property (nonatomic) UISplitViewControllerDisplayMode preferredDisplayMode
Universal way to change visibility for all iOS versions is overriding delegate method
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
return _needsHideMasterView;
}
Here _needsHideMasterView is BOOL ivar which can be changed in your code to hide master view. For example,
- (void)hideMasterView:(BOOL)needsHide
{
_needsHideMasterView = needsHide;
[splitViewController.view setNeedsLayout];
[splitViewController.view layoutIfNeeded];
}
try setting preferredDisplayMode to UISplitViewControllerDisplayModeAllVisible like
self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
I have a screen that supports Device Orientation.
Everything is working fine except for the fact that when I rotate the device upside down (home button at top), the rotation doesn't work (it's stuck on the last landscape settings).
I know of several places needed be updated to support this:
In the VC itself, I added the methods:
In the Project Target, I updated as follow:
In the Storyboard VC Scene, I updated as follow:
What am I missing here?
You also have to allow rotating to all orientations in every parent view controller of the current main view controller. For example, if your view controller is in navigation controller, try subclassing it and override the same methods as in your example.
Edit: As #JordanC mentioned, since iOS 7 you can implement UINavigationControllerDelegate method to return custom supported orientations:
- (UIInterfaceOrientationMask)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController
As #eGanges mentioned the key point could be to subclass your UITabBarController (and override supportedInterfaceOrientations) if that is your initial view controller, in that case this is the only controller you should subclass (and of course you should add all the supported interface orientations to your app Info.plist file UISupportedInterfaceOrientations key)
Have you tested on real device?
anyway try this:
- (NSUInteger)supportedInterfaceOrientations {
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
}
I have setup a new iPad project to only support UIInterfaceOrientationLandscapeRight.
In my App Delegate I add a RootViewController to the window's rootViewController.
In this UIViewController (RootViewController) I have the following:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
I have also tried with:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
However, I am not able to get the correct dimensions for my app when I create and add subviews based on the dimensions of my view controller's view.
If I output self.view.frame for my view controller I get {{0, 0}, {768, 1024}}, but I would like {1024, 768} instead. If I can't when are the dimensions correct so I can create my views with them in mind?
Sorry if this has been asked a billion times, I've browsed lots of SO questions, but nothing has solved my issue.
I was running into the same issue, and what Ash Furrow said above seems to be correct; the orientation is set after viewDidLoad is called.
I was creating an iPad app that works in all orientations, but only the portrait orientations were getting set up correctly in my root UIViewController. In order to make the views layout correctly in landscape, I had to make sure the autoresizing masks on all my subviews was set to allow the view to adjust to landscape behind the scenes before being displayed to the user.
For example, I had a UIImageView that was the same size as the UIViewController's UIView. In order to get it to adjust correctly when rotating to landscape:
UIImageView *backgroundImageView = [[UIImageView alloc] initWithFrame:self.view.bounds];
backgroundImageView.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight);
[self.view addSubview:backgroundImageView];
Now the UIViewController can be configured in portrait orientation in the viewDidLoad method and rotate nicely to the portrait orientation before being displayed to the user.
EDIT:
Looks like the interface orientation is being set already in viewDidLoad
p (UIInterfaceOrientation)[self interfaceOrientation]
(UIInterfaceOrientation) $1 = UIInterfaceOrientationLandscapeRight
Here's my theory: interfaces on the iPad are, by default, 1024x768 if that have a status bar, which yours does. I believe that, even though the interface orientation is correct, it's not updating the view geometry until after viewDidLoad. I believe it has a very good reason for that.
If you look at the UIViewController Life Cycle docs, viewDidLoad is called as part of the set up of the view controller. After the view is loaded, willAnimateRotationToInterfaceOrientation: duration: is called to let your view controller know it's geometry is changing.
It's not so much an answer as an explanation. Hopefully this will help you architect a solution to get around this problem.
Begin answer that doesn't actually work:
In the info.plist for your project, open the "Supported Interface Orientations" option and delete the interface orientations you don't want to support. By default, all are supported:
That should clear it up.
I have a simple solution: the Apple default app templates work with XIBs for the main view controller. To solve your problem just open the main viewcontroller XIB and set orientation to "landscape".
As I usually don't use XIBs and create all UI elements programmatically. That's why I had the same problem in previous projects that really drove me crazy. I then solved it by hard-coding the frame width & height value - not the nice way.
I have a detail view where i load a help view with a button. I am using [UIViewController presentModalViewController:animated:].
In help view I am dismissing the view with a button. I am using [UIViewController dismissModalViewControllerAnimated:].
The problem is, after dismissing the help view, the detail view is in portrait mode, regardless of which orientation the device is in.
In all the view controllers, I have implemented shouldAutoRotateToInterfaceOrientation: and returned YES.
I think there are two selective solution
1.Officially available in iOS 5.0 and later, you can implement
/* call this method when your return value from shouldAutorotateToInterfaceOrientation: changes
if the current interface orientation does not match the current device orientation, a rotation may occur provided all relevant view controllers now return YES from shouldAutorotateToInterfaceOrientation: */
+ (void)attemptRotationToDeviceOrientation
See also : http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIViewController_Class/Reference/Reference.html
2.Use the trick from Canopus's Answer. It's pretty fine with iOS 4.3 and earlier BUT It's not guarantee solution that owner answer has warned you.
Hope it helps you!
I am working on an iPad app that seems like a natural fit for using a Master / Detail UISplitViewController for portrait and companion detail controller / popover for navigation.
But... I would sometimes like to use the full screen for the detail controller in portrait as well, turning the master into a popover here as well.
Is there any best practices or sample code explaining how this can be done?
Is a UISplitViewController the appropriate root view?
Any tips that focus on using iOS 5 and segues are especially appreciated. Thanks!
I have discovered that this is possible under iOS 5.
Use the following function in your UISplitViewController delegate:
- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
return YES;
}
Return YES even in landscape view, and the SplitViewController will function with a popover-style interface just like in portrait. If you want to revert back to the normal split view behavior, use this function to return NO in landscape.