Флаттер Ориентация устройства для одной страницы на iOS - PullRequest
0 голосов
/ 25 октября 2018

Я хочу показать одну страницу в приложении Flutter в альбомной ориентации.Любой другой экран должен отображаться в портретном режиме.

Я нашел этот фрагмент кода:

В моем main.dart

SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
  ]).then((_) {
    runApp(new IHGApp());
  });

Это запускает приложение в портретном режиме.Итак, у меня есть экран, который я хочу показать в ландшафтном режиме, и вот код, который я там использовал:

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


  @override
  void dispose() {
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
      DeviceOrientation.portraitDown,
    ]);
    super.dispose();
  }

Это работает на Android.

В iOS, похоже, нет способаПринудительно использовать ландшафтный режим для одной страницы.

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

В этой статье я нашел проблему для этой проблемы.Сродди упомянул, как решить проблему.

"Я обошел проблему, создав небольшой канал платформы, который вызывает этот код для переключения в портретный режим непосредственно перед вызовом setPreferredOrientations:"

[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];

И аналогичный код для переключения в ландшафт

[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeLeft) forKey:@"orientation"];

Как я могу реализовать это в моем приложении?

1 Ответ

0 голосов
/ 25 июля 2019

У меня было точно такое же требование в одном из моих приложений.К счастью, весь проект с открытым исходным кодом!Давайте сделаем это:

  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
В виджете / экране, который должен быть ориентирован на ландшафт, определите MethodChannel - https://github.com/vintage/party_flutter/blob/master/lib/ui/screens/game_play.dart#L34
static const _rotationChannel = const MethodChannel('zgadula/orientation');

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) {}

Try-catch - обработать часть Android (такого канала нет, так как без него он работает как положено).

При утилизации - поверните обратно в портретный режим - 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();
}

Не стесняйтесь изменить zgadula/orientation на что-то, что будет лучше соответствовать вашему проекту:)

...