Skip to content

SystemChrome.setPreferredOrientations does not force the device to the given orientations until the device is physically rotated #13238

Closed
@sroddy

Description

@sroddy
Contributor

Steps to Reproduce

Running on iOS 10/11

Start an app in portrait mode and invoke:

SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp ]);

then invoke

SystemChrome.setPreferredOrientations([ DeviceOrientation.landscapeLeft ]);

Notice that neither the device neither the simulator automatically rotate until you physically rotate the device (and does not rotate at all if the device rotation trigger is locked).

This happens because calling +[UIViewController attemptRotationToDeviceOrientation] here https://github.com/flutter/engine/blob/master/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm#L703 is unfortunately not enough.

I workarounded the issue creating a small platform channel that invokes this code for switching to portrait right before the call to setPreferredOrientations:

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

And the counterpart code for switching to landscape

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

This solved my issue.
I think the current behaviour under iOS is bugged, moreover because my expected behaviour is what is currently happening on the Android counterpart without the need of any workaroud.

I know that the proposed way to fix it looks bad (using key-value coding on a read-only property), but if you search around the Internet, it seems to be the most reliable (and possibly only) way to handle this thing when you have just one view / view controller.

Activity

sroddy

sroddy commented on Nov 29, 2017

@sroddy
ContributorAuthor
chinmaygarde

chinmaygarde commented on Nov 30, 2017

@chinmaygarde
Member

I am not sure why this is not working for you. From my reading of the documentation on -[UIViewController supportedInterfaceOrientations] and -[UIViewController shouldAutorotate], the responses that the FlutterViewController makes to UIKit seem to be correct (assuming that the view controller is the top most view controller in the view controller hierarchy).

Have you checked whether the supported interface orientations are present in the application's Info.plist and that the application or its delegate is not giving conflicting replies in the -[UIApplicationDelegate application:supportedInterfaceOrientationsForWindow:] method?

chinmaygarde

chinmaygarde commented on Nov 30, 2017

@chinmaygarde
Member
sroddy

sroddy commented on Nov 30, 2017

@sroddy
ContributorAuthor

I know they seem right. Unfortunately they don't work.

https://stackoverflow.com/a/19125466

A call to attemptRotationToDeviceOrientation only rotates the orientation of the interface, if and only if, the device itself has been rotated.

I've been fighting in the past with this issue in the last 1 year and half and so far the only consistent way I've found to deal with this is to check the real device orientation and force it to one of the supported ones if unsupported.

sroddy

sroddy commented on Dec 4, 2017

@sroddy
ContributorAuthor

@chinmaygarde @cbracken you can see here a basic example demonstrating the issue:

Notice that:

  • If the previous device orientation was one of the supported ones (e.g. you keep the device in portraitUp mode or you lock the screen rotation), pressing the button won't produce any visible effect.
  • if you set the orientation to landscapeLeft, the orientation will change as soon as you physically rotate the device (cmd-right-arrow in iOS simulator). if you now keep the device in landscapeLeft, tapping the button won't produce any visible effect.
  • If you rotate the device in one of the two unsupported orientations (landscapeRight or portraitUp), tapping the button will produce the expected behaviour, causing the interface to rotate accordingly to the setting any time you tap on the button.
  • If you run the same code in Android, the behaviour is as (I guess) expected.
btastic

btastic commented on Feb 24, 2018

@btastic

We just noticed that when the device was in landscape and then the flutter app is opened with

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

The app will open in landscaped regardless of this setting.

added
platform-iosiOS applications specifically
engineflutter/engine repository. See also e: labels.
on May 30, 2018
added this to the Goals milestone on May 30, 2018
CaiJingLong

CaiJingLong commented on Jun 8, 2018

@CaiJingLong
Contributor

In iPad, this method doesn't seem to be implemented.
When I rotated iPad, flutter's UI rotated.

flutter doctor -v

[✓] Flutter (Channel master, v0.4.5-pre.85, on Mac OS X 10.12.6 16G29, locale zh-Hans-CN)
    • Flutter version 0.4.5-pre.85 at /Users/cai/fluttersdk/flutter
    • Framework revision 677df7c351 (2 weeks ago), 2018-05-24 16:33:46 -0700
    • Engine revision abd74ed5ed
    • Dart version 2.0.0-dev.55.0.flutter-97b6c2e09d

[!] Android toolchain - develop for Android devices (Android SDK 26.0.2)
    • Android SDK at /Users/cai/Library/Android/sdk
    • Android NDK at /Users/cai/Library/Android/sdk/ndk-bundle
    • Platform android-27, build-tools 26.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b01)
    ! Some Android licenses not accepted.  To resolve this, run: flutter doctor --android-licenses

[✓] iOS toolchain - develop for iOS devices (Xcode 9.2)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 9.2, Build version 9C40b
    • ios-deploy 1.9.2
    • CocoaPods version 1.5.0

[✓] Android Studio (version 3.1)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 23.1.2
    • Dart plugin version 171.4424
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b01)

[✓] IntelliJ IDEA Ultimate Edition (version 2018.1.4)
    • IntelliJ at /Users/cai/Applications/JetBrains Toolbox/IntelliJ IDEA Ultimate.app
    • Flutter plugin version 24.0.2
    • Dart plugin version 181.4203.498

