-
Notifications
You must be signed in to change notification settings - Fork 2k
[iOS 26] Fix Shell TitleView not resizing on device rotation #35883
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
Changes from 1 commit
efc0ac5
9400712
8e342fb
6e765f5
d89bdea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -371,6 +371,28 @@ TitleViewContainer CreateTitleViewContainer(View titleView) | |
| return new TitleViewContainer(titleView); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Re-applies the navigation bar frame to the current TitleView container. | ||
| /// On iOS 26+ the TitleView container uses autoresizing masks with an explicitly set frame | ||
| /// (see <see cref="CreateTitleViewContainer"/>), so the frame is not automatically recomputed | ||
| /// when the navigation bar resizes during rotation or window size changes. This explicitly | ||
| /// resizes the container to match the navigation bar's new dimensions. | ||
| /// </summary> | ||
| internal void UpdateTitleViewFrameForOrientation() | ||
| { | ||
| if (NavigationItem?.TitleView is not TitleViewContainer titleViewContainer) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| var navigationBarFrame = ViewController?.NavigationController?.NavigationBar.Frame; | ||
| if (navigationBarFrame.HasValue) | ||
| { | ||
| titleViewContainer.Frame = new CGRect(0, 0, navigationBarFrame.Value.Width, navigationBarFrame.Value.Height); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [major] Layout Measure-Arrange - The orientation helper updates the native |
||
| titleViewContainer.LayoutIfNeeded(); | ||
| } | ||
| } | ||
|
|
||
| void OnTitleViewParentSet(object? sender, EventArgs e) | ||
| { | ||
| if (sender is Element element) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| namespace Maui.Controls.Sample.Issues; | ||
|
|
||
| [Issue(IssueTracker.Github, 35844, "Shell TitleView does not resize after rotation on iOS 26+", PlatformAffected.iOS)] | ||
| public class Issue35844Shell : Shell | ||
| { | ||
| public Issue35844Shell() | ||
| { | ||
| Issue35844 contentPage = new Issue35844(); | ||
|
|
||
| ShellContent shellContent = new ShellContent | ||
| { | ||
| Content = contentPage, | ||
| Route = "Issue35844" | ||
| }; | ||
|
|
||
| Items.Add(shellContent); | ||
| } | ||
| } | ||
|
|
||
| public class Issue35844 : ContentPage | ||
| { | ||
| public Issue35844() | ||
| { | ||
| Shell.SetTitleView(this, new Grid | ||
| { | ||
| BackgroundColor = Colors.LightBlue, | ||
| AutomationId = "TitleViewGrid", | ||
| HorizontalOptions = LayoutOptions.Fill, | ||
| Children = | ||
| { | ||
| new Label | ||
| { | ||
| Text = "Shell TitleView", | ||
| AutomationId = "TitleLabel", | ||
| TextColor = Colors.White, | ||
| FontSize = 18, | ||
| FontAttributes = FontAttributes.Bold, | ||
| VerticalOptions = LayoutOptions.Center, | ||
| HorizontalOptions = LayoutOptions.Center | ||
| } | ||
| } | ||
| }); | ||
|
|
||
| Content = new VerticalStackLayout | ||
| { | ||
| Padding = new Thickness(20), | ||
| Spacing = 10, | ||
| Children = | ||
| { | ||
| new Label | ||
| { | ||
| Text = "Issue 35844", | ||
| FontSize = 20, | ||
| FontAttributes = FontAttributes.Bold, | ||
| AutomationId = "HeaderLabel", | ||
| HorizontalOptions = LayoutOptions.Center | ||
| }, | ||
| new Label | ||
| { | ||
| Text = "Shell TitleView should fill the navigation bar width after rotation on iOS 26+.", | ||
| FontSize = 14, | ||
| AutomationId = "DescriptionLabel" | ||
| }, | ||
| new Label | ||
| { | ||
| Text = "Rotate device to test", | ||
| AutomationId = "StatusLabel", | ||
| FontSize = 16, | ||
| TextColor = Colors.Gray | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| #if TEST_FAILS_ON_WINDOWS && TEST_FAILS_ON_CATALYST // SetOrientationLandscape/Portrait is only supported on iOS and Android. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [major] Regression Prevention - This preprocessor guard also includes the test in the Android test project: Android defines |
||
|
|
||
| using NUnit.Framework; | ||
| using UITest.Appium; | ||
| using UITest.Core; | ||
|
|
||
| namespace Microsoft.Maui.TestCases.Tests.Issues | ||
| { | ||
| public class Issue35844 : _IssuesUITest | ||
| { | ||
| public override string Issue => "Shell TitleView does not resize after rotation on iOS 26+"; | ||
|
|
||
| public Issue35844(TestDevice device) : base(device) { } | ||
|
|
||
| [Test] | ||
| [Category(UITestCategories.Shell)] | ||
| public void ShellTitleViewResizesOnRotation() | ||
| { | ||
| App.WaitForElement("TitleViewGrid"); | ||
| App.WaitForElement("StatusLabel"); | ||
|
|
||
| // Capture portrait width | ||
| var portraitRect = App.WaitForElement("TitleViewGrid").GetRect(); | ||
| var portraitWidth = portraitRect.Width; | ||
|
|
||
| App.SetOrientationLandscape(); | ||
|
|
||
| // After rotation, TitleView width must change to fill the wider nav bar | ||
| var landscapeRect = App.WaitForElement("TitleViewGrid").GetRect(); | ||
| var landscapeWidth = landscapeRect.Width; | ||
|
|
||
| Assert.That(landscapeWidth, Is.Not.EqualTo(portraitWidth).Within(100), | ||
| "Shell TitleView width should expand after rotating to landscape on iOS 26+"); | ||
| Assert.That(landscapeWidth, Is.GreaterThan(portraitWidth), | ||
| "Shell TitleView should be wider in landscape than portrait"); | ||
|
|
||
| // Rotate back and verify TitleView returns to original width | ||
| App.SetOrientationPortrait(); | ||
|
|
||
| var finalRect = App.WaitForElement("TitleViewGrid").GetRect(); | ||
| Assert.That(finalRect.Width, Is.EqualTo(portraitWidth).Within(5), | ||
| "Shell TitleView should return to original portrait width after rotating back"); | ||
| } | ||
| } | ||
| } | ||
| #endif | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[major] iOS Shell layout —
UpdateTitleViewFrameForOrientation()resizes the nativeTitleViewContainer.Frame, but it does not refresh the container'sHeightvalue used byUIContainerView.LayoutSubviews()whenMatchHeightis true. On iPhone rotation the navigation bar height can change between portrait and landscape, so the container frame can match the new bar while the MAUI title view is still measured/arranged with the previous bar height, causing vertical clipping or stale layout. Please update the stored height together with the frame, or route this through a helper that keepsFrameandHeightin sync, and cover the rotated height/clipping case in the regression test.