iOS上的Xamarin表单如何设置页面的屏幕方向?

iOS上的Xamarin表单如何设置页面的屏幕方向?,ios,xamarin.forms,Ios,Xamarin.forms,所以标题说明了一切。这一点我很关心iOS。我已经尝试为我的基本页面“LandscapeContentPage”使用一个定制的渲染器,希望它能被渲染成景观。我失败了 我试图使用我发现的一种方法,在ViewDid中,您显示了一个“假”UIViewController,它覆盖GetSupportedInterfaceOrientations以仅返回横向。这类工作。肉是这样的: var c = new LandscapeViewController(); c.View.BackgroundColor =

所以标题说明了一切。这一点我很关心iOS。我已经尝试为我的基本页面“LandscapeContentPage”使用一个定制的渲染器,希望它能被渲染成景观。我失败了

我试图使用我发现的一种方法,在ViewDid中,您显示了一个“假”UIViewController,它覆盖GetSupportedInterfaceOrientations以仅返回横向。这类工作。肉是这样的:

var c = new LandscapeViewController();
c.View.BackgroundColor = UIColor.Cyan;

await PresentViewControllerAsync(c, false);
await DismissViewControllerAsync(false);
如果我在关闭线处设置一个断点,我可以在模拟器中看到视图确实变为横向,模拟器窗口实际上会自行旋转。当我继续时,会抛出有关视图转换的错误,或者ViewDidDisplay会再次启动,并且原始页面以纵向显示

[assembly: ExportRenderer(typeof(MainPage), typeof(MainPagePageRenderer))]
namespace App2.iOS
{
    public class MainPagePageRenderer : PageRenderer
    {
        public override void ViewWillDisappear(bool animated)
        {
            base.ViewWillDisappear(animated);
            UIDevice.CurrentDevice.SetValueForKey(NSNumber.FromNInt((int)(UIInterfaceOrientation.LandscapeLeft)), new NSString("orientation"));
        }
    }
}
所以,在这一点上我多少有些迷茫。我尝试过很多不同的事情,但都没有成功。我不明白为什么没有现成的机制。如果没有方向处理,这样一个昂贵的工具集/框架似乎是不完整的


谢谢。

如果您只想强制一个页面或整个应用程序的横向方向,您就不必写了?

我想您已经知道,您可以在项目设置中强制整个应用程序的方向(例如,仅横向方向)?

我为此使用了依赖项服务

接口 从窗体调用接口 Android实现 编辑-根据请求添加基本依赖项实现

BaseDependency实现
如果要为整个应用程序设置方向,可以在应用程序设置/清单文件中完成

Chad Bonthuys的方法就像一种魅力。我有两个小补充

Android:如果您旋转并离开视图,其他视图现在也将处于请求的方向。就打电话

GetActivity().RequestedOrientation = ScreenOrientation.Unspecified;
离开时。这将允许其他视图再次旋转

iOS:视图将被旋转,但用户仍然可以将其旋转回来。如果覆盖了

GetSupportedInterfaceOrientations()

AppDelegate.cs

public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, [Transient] 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 SecondPage ||
                    (mainPage is NavigationPage && ((NavigationPage)mainPage).CurrentPage is SecondPage) ||
                    (mainPage.Navigation != null && mainPage.Navigation.ModalStack.LastOrDefault() is SecondPage))
            {
                return UIInterfaceOrientationMask.Landscape;
            }

            return UIInterfaceOrientationMask.Portrait;
        }

只需将您的视图替换为您想要锁定的内容页面即可

以下解决方案不需要依赖项服务

假设我们想要有三个页面,而第二个页面只需要横向,下面的代码对我有用

将以下方法添加到AppDelegate.cs

public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, [Transient] 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 SecondPage ||
                    (mainPage is NavigationPage && ((NavigationPage)mainPage).CurrentPage is SecondPage) ||
                    (mainPage.Navigation != null && mainPage.Navigation.ModalStack.LastOrDefault() is SecondPage))
            {
                return UIInterfaceOrientationMask.Landscape;
            }

            return UIInterfaceOrientationMask.Portrait;
        }
添加自定义渲染器以更改方向

