Delphi / Firemonkey在运行时更改iOS屏幕旋转

彼得·约翰·詹森

基本上我想要实现的是,当用户位于应用程序的某个部分以根据需要更改屏幕旋转时,我已经在Andriod上使用了它,我看不到为什么它不适用于iOS

procedure TForm1.Button1Click(Sender: TObject);
var
  ScreenService: IFMXScreenService;
  OrientSet: TScreenOrientations;
begin
    if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(ScreenService)) 
    then
    begin
        OrientSet := [TScreenOrientation.soLandscape];//<- Break point set here and line is executed
        ScreenService.SetScreenOrientation(OrientSet);
    end;
end;

取自此处:如何使用delphi xe5 Firemonkey中的android开发防止屏幕旋转

ScreenService.SetScreenOrientation将被执行,并且不会引发异常,但是方向不会更改,我还在“项目”>“选项”>“应用程序”>“方向”中设置了“启用自定义方向”,但这也没有任何效果。

对我来说奇怪的是,如果不支持它,那不应该

if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(ScreenService)) 

返回假?甚至不进入开始

我将其设置为仅横向放置后,添加了一个测试按钮来检查屏幕方向

if TPlatformServices.Current.SupportsPlatformService(IFMXScreenService, IInterface(ScreenService)) 
then
begin
    case ScreenService.GetScreenOrientation of
        TScreenOrientation.Portrait: ShowMessage('Portrait');
        TScreenOrientation.Landscape: ShowMessage('landscape');
        TScreenOrientation.InvertedPortrait: ShowMessage('Inverted-Portrait');
        TScreenOrientation.InvertedLandscape: ShowMessage('Inverted-Landscape');
        else ShowMessage('not set');
    end;
end;

如果将其设置为“风景”后处于“人像”状态,它仍会显示“人像”

更新1:我也尝试过更改

OrientSet := [TScreenOrientation.soLandscape] // <- Deprecated

OrientSet := [TScreenOrientation.Landscape]

但是行为还是一样

彼得·约翰·詹森

好的,这次轮换让我深入研究了iOS API,以了解iOS如何管理方向。

由于您无法在iOS中的iOS中伪造旋转或强制设备达到特定的设备方向,因此您需要考虑很多方向

  • 设备方向
  • 状态栏方向
  • UIViewcontroller方向

不能强制或更改设备方向,这将始终显示设备当前所处的方向。

但是,状态栏方向始终具有setStatusBarOrientation您可以调用过程并精简所需的方向,但这被标记为已弃用,因此不起作用,但是当我调用该函数时没有得到外部异常,这说明它仍然在那里,只是没有用。

然后我读到这个:

setStatusBarOrientation:animated:方法未完全弃用。现在,仅当最顶部的全屏视图控制器的supportedInterfaceOrientations方法返回0时,它才有效

然后我决定尝试这个

Application.FormFactor.Orientations := []; //the supportedInterfaceOrientations returns 0
App := TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication);
win := TUIWindow.Wrap(App.windows.objectAtIndex(0));
App.setStatusBarOrientation(UIInterfaceOrientationLandscapeLeft);

它可以使状态栏的方向发生变化,但是如上所述,该协议已被弃用,因此在某个阶段它可能/将消失并且将不再起作用。

但这仅改变了状态栏和所有警报视图等的旋转,但是在我想更改为横向的情况下,rootviewcontroller中的实际内容仍在Portrait中。

然后,如果我要在Delphi中进行操作,我将转至Application-> Orientation->启用自定义旋转并仅显示横向,然后该应用将仅以横向显示,并且这样做非常完美,因为在创建表单然后将rootViewcontroller设置为supportedInterface时返回的方向仅为风景,而Viewcontroller转到风景。

因为当您的设备更改设备方向时,将根据Viewcontroller支持的界面方向评估方向,因此,如果不支持该方向,则不会旋转。

