Actually, i want to create an iPad app who will looks like smilar to iPad Settings screen in portrait mode. Where primary view controller has all the list of litems and when i clicked on any item , it will show the detail on particular item.
I tried to create split view controller app but it only shows both controllers in landscape mode.
Thanks in advance.
//This method is in UISplitViewControllerDelegate , first set delegate for your splitviewcontroller object and implement following method in that delegate, i hope it will work for you
- (BOOL)splitViewController: (UISplitViewController*)svc shouldHideViewController:(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
return NO;
}
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'm currently developing for iOS 8 and developing an app with the new adaptive framework. The weird part is when I use the the splitviewcontroller on iPhone with this storyboard configuration the app does not start with the master view controller but the detail controller. Is this a bug and how could I be able to fix it?
This does only happen if the navigationController that envelops the master exists, if I remove it the app starts with master controller.
The thing to realise is that when a split view controller app starts on iPhone 6 Plus in portrait, it is just showing the split view controller in its collapsed state. By default this has the detailed view pushed above any view controllers in the primary navigation controller.
The way to stop a particular view (such as a blank detail view you may initially show on iPad) from being displayed at launch, or indeed after any rotation to portrait, is to handle this in the splitViewController:collapseSecondaryViewController:ontoPrimaryViewController: delegate method. This will be called at launch on iPhone or iPhone 6 Plus in portrait before presentation.
Doing this, you shouldn't need to have any device specific code.
In its simplest form this would look like:
- (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController
{
if ([secondaryViewController isKindOfClass:[BlankViewController class]])
{
// If our secondary controller is blank, do the collapse ourself by doing nothing.
return YES;
}
// Otherwise, use the default behaviour.
return NO;
}
Obviously, you then need to do the reverse in splitViewController:separateSecondaryViewControllerFromPrimaryViewController: to create and return a BlankViewController for the new secondary view if you don't want your topmost primary view controller to end up on the detail side after split view expands.
Be aware mixing your own implementation with Apple's in these methods, they do some crazy stuff like embedding UINavigationControllers inside other UINavigationControllers. See my related answer here: https://stackoverflow.com/a/26090823/4089333
UPDATE: Michael Wybrow's answer is better.
I ran into this issue and found this to work:
splitViewController.viewControllers =
UIScreen.mainScreen.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact ?
#[ leftNavigationController ] :
#[ leftNavigationController, rightNavigationController ]
;
And in the splitview delegate:
- (UIViewController *)primaryViewControllerForCollapsingSplitViewController:(UISplitViewController *)splitViewController
{
return leftNavigationController;
}
- (UIViewController *)primaryViewControllerForExpandingSplitViewController:(UISplitViewController *)splitViewController
{
return leftNavigationController;
}
- (UIViewController *)splitViewController:(UISplitViewController *)splitViewController separateSecondaryViewControllerFromPrimaryViewController:(UIViewController *)primaryViewController
{
return rightNavigationController;
}
It's horrible, I know. But it does the right thing, especially on the iPhone 6 Plus, which is very tricky to get right.
UPDATE: Michael Wybrow's answer is better.
It is probably an error due to the SplitViewController being just exclusive to the iPad. Also when you have it in the portrait orientation, it displays the detail view by default and the master view will show as a bar. You will have to change it using some method like splitViewController:shouldHideViewController:inOrientation
Here is an Apple document referring your problem
https://developer.apple.com/library/ios/documentation/uikit/reference/UISplitViewController_class/Reference/Reference.html
I hope this helps!
I have a homeViewController (should always be in portrait mode) , which has four buttons to be redirected to a tar bar controller, which has four different viewController (first, second, third, fourth).
We want to have firstViewController and fourthViewController in portrait mode always. And secondViewController and thirdViewController in landscape mode always, also when we will go back to homeViewController form any of these viewControllers the homeViewController should always be in portrait mode.
You can use the -shouldAutrotate - Method of the ViewControllers to make sure they dont rotate when the device does. Just return NO, and the VC will always be displayed like your xib-file or storyboard specifies.
Heres the docs:
https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/doc/uid/TP40006926-CH3-SW124
and heres an example:
-(BOOL)shouldAutorotate{
return NO;
}
EDIT: In Response to your coment:
UITabBarControllers wont forward the shouldAutorotate - Value to the ChildViewControllers. (As a sidenote, neither will a NavigationController). Your best bet is to subclass The TabBarController. Heres a link to a Stackoverflow-Post describing this. Have fun.
IO6 doesn't call -(BOOL)shouldAutorotate
Okay so I'm new to the whole storyboarding functionality in iOS 5. I have an application for iPad that is locked into landscape mode. Just to test out the seguing functionality, I took my initial view controller, added a button, dragged a new view controller next to it (which shows up in landscape mode visually on the designer), then tied the segue action to the button. I left everything defaulted.
Hitting the button on the initial view controller initiates the segue with no problems, and the new screen loads up, but ALWAYS in portrait mode.
What am I doing wrong? Is there some toggle I'm missing? I figured that if via the summary of the project, I have it locked into landscape left and right, it would assume I always want that orientation unless otherwise noted? Please help!
I had the same problem and managed it by adding a new own ViewControllerClass to the new scene.
Within the following auto created method, you can restrict the orientation to landscape only. This is also helpful for the Main Scene ViewController:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (UIInterfaceOrientationIsLandscape(interfaceOrientation));
}
Cheers,
Daniel
I have an application for iPad that is locked into landscape mode.
How are you locking it app-wide? Just want to make sure you are doing it correctly.
To lock an orientation in Storyboard mode, select your ViewController and on the Attributes inspector change the Orientation from Inferred to whatever you want it to be locked to.
What have you put in the orientation delegate method?
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
In the properties file for your app (YOURAPPNAME-Info.plist), located in the "supporting files" group, there is an array called "Supported interface orientations". Remove both landscape values from the array and your app will be locked in portrait orientation.
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.