iPad FormSheet/PageSheet modal view, when rotated fill entire screen.T - ipad

I have a iPad application, which has a UITabBarController as the root controller. From one of the tabs, I have a UIToolBar which contains a UIBarButtonItem, when clicked launches a Modal View.
The modal view appears in the correct size when first launched (in both landscape and portrait) however if you rotate the device, the modal view will then expand to fill the screen - regardless of how much you rotate the device from that point onwards.
I'm launching the modal view from the tab bar and I've set the ModalPresentationStyle in the view to be presented.
This affects the ModalView regardless of whether I set it to FormSheet or PageSheet.
Has anyone experienced similar behaviour, if so, how did you solve it?
Many thanks
EDIT
I've also noticed that since 4.2 when using a Modal Style Page/FormSheet that the view behind the Modal View isn't dimmed out anymore - am I presenting the view wrong or is this just standard on 4.2?
EDIT 2
Code:
In my default UIViewController I simply present the Modal view as follows:
void HandleNewMsgButtonTouch(object sender, EventArgs e)
{
PresentModalViewController(new ComposeMsgView(), true);
}
In the modal view itself, I've specified in the LoadView override:
public override void LoadView()
{
base.LoadView ();
...
// initialser code related to the view
...
View.AutoresizingMask = UIViewAutoresizing.None;
ModalPresentationStyle = UIModalPresentationStyle.PageSheet;
ModalTransitionStyle = UIModalTransitionStyle.CrossDissolve;
}
I've overriden the ShouldAutoRotateToInterfaceOrientation to always return true as well.
Regardless of whether I use Formsheet / Pagesheet, they both appear the correct width when first launched (whether in landscape or portrait - I'm aware PageSheet will fill the portrait view) however on rotation, the modal view will then fill the screen (as if I had presented the ModalView with FullScreen).

As stated in the comment, try this:
void HandleNewMsgButtonTouch(object sender, EventArgs e)
{
UIViewController oController = new ComposeMsgView();
oController.ModalPresentationStyle = UIModalPresentationStyle.PageSheet;
PresentModalViewController(oController, true);
}
LoadView() is too late to set the properties.
Previous content:
Please post some code. The view is definitely dimmed, also in 4.2.
I assume that you are setting the presentation style on the wrong controller, because "PageSheet" is transformed to fullscreen when in portrait mode.
You have to set the presentation style on the controller you want to show in the moda view and not on the one which IS showing. So if your controller to show is "oToShow" and the one you are showing from is "oCurrent", you would have to set the style for "oToShow".
Try setting it to FormSheet which will always be on top and never goes fullscreen.
René

you can work around it by using a different style, like
UIModalPresentationFullScreen: This is the default style and as the name suggests causes the modal view to be presented full screen exactly as with the iPhone
UIModalPresentationPageSheet: The modal view occupies the full screen height but the width is set to the width of the screen in portrait mode. This means that when the device is in portrait mode it still occupies the full screen. However in landscape mode it leaves some of the underlying master view to still be visible, but dimmed as the user cannot interact with the uncovered master view controller.
UIModalPresentationFormSheet: Both the width and height of the modal view are set to be smaller than the screen size. The modal view is centered on the screen and the uncovered areas of the master view controller are dimmed to prevent user interaction. If the modal view makes used of the keyboard the modal view is moved upwards to make room.
UIModalPresentationCurrentContext: The modal view is displayed using the same style as the parent master view controller.
also remember to adjust size and position because it would otherwise always be shown in PageFormSheet's default size.
hope this helps
Alex

View.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;

Related

How to know when a view controller is presented using a 'form sheet' modal presentation style

When presenting a view controller modally, we can set the modalPresentationStyle to .formSheet:
In a horizontally regular environment, the view controller is sized so that its content area is smaller than the screen size and a dimming view is placed underneath the content...
In a horizontally compact environment, this option behaves the same as UIModalPresentationStyle.fullScreen.
I would like my modally presented view controller to update its layout based on whether it is being presented in this reduced-width form style, or as a full screen presentation. But The modal's horizontal size class is always compact, even when full screen on an iPad Pro in landscape.
The horizontal size class of the presenting view controller can tell me what I need to know (as Apple's docs mention above). But that means observing changes in traitCollection in every view controller than can present my modal, just so they pass them on to the modal view controller.
Is there some way for the modal view controller itself to know which style it is using, and be alerted when it changes so it can respond?
One slightly-gross way to at least know the applications size class:
UIApplication.shared.delegate?.window??.rootViewController?.traitCollection

Showing a view controller in Modal Dialog programmatically is appearing as full screen

I have 2 swift View controllers and i want the second one to show as a modal dialog ( like bootstrap modal in web) on top of the first view when i click a button. I used the below code to achieve this, but the second view controller is still appearing full screen!
This is the code i execute to show the second view controller
var addCtrl = self.storyboard?.instantiateViewControllerWithIdentifier("mCtrl")
as? ModalContentViewController
addCtrl!.modalPresentationStyle = .Popover
presentViewController(addCtrl!, animated: true, completion: nil)
mCtrl is the storyboard id of the second viewcontroller.
What am i missing here ? My objective is to show the second view controller in a modal dialog.
EDIT : I am trying to make it work on iPhone.
You don't mention whether you're on iPhone or iPad. Assuming you're on iPad, if you want something like a modal dialog, then you'd be better off using UIModalPresentationFormSheet, which in swift I guess would be .FormSheet. If you really want to use a popover, you'll need to tell it where to popover from. You'd do this by setting the sourceView and sourceRect, or the barButtonItem properties of the controller's popoverPresentationController, after the call to presentViewController.
If you're on the iPhone, you'd still get a full screen presentation in both these cases. However, you can get the iPad style presentations if you set the presenting controller to be the presented controller's presentationController's delegate, before the call to presentViewController, and then implement adaptivePresentationStyleForPresentationController:traitCollection to always return UIModalPresentationNone.
Based on Apple's documentation, you try setting preferredContentSize explicitly for the popover view. Something like
addCtrl!.preferredContentSize = CGSizeMake(200, 100)
The value in this property is used primarily when displaying the view controller’s content in a popover but may also be used in other situations. Changing the value of this property while the view controller is being displayed in a popover animates the size change; however, the change is not animated if you specify a width or height of 0.0.

Presented Modal view controller not displayed like a Form

I am new to iOS programming. I am learning How to use Modal in iOS. I have a button. Inside button tap handler. I want to show a UIViewController like Modal form.
Here is my code:
#IBAction func userEditClick(sender: AnyObject) {
let userCtrl = UserEditViewController(nibName: "UserEditViewController", bundle: nil)
userCtrl.callback = self
userCtrl.modalPresentationStyle = UIModalPresentationStyle.FormSheet
//userCtrl.preferredContentSize = CGSizeMake(400, 800);
self.presentViewController(userCtrl, animated: true, completion: nil)
}
UserEditViewController is showed BUT the screen look like Normal UIViewController -> This is not what I expected ---> Form Modal
Thanks!
You just call presentViewController. That will do the job. The default animation of the presentViewController is modal. Also when you see the documentation it says that the setting will adapt to the environment. So I think when you are on the iPhone the FormSheet have to cover the whole screen. I think you may stick to the apple's default behavior.
In a horizontally regular environment, a presentation style that
displays the content centered in the screen. The width and height of
the content area are smaller than the screen size and a dimming view
is placed underneath the content. If the device is in a landscape
orientation and the keyboard is visible, the position of the view is
adjusted upward so that the view remains visible. All uncovered areas
are dimmed to prevent the user from interacting with them.
In a horizontally compact environment, this option behaves the same as
UIModalPresentationFullScreen.
Available in iOS 3.2 and later.
Ok so if you want to show like form sheet on the iPhone or iPad you need to calculate the size and show them with the animation you make and load it on your view controller.
Or you can check this repository https://github.com/m1entus/MZFormSheetController
They did the hard parts :)