[assembly: ExportRenderer(typeof(MainPage), typeof(MainPagePageRenderer))]
namespace App2.iOS
{
    public class MainPagePageRenderer : PageRenderer
    {
        public override void ViewWillDisappear(bool animated)
        {
            base.ViewWillDisappear(animated);
            UIDevice.CurrentDevice.SetValueForKey(NSNumber.FromNInt((int)(UIInterfaceOrientation.LandscapeLeft)), new NSString("orientation"));
        }
    }
}
在这里,我们有三个网页主页,第二页和第三页在应用程序中,我们正试图修复横向方向的第二页。我们需要为主页创建一个自定义的渲染器,因为我们需要在转到第二页时更改方向。我们在AppDelegate for SecondPage中修复了方向,因此即使我们旋转手机,它也不会改变方向

现在,主页和第三页的纵向方向被锁定,第二页的横向方向被锁定

我们可能需要为每个页面创建尽可能多的自定义渲染器来修复方向

[assembly: ExportRenderer(typeof(MainPage), typeof(MainPagePageRenderer))]
namespace App2.iOS
{
    public class MainPagePageRenderer : PageRenderer
    {
        public override void ViewWillDisappear(bool animated)
        {
            base.ViewWillDisappear(animated);
            UIDevice.CurrentDevice.SetValueForKey(NSNumber.FromNInt((int)(UIInterfaceOrientation.LandscapeLeft)), new NSString("orientation"));
        }
    }
}

谢谢。

是的,这就是为什么标题上写着“for Page”。所以,是的,它只针对一个页面,而不是整个应用程序。似乎很难相信,没有其他人在他们的应用程序中有这样的要求。我也有这样的要求:-)我想在手机上(仅)以纵向显示特定的搜索页面(因为它在横向手机上不可用)。因此,我向Jason提出了一个“愿望”,即为page对象实现一个新属性,该属性允许设置单个页面的方向。但是离圣诞节还有很长时间…:-)@杰米奇有什么办法吗?@FredyWenger有什么办法吗?@Johan我还没找到。无论如何,我现在几乎搁置了我项目的那一部分。我倾向于不使用XF,而只使用传统的Xamarin应用程序,因为我需要对UI进行更多控制。谢谢,这看起来很有希望。我会试试看。而且时机也很好,因为我刚刚开始一个新的表单项目,可以使用这种控制。很棒的东西,这是我的荣幸,如果你遇到任何问题,请告诉我,什么是BaseDependencyImplementation?我的错误很抱歉疏忽了,它是我继承的一个额外接口,用于获取活动上下文,因为您需要知道在哪个活动上执行定向。我在回答中添加了这个作为编辑。今天我尝试了这个,但我仍然能够在iOS中进入横向模式。这太神奇了——经过大量的搜索和实验,这是我发现的唯一能够在应用程序中使用ImagePicker的方法,应该是横向的!将代码放在第二页的
视图将出现
,而不是第三页的
视图将消失
,不是更简单吗?这似乎更简单,因为您控制的是第二页。你这样做有什么好处吗?
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations (UIApplication application, [Transient] UIWindow forWindow)
{
    if (Xamarin.Forms.Application.Current == null || Xamarin.Forms.Application.Current.MainPage == null)
    {
        return UIInterfaceOrientationMask.All;
    }

    var mainPage = Xamarin.Forms.Application.Current.MainPage;

    if (mainPage is YOUR_VIEW||
            (mainPage is NavigationPage && ((NavigationPage)mainPage).CurrentPage is YOUR_VIEW) ||
            (mainPage.Navigation != null && mainPage.Navigation.ModalStack.LastOrDefault () is YOUR_VIEW))
    {
        return UIInterfaceOrientationMask.Landscape;
    }

    return UIInterfaceOrientationMask.All;
}
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, [Transient] 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 SecondPage ||
                    (mainPage is NavigationPage && ((NavigationPage)mainPage).CurrentPage is SecondPage) ||
                    (mainPage.Navigation != null && mainPage.Navigation.ModalStack.LastOrDefault() is SecondPage))
            {
                return UIInterfaceOrientationMask.Landscape;
            }

            return UIInterfaceOrientationMask.Portrait;
        }
[assembly: ExportRenderer(typeof(MainPage), typeof(MainPagePageRenderer))]
namespace App2.iOS
{
    public class MainPagePageRenderer : PageRenderer
    {
        public override void ViewWillDisappear(bool animated)
        {
            base.ViewWillDisappear(animated);
            UIDevice.CurrentDevice.SetValueForKey(NSNumber.FromNInt((int)(UIInterfaceOrientation.LandscapeLeft)), new NSString("orientation"));
        }
    }
}