Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Using StatusBarBehavior does not display the status bar as intended after screen rotation on iOS. #1193

Closed
2 tasks done
cat0363 opened this issue May 18, 2023 · 8 comments · Fixed by #1248
Closed
2 tasks done
Labels
bug Something isn't working unverified

Comments

@cat0363
Copy link
Contributor

cat0363 commented May 18, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Did you read the "Reporting a bug" section on Contributing file?

Current Behavior

To reproduce the problem, layout as below.

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
         x:Class="MauiComm_IssueStatusBar.MainPage" BackgroundColor="Green">
    <ContentPage.Behaviors>
        <mct:StatusBarBehavior StatusBarColor="White" />
    </ContentPage.Behaviors>
</ContentPage>

If the screen orientation is portrait, there is no problem.

test_001

When changing the screen orientation from portrait to landscape, the status bar remains at the top of the screen.

test_002

Then quit the app completely.

If the screen orientation is landscape, there is no problem.

test_003

The status bar disappears when the screen orientation is changed from landscape to portrait.

test_004

This issue was previously reported as Issue #637, but was already closed.
For this reason, I have opened a new issue.

Any good ideas? Thank you.

Expected Behavior

I expected the status bar to disappear at the top of the screen when the screen orientation changed from portrait to landscape.
I expected the status bar at the top of the screen to appear when the screen orientation changed from landscape to portrait.

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. Change the device orientation from portrait to landscape
  3. Completely quit the app.
  4. Launch the app uploaded to github with the device in landscape orientation on iOS
  5. Change the device orientation from landscape to portrait

In step 2., the status bar remains displayed at the top of the screen.
In step 5., the status bar remains hidden.

Link to public reproduction project repository

https://github.com/cat0363/MauiComm-IssueStatusBar.git

Environment

- .NET MAUI CommunityToolkit:5.1.0
- OS:iOS 16.4
- .NET MAUI:7.0.86

Anything else?

None

@cat0363 cat0363 added bug Something isn't working unverified labels May 18, 2023
@cat0363 cat0363 changed the title [BUG] Using StatusBarBehavior does not display the status bar as intended after screen rotation.on iOS. [BUG] Using StatusBarBehavior does not display the status bar as intended after screen rotation on iOS. May 18, 2023
@cat0363
Copy link
Contributor Author

cat0363 commented Jun 14, 2023

I found the solution for this issue.
It can be solved by adding the following code to StatusBarBehavior.shared.cs.

#if IOS
protected override void OnAttachedTo(Page bindable, UIKit.UIView platformView)
#elif ANDROID
protected override void OnAttachedTo(Page bindable, Android.Views.View platformView)
#else
protected override void OnAttachedTo(Page bindable, object platformView)
#endif
{
    StatusBar.SetColor(StatusBarColor);
    StatusBar.SetStyle(StatusBarStyle);
    bindable.SizeChanged += new EventHandler(page_SizeChanged);
}

#if IOS
protected override void OnDetachedFrom(Page bindable, UIKit.UIView platformView)
#elif ANDROID
protected override void OnDetachedFrom(Page bindable, Android.Views.View platformView)
#else
protected override void OnDetachedFrom(Page bindable, object platformView)
#endif
{
    bindable.SizeChanged -= new EventHandler(page_SizeChanged);
}

void page_SizeChanged(object? sender, EventArgs e)
{
    StatusBar.SetColor(StatusBarColor);
    StatusBar.SetStyle(StatusBarStyle);
}

Below is the execution result.

[iOS]

iPad.10th.generation.iOS.16.4.2023-06-14.17-11-36.mp4

Could you please check if there is any problem with the solution described above?
If there is no problem with this correspondence, I can create a PR.

@cat0363
Copy link
Contributor Author

cat0363 commented Jun 15, 2023

Based on this post, I will reconsider the solution again.
Because the solution I posted yesterday unintentionally changes colors when rotated.

@cat0363
Copy link
Contributor Author

cat0363 commented Jun 15, 2023

I changed the solution as below.

[StatusBar.shared.cs]

/// <summary>
/// Method to update the status bar size.
/// </summary>
public static void UpdateBarSize() =>
    PlatformUpdateBarSize();

[StatusBar.ios.cs]

static void PlatformUpdateBarSize()
{
    if (OperatingSystem.IsIOSVersionAtLeast(13))
    {
        var statusBarTag = new IntPtr(38482);
        foreach (var window in UIApplication.SharedApplication.Windows)
        {
            var statusBar = window.ViewWithTag(statusBarTag);
            var statusBarFrame = window.WindowScene?.StatusBarManager?.StatusBarFrame;
            if (statusBarFrame is null)
            {
                continue;
            }

            statusBar ??= new UIView(statusBarFrame.Value);
            statusBar.Tag = statusBarTag;
            statusBar.Frame = UIApplication.SharedApplication.StatusBarFrame;
            var statusBarSubViews = window.Subviews.Where(x => x.Tag == statusBarTag).ToList();
            foreach (var statusBarSubView in statusBarSubViews)
            {
                statusBarSubView.RemoveFromSuperview();
            }
            window.AddSubview(statusBar);

            UpdateStatusBarAppearance(window);
        }
    }
    else
    {
        if (UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) is UIView statusBar)
        {
            statusBar.Frame = UIApplication.SharedApplication.StatusBarFrame;
        }
        UpdateStatusBarAppearance();
    }
}