[✓] VS Code (version 1.23.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Dart Code extension version 2.12.1

[✓] Connected devices (4 available)
    • PRO 5               • 192.168.2.2:5555                         • android-arm64 • Android 5.1 (API 22)
    • iPad mini2          • 58366e2a63aae6f85e6e806039316c27faa52868 • ios           • iOS 10.0.2
    • iPhone 8 Plus       • 8595BEDC-42FA-4B3E-8461-2AEC3D1B6272     • ios           • iOS 11.2 (simulator)
    • iPad Pro (9.7-inch) • E24A8FEF-1F44-4B3F-9FCB-2960D7CABB1C     • ios           • iOS 11.2 (simulator)


miguelpruivo

miguelpruivo commented on Aug 21, 2018

@miguelpruivo

+1

crnaosa

crnaosa commented on Aug 31, 2018

@crnaosa

+1

zoechi

zoechi commented on Aug 31, 2018

@zoechi
Contributor

@miguelpruivo @crnaosa
Using "add reaction" on the initial comment would increase priority while +1 comments are rather pointless and cause lots of people to get notified for no reason.
If you want to get notified just click the "Subscribe" button to the right.

lennartschoch

lennartschoch commented on Oct 11, 2018

@lennartschoch

I am experiencing the same issue both with the iOS emulator (iPad Pro 9.7, iOS 12) and a physical device (iPad Air 2, iOS 11). I implemented the setPreferredOrientations method inside the main function, but there is no effect noticeable. This is a huge problem when developing with user interfaces which are designed to only work in either portrait or landscape mode, not both. Can we get an update on this?

albo1337

albo1337 commented on Oct 24, 2018

@albo1337

@sroddy Could you please share your solution? I'm facing the same issue and have no idea how to fix this on iOS. It seems that you fixed it.

70 remaining items

mofada

mofada commented on Nov 9, 2019

@mofada
mofada

mofada commented on Nov 9, 2019

@mofada

upgrade your flutter and retry

kanthi0802

kanthi0802 commented on Nov 9, 2019

@kanthi0802

Not working for me tried with
Flutter (Channel master, v1.10.16-pre.110, on Mac OS X 10.14.1 18B75, locale en-GB).
Should we do anything other than calling
SystemChrome.setPreferredOrientations(
[DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
?

ZTPR0035

ZTPR0035 commented on Nov 11, 2019

@ZTPR0035

@lennartschoch the problem is, I need the landscape mode only for one screen and the portrait mode for every other screen... Your solution does not help me with my current problem, but thank you a lot for your help!

Hello @lennartschoch, I think this will solve your issue , I tried it and it work on both platforms,

return RotatedBox(
quarterTurns: 1,
child: Scaffold(),);

cbracken

cbracken commented on Nov 11, 2019

@cbracken
Member

Sounds like this is resolved based on other reports.

@lennartschoch please let us know if @ZTPR0035's suggestion doesn't work for you.

mirkopoloni

mirkopoloni commented on Dec 20, 2019

@mirkopoloni

Working fine on iPhone but still having problems on iPad, am I the only one?

Channel master, v1.13.4-pre.12, on Mac OS X 10.15.1

UPDATE 13 January
I just found out that this can't actually work on iPad without some limitations, it isn't a bug... sorry if I didn't find it out before writing my comment.
As a reference for other people, more infos here:
#27235 (comment)
https://api.flutter.dev/flutter/services/SystemChrome/setPreferredOrientations.html

ghost
hawkinsjb1

hawkinsjb1 commented on Jul 8, 2020

@hawkinsjb1

Is the only solution to this really to use a RotatedBox as @ZTPR0035 mentioned? This doesn't properly change the screen's size like a native orientation change. I'm having lots of overflow errors trying to use that solution

EDIT: Nevermind orientation is properly getting updated, my WillPopScope wasn't being triggered because I wasn't using maybePop(), duh..

pisces116

pisces116 commented on Sep 15, 2020

@pisces116

Why this issue is not resolved but is marked as resolved

removed
waiting for customer responseThe Flutter team cannot make further progress on this issue until the original reporter responds
on Dec 30, 2020
SaidiAli

SaidiAli commented on Jan 13, 2021

@SaidiAli

The issue is closed but I think i can add this just incase. I am just learning flutter and in a lecture by Maximiliano of academind, he points out that for the issue at hand to work you need to add a WidgetFlutterBinding.ensureInitialised().
Like:
WidgetFlutterBinding.ensureInitialised(); SystemChrome.setPrefferedOrientation();

yubaokang

yubaokang commented on Jan 18, 2021

@yubaokang

在iPhone上可以正常工作,但在iPad上仍然有问题,我是唯一的一个吗?

Channel master, v1.13.4-pre.12, on Mac OS X 10.15.1

1月13日更新
我刚刚发现,如果没有一些限制,这实际上无法在iPad上运行,这不是bug。...抱歉,如果我在写评论之前没有找到它。
作为其他人的参考,请在此处获取更多信息:
#27235(评论)
https://api.flutter.dev/flutter/services/SystemChrome/setPreferredOrientations.html

then same

github-actions

github-actions commented on Aug 7, 2021

@github-actions

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

locked as resolved and limited conversation to collaborators on Aug 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    a: annoyanceRepeatedly frustrating issues with non-experimental functionalityc: API breakBackwards-incompatible API changescustomer: crowdAffects or could affect many people, though not necessarily a specific customer.engineflutter/engine repository. See also e: labels.platform-iosiOS applications specifically

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @chinmaygarde@xster@cbracken@zoechi@sfaujour

        Issue actions

          SystemChrome.setPreferredOrientations does not force the device to the given orientations until the device is physically rotated · Issue #13238 · flutter/flutter