chewie icon indicating copy to clipboard operation
chewie copied to clipboard

iOS orientation stays landscape after fullscreen

Open gazialankus opened this issue 2 years ago • 5 comments

After entering and exiting fullscreen, the app stays in landscape orientation even though app was being held in portrait orientation the whole time. At this point, rotating the simulator to landscape and back to portrait brings the app back to portrait mode.

Expected behavior: When we exit fullscreen, whatever physical orientation that the simulator is in should be the orientation that the app adopts. At 00:07 in the video below, the app should appear in portrait mode, just like it was before going to full screen.

Forcing portrait is not a good option as the user could have actually turned the phone to landscape orientation and this video would be how it should be. However, in this video I keep it portrait throughout and it makes the app landscape unexpectedly.

I'm using the fullscreen button that Chewie shows, as seen in the video below. This is the example code in Chewie repo, with Flutter 3.0.3, Chewie 1.3.4 and iOS 15.2 simulator of iPhone 13 Pro Max.

https://user-images.githubusercontent.com/412997/187079020-7e95eda4-6eab-4a25-8800-02d6a5c3ea4a.mov

gazialankus avatar Aug 28 '22 14:08 gazialankus

I just tried it on an iPhone 6S with iOS 15.0 and observed the exact same behavior. The sad thing is, if you have orientation lock enabled in your phone and start in portrait mode, you end up locked in landscape mode unexpectedly.

https://user-images.githubusercontent.com/412997/187080610-66de0d7e-2902-4466-be46-5861a76ee04e.mp4

Btw in Android we do not have this problem and it works as expected: when we press fullscreen it goes to landscape mode and (unlike iOS) when we press it again it goes back to portrait mode.

gazialankus avatar Aug 28 '22 15:08 gazialankus

Here's my temporary workaround. When coming back from fullscreen, I enforce portraitUp for a bit.

The only weird case is when the user wanted to continue using the app in landscape, this leaves the user in portrait. A simple rotation of the device gets you back to landscape. For my current app that's ok, but surely there should be a better fix.

    _chewieController?.addListener(() {
      final isFullScreen = _chewieController?.isFullScreen;
      if (wasFullScreen == true && isFullScreen == false) {
        SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
        Future.delayed(const Duration(seconds: 1)).then((_) =>
            SystemChrome.setPreferredOrientations(DeviceOrientation.values));
      }
      wasFullScreen = isFullScreen;
    });

gazialankus avatar Aug 29 '22 10:08 gazialankus

ChewieController has deviceOrientationsOnEnterFullScreen and deviceOrientationsAfterFullScreen. What you can do is you can monitor changes to the current orientation by mixing in WidgetsBindingObserver to a StatefulWidget that displays Chewie. Every time didChangeMetrics gets called in the WidgetsBindingObserver, you save the current orientation value locally by calling MediaQuery.of(context).orientation and doing the same thing in a post frame callback every time the widget is rebuilt. Once you have a reference to the current orientation, just re-create ChewieController by calling copyWith and setting deviceOrientationsAfterFullScreen to your current orientation.

After it exits full screen, it will set it to that value. If you want to retain all orientations after exiting, and not just a fixed one, then simply set deviceOrientationsAfterFullScreen to DeviceOrientation.values when creating the ChewieController.

diegotori avatar Aug 29 '22 15:08 diegotori

@diegotori this sounds like a perfect fix, thank you. For the time being my app is fine but I will consider switching to this solution.

However, this difference in behavior between iOS and Android it's unexpected and I believe this solution should be integrated into Chewie itself.

gazialankus avatar Sep 06 '22 05:09 gazialankus

@gazialankus that is true. I'll have to think about how best to implement it without creating unintended consequences.

In other words, this has to be opt-in and it shouldn't for example force the current orientation that was queried before fullscreen to supersede the previous orientation after exiting it.

Suppose your app supports portrait and landscape. If you're viewing a landscape video in portrait, and you go to fullscreen, this will remember the previous portrait orientation before entering FS, but it will force set the app back to portrait when exiting it, thus negating the landscape orientation that was set to it previously. This might be desired if your app only supports one orientation.

However, if your app supports more than one, then it makes sense to set deviceOrientationsAfterFullScreen on your ChewieController to all of the expected orientations.

Either way, this has to be thought out so that it doesn't create collateral damage. I also accept PRs to this effect, so that's another avenue that you can pursue.

diegotori avatar Sep 06 '22 20:09 diegotori

For those who need the working code, just pass this arguments when ChewieController is initialized. It will make the landscape video to be back to portrait mode when you exit the video. deviceOrientationsAfterFullScreen: [DeviceOrientation.portraitUp],

zerowu49 avatar Dec 09 '22 06:12 zerowu49

@gazialankus did you fix it?

asrafulattare avatar Dec 29 '22 15:12 asrafulattare

No I had left this app the way I explained before, I don't work on that project anymore.

gazialankus avatar Dec 29 '22 19:12 gazialankus

deviceOrientationsAfterFullScreen: [DeviceOrientation.portraitUp],

I tried to do what you said, but when returning from fullscreen mode it continues in landscape mode.

lucasbarretoluz avatar Jan 04 '23 02:01 lucasbarretoluz