4

基本的に私が達成したいのは、ユーザーがアプリの特定の部分にいて、必要に応じて画面の回転を変更することです。これは 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)) 

false を返しますか? 始まりにも入らない

横向きのみに設定した後、画面の向きを確認するテストボタンを追加しました

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]

しかし、動作はまだ同じです

4

1 に答える 1

5

この回転により、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);

ステータスバーの向きの変更は機能しますが、上記のように、このプロトコルは非推奨であるため、ある段階で廃止される可能性があり、これは機能しなくなります。

しかし、これはステータスバーとすべてのアラートビューなどの回転を変更しただけですが、ルートビューコントローラー内の実際のコンテンツは、ランドスケープに変更したい場合でもポートレートのままです。

次に、Delphi で Application->Orientation-> Enable custom rotation に移動し、横向きのみと言うと、アプリは横向きでのみ表示され、フォームが作成されたときに rootViewcontroller が supportedInterface になるため、完全に機能します。返される向きは横向きのみで、Viewcontroller は横向きになります。

デバイスがデバイスの向きを変更すると、Viewcontroller のサポートされているインターフェイスの向きに対して向きが評価されるため、向きがサポートされていない場合は単に回転されません。

しかし、新しい rootviewcontroller が割り当てられた場合、その Viewcontrollers がサポートする向きで表示するように GUI を更新する必要があります。

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]);    

これは取り組んでいます

  • Delphi 10 シアトル
  • iOS 9.0 を実行している iPhone 5
  • PA サーバー 17.0
  • Xcode 7.1
  • iPhoneOS 9.1 SDK
于 2015-11-10T13:26:35.300 に答える