How to set ContentPage orientation in Xamarin.Forms
Hate to say this but this can only be done using custom renderers or a platform-specific code
In android, you can set the RequestedOrientation property of the MainActivity to ScreenOrientation.Landscape
.
In iOS, you can override GetSupportedInterfaceOrientations
in the AppDelegate
class to return one of the UIInterfaceOrientationMask
values when Xamarin.Forms.Application.Current.MainPage
is the ContentPage
that you are intereted in.
Android
[assembly: Xamarin.Forms.ExportRenderer(typeof(MyCustomContentPage), typeof(CustomContentPageRenderer))]
public class CustomContentPageRenderer : Xamarin.Forms.Platform.Android.PageRenderer
{
private ScreenOrientation _previousOrientation = ScreenOrientation.Unspecified;
protected override void OnWindowVisibilityChanged(ViewStates visibility)
{
base.OnWindowVisibilityChanged(visibility);
var activity = (Activity)Context;
if (visibility == ViewStates.Gone)
{
// Revert to previous orientation
activity.RequestedOrientation = _previousOrientation == ScreenOrientation.Unspecified ? ScreenOrientation.Portrait : _previousOrientation;
}
else if (visibility == ViewStates.Visible)
{
if (_previousOrientation == ScreenOrientation.Unspecified)
{
_previousOrientation = activity.RequestedOrientation;
}
activity.RequestedOrientation = ScreenOrientation.Landscape;
}
}
}
iOS
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, UIWindow forWindow)
{
if (Xamarin.Forms.Application.Current == null || Xamarin.Forms.Application.Current.MainPage == null)
{
return UIInterfaceOrientationMask.Portrait;
}
var mainPage = Xamarin.Forms.Application.Current.MainPage;
if (mainPage is MyCustomContentPage ||
(mainPage is NavigationPage && ((NavigationPage)mainPage).CurrentPage is MyCustomContentPage) ||
(mainPage.Navigation != null && mainPage.Navigation.ModalStack.LastOrDefault() is MyCustomContentPage))
{
return UIInterfaceOrientationMask.Landscape;
}
return UIInterfaceOrientationMask.Portrait;
}
}
This can also be done by sending the message from Form project to host project using MessagingCenter class. without using the custom renderer or dependency service as follows,
public partial class ThirdPage : ContentPage
{
protected override void OnAppearing()
{
base.OnAppearing();
MessagingCenter.Send(this, "allowLandScapePortrait");
}
//during page close setting back to portrait
protected override void OnDisappearing()
{
base.OnDisappearing();
MessagingCenter.Send(this, "preventLandScape");
}
}
Change in mainactivity to receive the message and set RequestedOrientation
[Activity(Label = "Main", ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation,ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
//allowing the device to change the screen orientation based on the rotation
MessagingCenter.Subscribe<ThirdPage>(this, "allowLandScapePortrait", sender =>
{
RequestedOrientation = ScreenOrientation.Unspecified;
});
//during page close setting back to portrait
MessagingCenter.Subscribe<ThirdPage>(this, "preventLandScape", sender =>
{
RequestedOrientation = ScreenOrientation.Portrait;
});
}
Check for more in my blog post : http://www.appliedcodelog.com/2017/05/force-landscape-or-portrait-for-single.html