[StatusBar.android.cs]

static void PlatformUpdateBarSize()
{
    throw new NotSupportedException("Android does not currently support updating the status bar size");
}

[StatusBar.macos.cs]

static void PlatformUpdateBarSize()
{
    throw new NotSupportedException("MacCatalyst does not currently support updating the macOS status bar size");
}

[StatusBar.net.cs]

static void PlatformUpdateBarSize() => throw new NotSupportedException($"{nameof(PlatformUpdateBarSize)} is only supported on net6.0-ios and later");

[StatusBar.tizen.cs]

static void PlatformUpdateBarSize()
{
    throw new NotSupportedException("Tizen does not currently support updating the status bar size");
}

[StatusBar.windows.cs]

static void PlatformUpdateBarSize()
{
    throw new NotSupportedException("WinUI does not currently support updating the Windows status bar size");
}

[StatusBarBehavior.shared.cs]

#if IOS
protected override void OnAttachedTo(Page bindable, UIKit.UIView platformView)
#elif ANDROID
protected override void OnAttachedTo(Page bindable, Android.Views.View platformView)
#else
protected override void OnAttachedTo(Page bindable, object platformView)
#endif
{
    StatusBar.SetColor(StatusBarColor);
    StatusBar.SetStyle(StatusBarStyle);
#if IOS
    bindable.SizeChanged += new EventHandler(page_SizeChanged);
#endif
}

#if IOS
protected override void OnDetachedFrom(Page bindable, UIKit.UIView platformView)
#elif ANDROID
protected override void OnDetachedFrom(Page bindable, Android.Views.View platformView)
#else
protected override void OnDetachedFrom(Page bindable, object platformView)
#endif
{
#if IOS
    bindable.SizeChanged -= new EventHandler(page_SizeChanged);
#endif
}

#if IOS
void page_SizeChanged(object? sender, EventArgs e)
{
    StatusBar.UpdateBarSize();
}
#endif

If you call the SetColor and SetLayout methods of StatusBar when rotating,
you can adjust the size of the status bar to fit the width of the screen,
but the color will change unintentionally. So I changed the size only.

I defined an UpdateBarSize method in shared and implemented a PlatformUpdateBarSize
method for each platform. Other platforms than iOS don't need support, so they throw
NotSupportedException.

Since I do not have a simulator prior to iOS 13 in my execution environment,
I have not been able to confirm the operation on versions prior to iOS 13.
Is there anyone who can verify that the following works?

if (UIApplication.SharedApplication.ValueForKey(new NSString("statusBar")) is UIView statusBar)
{
    statusBar.Frame = UIApplication.SharedApplication.StatusBarFrame;
}
UpdateStatusBarAppearance();

Below is the execution result.

[iOS 16.4]

iPad.10th.generation.iOS.16.4.2023-06-15.13-01-13.mp4

[iOS 15.5]

iPad.9th.generation.iOS.15.5.2023-06-15.13-18-40.mp4

[iOS 14.5]

iPad.8th.generation.iOS.14.5.2023-06-15.13-58-52.mp4

[iOS 13.7]

iPad.7th.generation.iOS.13.7.2023-06-15.14-39-01.mp4

The video is a recording of the following steps.

  1. Perform a rotation operation
  2. Page transition
  3. Change status bar color
  4. Return to transition source page
  5. Perform a rotation operation

The color of the status bar is changed at both the page transition source and the page transition
destination, but the finally changed status bar color is retained, and only the size of the status bar is
changed after the rotation operation.

I will create a PR, so could you please check it?

cat0363 added a commit to cat0363/Maui that referenced this issue Jun 15, 2023
@cat0363 cat0363 mentioned this issue Jun 15, 2023
6 tasks
VladislavAntonyuk pushed a commit that referenced this issue Jun 15, 2023
* Fix Issue #1193

* Fixed event registration process

* Method refactoring

Removal of unnecessary methods for each platform other than iOS

* Changed OnDetachedFrom method to iOS only
@vallgrenerik
Copy link

Has this fix been released? Can't find in release notes @cat0363 @VladislavAntonyuk

@brminnick
Copy link
Collaborator

brminnick commented Oct 30, 2023

@vallgrenerik Here's a quick pro tip for GitHub to find out if a commit has been released:

  1. Navigate to the GitHub page detailing the commit: 8e67d0a
  2. In the details of the commit, it tells you which Release(s) in which it's included:

Group

To answer your question, yes the PR containing this bug fix was included in v6.0.0

@vallgrenerik
Copy link

Thank you @brminnick! Appreciate the pro tip! ⭐👏

@RsZoli
Copy link

RsZoli commented Feb 22, 2024

@brminnick So how come it is still present in 7.0.1?

@brminnick
Copy link
Collaborator

Hi, if you've uncovered a bug, please report a new issue that includes a reproduction sample. If you know how to fix it, please submit a Pull Request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working unverified
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants