iOS上单一页面的Flutter设备方向

Nul*_*ter 5 landscape ios landscape-portrait flutter

我想以横向模式在Flutter应用程序中显示单个页面。其他所有屏幕均应以纵向模式显示。

我找到了以下代码片段:

在我的main.dart中

SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
  ]).then((_) {
    runApp(new IHGApp());
  });
Run Code Online (Sandbox Code Playgroud)

这将以纵向模式启动该应用程序。所以我有要在横向模式下显示的屏幕,这是我在那里使用的代码:

@override
  void initState() {
    super.initState();
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.landscapeRight,
      DeviceOrientation.landscapeLeft,
    ]);
  }


  @override
  void dispose() {
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
      DeviceOrientation.portraitDown,
    ]);
    super.dispose();
  }
Run Code Online (Sandbox Code Playgroud)

这适用于Android。

在iOS上,似乎无法对单个页面强制使用横向模式。

https://github.com/flutter/flutter/issues/13238

在本文中,我找到了此问题的问题。鲁rod的提到了如何解决这个问题。

“我解决了创建一个小型平台通道的问题,该通道调用此代码以在调用setPreferredOrientations之前立即切换到肖像:”

[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];
Run Code Online (Sandbox Code Playgroud)

和对应的代码切换到风景

[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeLeft) forKey:@"orientation"];
Run Code Online (Sandbox Code Playgroud)

如何在我的应用程序中实现呢?

Kam*_*ski 3

我的一个应用程序也有完全相同的要求。你很幸运——整个项目都是开源的!让我们完成它:

  1. 在 iOS 端添加平台通道逻辑ios/Runner/AppDelegate.m- https://github.com/vintage/party_flutter/blob/27b11fc46755d8901f02c3b439b294ca9005277a/ios/Runner/AppDelegate.m#L8-L23
#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;

    FlutterMethodChannel* rotationChannel = [FlutterMethodChannel
                                             methodChannelWithName:@"zgadula/orientation"
                                             binaryMessenger:controller];

    [rotationChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
        if ([@"setLandscape" isEqualToString:call.method]) {
            [[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeRight) forKey:@"orientation"];
        }
        else if ([@"setPortrait" isEqualToString:call.method]) {
            [[UIDevice currentDevice] setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];
        }
        else {
            result(FlutterMethodNotImplemented);
        }
    }];

    [GeneratedPluginRegistrant registerWithRegistry:self];
    // Override point for customization after application launch.
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}

@end
Run Code Online (Sandbox Code Playgroud)
  1. 在应该面向横向的小部件/屏幕中定义MethodChannel- https://github.com/vintage/party_flutter/blob/master/lib/ui/screens/game_play.dart#L34
static const _rotationChannel = const MethodChannel('zgadula/orientation');
Run Code Online (Sandbox Code Playgroud)

3.initState应该触发旋转到横向 - https://github.com/vintage/party_flutter/blob/master/lib/ui/screens/game_play.dart#L71-L78

SystemChrome.setPreferredOrientations([
  DeviceOrientation.landscapeRight,
]);
// TODO: Remove it when fixed in Flutter
// https://github.com/flutter/flutter/issues/13238
try {
  _rotationChannel.invokeMethod('setLandscape');
} catch (error) {}
Run Code Online (Sandbox Code Playgroud)

try-catch 用于处理 Android 部分(没有这样的通道,因为没有它它也能按预期工作)。

  1. 处置时 - 旋转回纵向模式 - https://github.com/vintage/party_flutter/blob/master/lib/ui/screens/game_play.dart#L111-L122

SystemChrome.setPreferredOrientations([
  DeviceOrientation.portraitUp,
]);

// TODO: Remove it when fixed in Flutter
// https://github.com/flutter/flutter/issues/13238
try {
  _rotationChannel.invokeMethod('setPortrait');
} catch (error) {}

if (_rotateSubscription != null) {
  _rotateSubscription.cancel();
}
Run Code Online (Sandbox Code Playgroud)

请随意更改zgadula/orientation为更适合您的项目的内容:)