【问题标题】:Xamarin Forms Forcing Page Specific Orientation on iOSXamarin Forms 在 iOS 上强制页面特定方向
【发布时间】:2023-01-30 13:53:25
【问题描述】:

我的 XF 应用程序中有几个页面需要纵向或横向,具体取决于它显示的内容。在 Android 上,这没有问题,在 iOS 16 发布之前,在 iOS 上也从来没有问题。

iOS 16 显然删除了使用 UIDevice UIInterfaceOrientation 方法的能力,该方法位于我的 AppDelegate 中,如下所示。

MessagingCenter.Subscribe<MainPage>(this, "SetLandscapeModeOff", sender =>
            {
                UIDevice.CurrentDevice.SetValueForKey(new NSNumber((int)UIInterfaceOrientation.Portrait), new NSString("orientation"));
            });

这工作得很好,我可以简单地在我试图以特定方向加载的页面上的 OnAppearing 方法中调用下面的代码。

MessagingCenter.Send(this, "SetLandscapeModeOff");

我在这里看到 1 或 2 篇帖子谈论新方法(还有很多关于 iOS 16 之前的方法)但它们都不够完整,不足以让我的技能水平的人理解如何实现它们。除了上面发布的内容外,我没有任何起点。

编辑

我根据回复尝试了以下解决方案。

界面:

using System;
using System.Collections.Generic;
using System.Text;

namespace MyApp
{
    public interface InterfaceOrientationService
    {
        void SetLandscape();
        void SetPortrait();
    }
}

AppDelegate.cs

[assembly: Xamarin.Forms.Dependency(typeof(MyApp.iOS.InterfaceOrientationServiceiOS))]

namespace MyApp.iOS
{
    public class InterfaceOrientationServiceiOS : InterfaceOrientationService
    {
        public InterfaceOrientationServiceiOS() { }

        public void SetLandscape()
        {
            if (UIDevice.CurrentDevice.CheckSystemVersion(16, 0))
            {
                var windowScene = (UIApplication.SharedApplication.ConnectedScenes.ToArray()[0] as UIWindowScene);

                if (windowScene != null)
                {
                    var nav = UIApplication.SharedApplication.KeyWindow?.RootViewController;
                    if (nav != null)
                    {
                        nav.SetNeedsUpdateOfSupportedInterfaceOrientations();
                        windowScene.RequestGeometryUpdate(
                            new UIWindowSceneGeometryPreferencesIOS(UIInterfaceOrientationMask.Portrait),
                            error => { }
                        );
                    }
                }
            }
            else
            {
                UIDevice.CurrentDevice.SetValueForKey(new NSNumber((int)UIInterfaceOrientation.Portrait), new NSString("orientation"));
            }
        }
        public void SetPortrait()
        {

            if (UIDevice.CurrentDevice.CheckSystemVersion(16, 0))
            {
                var windowScene = (UIApplication.SharedApplication.ConnectedScenes.ToArray()[0] as UIWindowScene);
                if (windowScene != null)
                {
                    var nav = UIApplication.SharedApplication.KeyWindow?.RootViewController;
                    if (nav != null)
                    {
                        nav.SetNeedsUpdateOfSupportedInterfaceOrientations();
                        windowScene.RequestGeometryUpdate(
                            new UIWindowSceneGeometryPreferencesIOS(UIInterfaceOrientationMask.Portrait),
                            error => { }
                        );
                    }
                }
            }
            else
            {
                UIDevice.CurrentDevice.SetValueForKey(new NSNumber((int)UIInterfaceOrientation.Portrait), new NSString("orientation"));
            }
        }
    }

    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            LoadApplication(new App());
            return base.FinishedLaunching(app, options);
        }
    }
}

我在需要横向的页面上的 OnAppearing 方法:

protected override void OnAppearing()
        {
            base.OnAppearing();
            DependencyService.Get <InterfaceOrientationService>().SetLandscape();
        }

