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