Allow users to further customize modal behavior and simplify down the interaction with modal pages. The majority of the time pages that are treated as Modal are only used modally so it makes more sense to just describe the modal behavior as a permanent attribute of the page itself.
This is different than PopOvers (https://github.com/xamarin/Xamarin.Forms/issues/1778). You can have only one pop over and pop overs map more to alerts/dialogs associated to visible content. The difference can also be seen at the platform level with how iOS has a specific UIPopOverController vs setting the Modal Behavior on a UIViewController itself. You can push as many Modal Pages as you want onto a stack but there can be only one PopOver.
API
Supporting APIs
ModalBehavior
Users will set this on a Page to define how this page will be displayed modally. With Shell this will allow users to pass in parameters on the query string to influence the modal behavior on a page. They could even bind to the IsEnabled property on ModalBehavior which will cause it to not be pushed modally
public class ModalBehavior
{
bool IsEnabled //v1
bool Animate //v1
DismissOptions Dismiss //v2
DisplayOptions Display //v2
}
Properties
API
Description
IsEnabled
If this is set to false than the page will just push onto the current stack intead of being pushed modally. Changing this value while the page is already displayed will have no real time effect
Dismiss
Indicate what ways you can dismiss the modal. Default will use a combination of platform defaults and display to determine default
Display
Default: Use platform default. FullScreen: Cover the entire screen. FitToDevice: Size the content based on the size of the device. Phones will be FullScreen whereas larger tablets will show content in a window
Animate
Default: true. Whether to animate or not
public enum DisplayOptions
Default,
FitToDevice,
}
// This will push the page modally
Navigation.PushAsync(new MainPage())
// This will push the page non modally
Shell.Current.GotoAsync("MainPage?IsModal=false")
// This will push the page modally
Shell.Current.GotoAsync("MainPage?IsModal=true")
Implementation Details
The first version can just take ModalBehavior and implement the Animated/IsEnabled properties. This will allow for better Shell navigation integration and simplify the overall navigation API
Android
Androids Modal implementation should be switched to using a DialogFragment. Currently Modal pages on Android just get added to the root ViewGroup and are animated over the top of the current view but both views are techinically still on the screen. This implementation has caused accessibility issues and generally just seems counter to the platform. When a Modal page is pushed the container can use a ViewPager or just FragmentTransations to swap out content. Both of these can be animated at the Android level.
This does need to be spiked a bit more to see if all current Modal behavior can be replicated if we use DialogFragments
FitToDevice on Android will use a MinHeight/MinWidth that will match how the FormSheet sizing works on iOS
Modal Spec
Allow users to further customize modal behavior and simplify down the interaction with modal pages. The majority of the time pages that are treated as Modal are only used modally so it makes more sense to just describe the modal behavior as a permanent attribute of the page itself.
This is different than PopOvers (https://github.com/xamarin/Xamarin.Forms/issues/1778). You can have only one pop over and pop overs map more to alerts/dialogs associated to visible content. The difference can also be seen at the platform level with how iOS has a specific UIPopOverController vs setting the Modal Behavior on a UIViewController itself. You can push as many Modal Pages as you want onto a stack but there can be only one PopOver.
API
Supporting APIs
ModalBehavior
Users will set this on a Page to define how this page will be displayed modally. With Shell this will allow users to pass in parameters on the query string to influence the modal behavior on a page. They could even bind to the IsEnabled property on ModalBehavior which will cause it to not be pushed modally
Properties
When Display and Dismiss are set to default how they act will be determined by the platform and device types.
Examples
Implementation Details
Android
Androids Modal implementation should be switched to using a DialogFragment. Currently Modal pages on Android just get added to the root ViewGroup and are animated over the top of the current view but both views are techinically still on the screen. This implementation has caused accessibility issues and generally just seems counter to the platform. When a Modal page is pushed the container can use a ViewPager or just FragmentTransations to swap out content. Both of these can be animated at the Android level.
iOS
FitToDevice on iOS will map to FormSheet
UWP