但是,当分配了新的rootviewcontroller时,必须更新GUI以在Viewcontrollers支持的方向上显示,牢记这一点,这是我的修正/技巧,可以将您的App的方向更改为所需的方向。

TL; DR

Uses: iOSapi.UIKit; 

procedure ChangeiOSorientation(toOrientation: UIInterfaceOrientation;
possibleOrientations: TScreenOrientations);
var
    win : UIWindow;
    App : UIApplication;
    viewController : UIViewController;
    oucon: UIViewController;
begin
    Application.FormFactor.Orientations := []; //Change supported orientations
    App := TUIApplication.Wrap(TUIApplication.OCClass.sharedApplication);
    win := TUIWindow.Wrap(App.windows.objectAtIndex(0)); //The first Windows is always the main Window

    App.setStatusBarOrientation(toOrientation);
    {After you have changed your statusbar orientation set the
    Supported orientation/orientations to whatever you need}
    Application.FormFactor.Orientations := possibleOrientations;
    viewController := TUIViewController.Wrap(TUIViewController.alloc.init);//dummy ViewController
    oucon := TUIViewController.Wrap(TUIViewController.alloc.init);
    {Now we are creating a new Viewcontroller now when it is created
     it will have to check what is the supported orientations}
    oucon := win.rootViewController;//we store all our current content to the new ViewController
    Win.setRootViewController(viewController);
    Win.makeKeyAndVisible;// We display the Dummy viewcontroller

    win.setRootViewController(oucon);
    win.makeKeyAndVisible; 
    {And now we Display our original Content in a new Viewcontroller 
     with our new Supported orientations} 
end;

您现在要做的就是致电 ChangeiOSorientation(toOrientation,possibleOrientations)

如果您想将其转到“肖像”,但可以选择“风景”

 ChangeiOSorientation(UIInterfaceOrientationPortrait,[TScreenOrientation.Portrait,TScreenOrientation.Landscape,TScreenOrientation.InvertedLandscape]);    

这正在

  • 西雅图德尔福10号酒店
  • 运行iOS 9.0的iPhone 5
  • PA服务器17.0
  • Xcode 7.1
  • iPhoneOS 9.1开发工具包

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Delphi在运行时更改JSONMarshalledAttribute

Delphi Firemonkey 在运行时创建 TExpanders 和 TLabels

Delphi在运行时更改高dpi

从字符串在运行时创建Delphi Firemonkey组件

delphi调整屏幕大小后如何在运行时处理组件的重新对齐

Delphi在运行时重建模式形式

在运行时创建的对象上的双击事件-Delphi

在运行时从Delphi TDBGrid后代显示DBGrid之前,如何以编程方式更改TColumn属性?

确定运行时的项目(Delphi Seattle)

Delphi 创建 dxTileBarItem 运行时

Delphi XE2在运行时不考虑组件属性

Delphi 7在运行时创建tChart Bar金字塔/圆柱体

在运行时在Delphi中从数据库表创建按钮

在运行时错误 Delphi 中创建自定义 TPanel

在 Delphi 的 android 应用程序中搜索在运行时创建的标签

Delphi 和高 DPI:在运行时创建的控件获得错误的位置

如何在运行时从 Delphi Rio 获取 Android API 版本?

Delphi Firemonkey iOS后台处理

在Delphi Seattle中更改运行时DPI后如何处理菜单缩放

当我尝试在iOS上运行时,Delphi说我丢失了一个文件

设置文本对齐方式listboxitem Delphi XE5 FM在运行时不起作用

如何在运行时在Delphi中创建自定义属性并将其附加到字段

Delphi 2007-是否有可能在运行时获取被忽略的异常类的列表?

Delphi:避免运行时组件选择破折号

Firemonkey组件在运行时移动

Delphi在运行应用程序时更改主窗体

Delphi更改正在运行的进程的汇编代码

在Delphi中旋转图像

更改Tballoonhint(Delphi)的字体