【问题讨论】:

    标签: c# ios xamarin xamarin.forms xamarin.ios


    【解决方案1】:

    iOS16改变了换页的方式,可以使用DependencyService来实现,参考如下代码:

    在 Forms 中创建一个界面:

    public interface InterfaceOrientationService    {        
    void SetLandscape();        
    void SetPortrait();    
    }
    

    iOS 项目:

    using Foundation;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Text;
    using UIKit;
    using Xamarin.Forms;
    using XamarinFormsOne;
    using XamarinFormsOne.iOS;
    
    [assembly: Xamarin.Forms.Dependency(typeof(InterfaceOrientationServiceiOS))]   
    namespace XamarinFormsOne.iOS    
    {
        public class InterfaceOrientationServiceiOS: InterfaceOrientationService 
        {
            public InterfaceOrientationServiceiOS() { }
    
            public void SetLandscape() {
                if (UIDevice.CurrentDevice.CheckSystemVersion(16, 0))    
                {    
                    var windowScene = (UIApplication.SharedApplication.ConnectedScenes.ToArray()[0] as UIWindowScene);
    
                    if (windowScene != null)    
                    {    
                        var nav = UIApplication.SharedApplication.KeyWindow?.RootViewController;   
                        if (nav != null)  
                        {
                       nav.SetNeedsUpdateOfSupportedInterfaceOrientations();   
                            windowScene.RequestGeometryUpdate( 
                                new UIWindowSceneGeometryPreferencesIOS(UIInterfaceOrientationMask.Portrait),
                                error => { }    
                            );
                        }
                   }
                }
                else
                {
                    UIDevice.CurrentDevice.SetValueForKey(new NSNumber((int)UIInterfaceOrientation.Portrait), new NSString("orientation"));
                }
            }
                public void SetPortrait() {
        
                    if (UIDevice.CurrentDevice.CheckSystemVersion(16, 0))
                    {
                        var windowScene = (UIApplication.SharedApplication.ConnectedScenes.ToArray()[0] as UIWindowScene);
                        if (windowScene != null)
                        {
                            var nav = UIApplication.SharedApplication.KeyWindow?.RootViewController;
                            if (nav != null)
                            {
                           nav.SetNeedsUpdateOfSupportedInterfaceOrientations();
                                windowScene.RequestGeometryUpdate(
                                    new UIWindowSceneGeometryPreferencesIOS(UIInterfaceOrientationMask.Portrait),
                                    error => { }
                                );
                            }
                        }
                    }
                    else
                    {
                        UIDevice.CurrentDevice.SetValueForKey(new NSNumber((int)UIInterfaceOrientation.Portrait), new NSString("orientation"));
                    }
                }
            }
        }
    

    在 Xamarin.Forms 中调用接口:

    protected override void OnAppearing()        
    {            
    base.OnAppearing();            
    //SetLandscape            
    DependencyService.Get<InterfaceOrientationService().SetLandscape();            
    //SetPortrait            
    DependencyService.Get<InterfaceOrientationService>().SetPortrait();        
    }
    

    更新: 在 AppDelegate 中

    public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, [Transient] UIWindow forWindow)        
    {            
       var mainPage = Xamarin.Forms.Application.Current.MainPage;            
       if (mainPage.Navigation.NavigationStack.Last() is PageOne)            
    {            
     return UIInterfaceOrientationMask.Landscape;            
    }            
    return UIInterfaceOrientationMask.Portrait;       
    }
    

    【讨论】:

    • 非常感谢您的帮助!我没有收到任何错误,但似乎什么也没做。我将加载带有旋转锁定的页面,应用程序不会强制调用方向。我已经编辑了实现您的示例的原始帖子。是否有任何可见的错误?
    • @RileyHouston 我更新了我的答案,它在 ios16 中工作正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2022-12-15
    • 2014-09-13
    • 1970-01-01
    • 2019-03-26
    • 2017-07-22
    相关资源
    最近更新 更多