dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
21.98k stars 1.72k forks source link

The overlay when displaying Shell Flyout is not drawn correctly when the screen is rotated on iOS. #15173

Open cat0363 opened 1 year ago

cat0363 commented 1 year ago

Description

This issue can be reproduced with a simple app that displays a menu using Shell's Flyout when the hamburger menu button is pressed.

The layout of AppShell.xaml is as follows.

<Shell
    x:Class="Maui_IssueFlyout.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:Maui_IssueFlyout"
    Shell.FlyoutBehavior="Flyout">
    <Shell.FlyoutContent>
        <local:FlyoutMenu x:Name="fmMenu" MenuTapped="fmMenu_MenuTapped"/>
    </Shell.FlyoutContent>
    <ShellContent
        Title="Home"
        ContentTemplate="{DataTemplate local:MainPage}"
        Route="MainPage" />
</Shell>

The layout of FlyoutMenu.xaml is as follows. This issue will probably reproduce with any layout.

<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:ios="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;assembly=Microsoft.Maui.Controls"
    x:Class="Maui_IssueFlyout.FlyoutMenu"
    ios:Page.UseSafeArea="true">
    <ScrollView Orientation="Vertical">
        <StackLayout x:Name="slMenuList" Orientation="Vertical">
            <BindableLayout.ItemTemplate>
                <DataTemplate>
                    <Grid HeightRequest="60">
                        <Grid.GestureRecognizers>
                            <TapGestureRecognizer Tapped="gdMenu_Tapped" />
                        </Grid.GestureRecognizers>
                        <Label FontSize="20" Text="{Binding MenuName}" VerticalOptions="Center" HorizontalOptions="Start" />
                    </Grid>
                </DataTemplate>
            </BindableLayout.ItemTemplate>
        </StackLayout> 
    </ScrollView>
</ContentView>

You can clearly see the problem when the theme is in light mode. Launch the app with the screen oriented portrait. Press the hamburger menu button.

test_005

Rotate the screen from portrait to landscape with the Flyout menu displayed.

test_007

The size of the overlay displayed when displaying the Flyout menu does not change after screen rotation. The size of the overlay remains the size it was when the screen was displayed in portrait orientation.

I expected the overlay to dynamically change size depending on the screen orientation. Android does not have this issue.

Steps to Reproduce

The steps to reproduce are as follows.

  1. Launch the app uploaded to github with the device in portrait orientation on iOS
  2. Press the hamburger menu button
  3. Change the device orientation from portrait to landscape

In step 3, the overlay will be displayed at the same size as it was displayed when the screen was in portrait orientation.

Link to public reproduction project repository

https://github.com/cat0363/Maui-IssueFlyout.git

Version with bug

7.0.86

Last version that worked well

Unknown/Other

Affected platforms

iOS

Affected platform versions

iOS 16.4

Did you find any workaround?

None

Relevant log output

No response

cat0363 commented 1 year ago

The reverse pattern is equally problematic.

Launch the app with the screen oriented landscape. Press the hamburger menu button.

test_009

Rotate the screen from landscape to portrait with the Flyout menu displayed.

test_010
cat0363 commented 1 year ago

I found a solution for this Issue. It is possible to solve this problem by correcting as follows.

[src\Controls\src\Core\PublicAPI\net-ios\PublicAPI.Unshipped.txt]

~override Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.ViewWillTransitionToSize(CoreGraphics.CGSize toSize, UIKit.IUIViewControllerTransitionCoordinator coordinator) -> void

[src\Controls\src\Core\PublicAPI\net-maccatalyst\PublicAPI.Unshipped.txt]

~override Microsoft.Maui.Controls.Platform.Compatibility.ShellFlyoutRenderer.ViewWillTransitionToSize(CoreGraphics.CGSize toSize, UIKit.IUIViewControllerTransitionCoordinator coordinator) -> void

[src\Controls\src\Core\Compatibility\Handlers\Shell\iOS\ShellFlyoutRenderer.cs]

public override void ViewWillTransitionToSize(CoreGraphics.CGSize toSize, UIKit.IUIViewControllerTransitionCoordinator coordinator)
{
    base.ViewWillTransitionToSize(toSize, coordinator);

    coordinator.AnimateAlongsideTransition((IUIViewControllerTransitionCoordinatorContext obj) => {
        // Before screen rotate
    }, (IUIViewControllerTransitionCoordinatorContext obj) => {
        // After screen rotate
        if (IsOpen)
        {
            TapoffView.Frame = View.Frame;
        }
    });
}

Override the ViewWillTransitionToSize method to update the Tapoffview's Frame on rotation detection. This will allow the size of the overlay portion to update on rotation. However, I need to add a definition to PublicAPI.Unshipped.txt to override the ViewWillTransitionToSize method.

Below is the execution result.

https://github.com/dotnet/maui/assets/125236133/d46b7d21-04f0-4b4a-9c51-f39f3db3d29b

In the video, after rotating the terminal from portrait to landscape, the terminal is returned from landscape to portrait.

Could you please check it? Thank you.

cat0363 commented 5 months ago

When will this issue be resolved?