Unable to set a dim background to a modal view

I'm developing an app targeting iOS 7 and above. I'd like to present modally a view with a dim background that partially shows the previous view below. I've read several posts dealing with this scenario, and I did:
Created a view controller scene in storyboard and set a modal segue to navigate to it.
Set the Presentation value of that modal segue to Current Context.
Set the view controller's view background color to clear color.
Added a full-screen view above the parent view, with black color background and 50% opacity.
Transition to the modal view is default and animated. While the animation, I see the view being presented as semi-transparent, but once the transition animation ends and view finally occupies the full screen, the view becomes opaque black.
What I'm doing wrong? How could I solve this?
As #luk2302 said, when you present a view controller modally, iOS removes the view controllers underneath it from the view hierarchy so is nothing underneath it except the app window, which is black. Anyway, iOS 7 has a new modal presentation style, UIModalPresentationCustom, that forces iOS not to remove the views underneath the presented view controller. But you must provide your own transition delegate to handle the presentation and dismiss animations
Check this link how to implement custom transition delegate.

UI for dismissing View Controller presented by UIPopoverPresentationController regardless of Size Class

I have a Universal app, Xcode 7 Beta, targeting iOS 8.
I am presenting a View Controller using UIPopoverPresentationController.
When presented in any Regular Size Class (e.g. Full screen iPad in any orientation), the View Controller appears as a popover, at the size I have set in the preferredContentSize property. A tap outside the bounds of the View Controller will dismiss the popover.
When presented in Compact Width Size Class (e.g. any iPhone in portrait orientation), the "popover" will become a full screen view, sliding in from the bottom to the top.
The Problem
While an iPad popover has built-in dismissal behaviour (i.e. tap outside of the popover), "popovers" presented full-screen do not. And thus need some UI in order to provide the user with a way to dismiss the popover.
Question
What is the best (recommended?) way to present a UI such that it only appears for the Compact Width Size Class, in order to give the user an option to dismiss the (full screen) "popover" View Controller?
Discussion
One approach I have seen is to embed the [View Controller to be presented] in a UINavigationController. A bar button is added to the Navigation Bar, though whose outlet we can tell the presenting View Controller to dismiss the presentation.
However, not only does this require an extra, unwanted hierarchy for the otherwise simple presented View Controller on the iPad, but it requires environment checking (idiom? size class?) in viewDidLoad to programmatically hide the NavigationBar if a Regular Width Size Class (e.g. iPad) is being used. This strikes me as... fragile.
Another option is to do the above, but use Size Classes within Interface Builder to Install/Uninstall the Navigation elements, non-programmatically.
Thoughts?
Related link, discussing the detection of popover mode
Look at Interface Builder, you can make available any view depending on the Size Class currently running on your app :) If i remember well (because I can't check for now as I'm in a bus) you can specify a view to be available in a specific Size Class in the Property Inspector tab of the selected view. That way you just have to add a button or a navigation bar with items in your view and make it available only for Compact widths :) I'll check more specificaly today to take you some screenshots :)

Resources