From 63cc938632aea3fd677ca4bc4e91c363055fac05 Mon Sep 17 00:00:00 2001 From: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com> Date: Wed, 29 Apr 2026 11:15:22 +0530 Subject: [PATCH 01/12] Fixed-35114 : [.NET 10][iOS] D2 - Editor can't be scrolled after rotating simulator --- src/Controls/src/Core/Editor/Editor.iOS.cs | 26 ++++++++++ .../PublicAPI/net-ios/PublicAPI.Unshipped.txt | 2 + .../net-maccatalyst/PublicAPI.Unshipped.txt | 2 + .../TestCases.HostApp/Issues/Issue35114.cs | 37 ++++++++++++++ .../Tests/Issues/Issue35114.cs | 51 +++++++++++++++++++ .../src/Handlers/Editor/EditorHandler.iOS.cs | 27 +++++++++- src/Core/src/Platform/iOS/MauiTextView.cs | 7 +++ 7 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 src/Controls/tests/TestCases.HostApp/Issues/Issue35114.cs create mode 100644 src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35114.cs diff --git a/src/Controls/src/Core/Editor/Editor.iOS.cs b/src/Controls/src/Core/Editor/Editor.iOS.cs index 1430b10cb4dc..1dfc99961e13 100644 --- a/src/Controls/src/Core/Editor/Editor.iOS.cs +++ b/src/Controls/src/Core/Editor/Editor.iOS.cs @@ -1,4 +1,6 @@ #nullable disable +using Microsoft.Maui.Platform; + namespace Microsoft.Maui.Controls { public partial class Editor @@ -13,5 +15,29 @@ public static void MapText(IEditorHandler handler, Editor editor) // Any text changes in the editor field require recalculating the CharacterSpacing by regenerating the attributed string to properly apply the spacing and override the current text formatting. handler?.UpdateValue(nameof(CharacterSpacing)); } + + protected override void OnHandlerChanged() + { + base.OnHandlerChanged(); + SyncAllowAutoGrowthToPlatform(); + } + + protected override void OnPropertyChanged(string propertyName = null) + { + base.OnPropertyChanged(propertyName); + + if (propertyName == nameof(AutoSize)) + { + SyncAllowAutoGrowthToPlatform(); + } + } + + void SyncAllowAutoGrowthToPlatform() + { + if (Handler?.PlatformView is MauiTextView textView) + { + textView.AllowAutoGrowth = AutoSize == EditorAutoSizeOption.TextChanges; + } + } } } diff --git a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt index 21d15383214b..955b7c611b39 100644 --- a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt @@ -6,3 +6,5 @@ override Microsoft.Maui.Controls.Platform.Compatibility.ShellTableViewController ~override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.DisconnectHandler(UIKit.UIView platformView) -> void override Microsoft.Maui.Controls.Platform.Compatibility.ShellItemRenderer.ViewDidAppear(bool animated) -> void ~override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRenderer.DidMoveToParentViewController(UIKit.UIViewController parent) -> void +override Microsoft.Maui.Controls.Editor.OnHandlerChanged() -> void +~override Microsoft.Maui.Controls.Editor.OnPropertyChanged(string propertyName = null) -> void diff --git a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt index 21d15383214b..955b7c611b39 100644 --- a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt @@ -6,3 +6,5 @@ override Microsoft.Maui.Controls.Platform.Compatibility.ShellTableViewController ~override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.DisconnectHandler(UIKit.UIView platformView) -> void override Microsoft.Maui.Controls.Platform.Compatibility.ShellItemRenderer.ViewDidAppear(bool animated) -> void ~override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRenderer.DidMoveToParentViewController(UIKit.UIViewController parent) -> void +override Microsoft.Maui.Controls.Editor.OnHandlerChanged() -> void +~override Microsoft.Maui.Controls.Editor.OnPropertyChanged(string propertyName = null) -> void diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue35114.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue35114.cs new file mode 100644 index 000000000000..9d098c6760ac --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue35114.cs @@ -0,0 +1,37 @@ +namespace Maui.Controls.Sample.Issues; + +[Issue(IssueTracker.Github, 35114, "Editor can not be scrolled after rotating simulator", PlatformAffected.iOS)] +public class Issue35114 : ContentPage +{ + public Issue35114() + { + Title = "D2"; + + var slider = new Slider + { + AutomationId = "Slider", + Maximum = 300, + Minimum = 0 + }; + + var editor = new Editor + { + AutomationId = "TestEditor", + Text = "testing" + }; + + editor.BindingContext = slider; + editor.SetBinding(Editor.CharacterSpacingProperty, new Binding("Value")); + + Content = new VerticalStackLayout + { + Children = + { + new Label { Text = "1. Play with the value of the slider below and observe as the space between characters widens." }, + new Label { Text = "2. The tests fails if the space between characters does not change." }, + slider, + editor + } + }; + } +} diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35114.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35114.cs new file mode 100644 index 000000000000..4d2d6c69c903 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35114.cs @@ -0,0 +1,51 @@ +#if IOS || ANDROID // The SetOrientation method is only supported on mobile platforms. +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue35114 : _IssuesUITest +{ + public Issue35114(TestDevice device) : base(device) + { + } + + public override string Issue => "Editor can not be scrolled after rotating simulator"; + + [Test] + [Category(UITestCategories.Editor)] + public void EditorCanBeScrolledAfterRotation() + { + // Step 1: Wait for slider and drag it to max + var sliderRect = App.WaitForElement("Slider").GetRect(); + App.DragCoordinates( + sliderRect.X + 5, + sliderRect.Y + sliderRect.Height / 2, + sliderRect.X + sliderRect.Width - 5, + sliderRect.Y + sliderRect.Height / 2); + App.WaitForElement("TestEditor"); + + // Step 2: Get editor height before rotation + var editorRectBefore = App.WaitForElement("TestEditor").GetRect(); + var heightBefore = editorRectBefore.Height; + + // Step 3: Rotate to landscape + App.SetOrientationLandscape(); + App.WaitForElement("TestEditor"); + + // Step 4: Rotate back to portrait + App.SetOrientationPortrait(); + // Allow time for layout to settle after rotation + Task.Delay(2000).Wait(); + App.WaitForElement("TestEditor"); + + // Step 5: Get editor height after rotation — should NOT grow + var editorRectAfter = App.WaitForElement("TestEditor").GetRect(); + var heightAfter = editorRectAfter.Height; + + Assert.That(heightAfter, Is.EqualTo(heightBefore), + $"Editor height should not grow after rotation. Before: {heightBefore}, After: {heightAfter}"); + } +} +#endif diff --git a/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs b/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs index aaf1a2ec7eda..0e8a9e909f43 100644 --- a/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs +++ b/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs @@ -54,6 +54,24 @@ public override bool NeedsContainer public override Size GetDesiredSize(double widthConstraint, double heightConstraint) { + // When the editor's content overflows its current frame (i.e., it's scrollable), + // cap the returned height to preserve scrollability. Without this, rotation triggers + // a re-measurement that returns the full content height, causing the editor + // to grow and lose scrollability (fixes #35114). + // Skip capping when AllowAutoGrowth is set (AutoSize=TextChanges mode), + // because in that mode the Editor is expected to grow to fit its content. + double capHeight = 0; + bool shouldCapHeight = false; + if (double.IsInfinity(heightConstraint) && !PlatformView.AllowAutoGrowth) + { + var currentHeight = (double)PlatformView.Bounds.Height; + if (currentHeight > 0 && PlatformView.ContentSize.Height > currentHeight) + { + shouldCapHeight = true; + capHeight = currentHeight; + } + } + if (double.IsInfinity(widthConstraint) || double.IsInfinity(heightConstraint)) { // If we drop an infinite value into base.GetDesiredSize for the Editor, we'll @@ -73,7 +91,14 @@ public override Size GetDesiredSize(double widthConstraint, double heightConstra } } - return base.GetDesiredSize(widthConstraint, heightConstraint); + var result = base.GetDesiredSize(widthConstraint, heightConstraint); + + if (shouldCapHeight && result.Height > capHeight) + { + return new Size(result.Width, capHeight); + } + + return result; } public static void MapText(IEditorHandler handler, IEditor editor) diff --git a/src/Core/src/Platform/iOS/MauiTextView.cs b/src/Core/src/Platform/iOS/MauiTextView.cs index abd5be6475b1..66cba191fd55 100644 --- a/src/Core/src/Platform/iOS/MauiTextView.cs +++ b/src/Core/src/Platform/iOS/MauiTextView.cs @@ -68,6 +68,13 @@ public UIColor? PlaceholderTextColor public TextAlignment VerticalTextAlignment { get; set; } + /// + /// When true, the Editor is allowed to grow beyond its current frame to fit content + /// (AutoSize=TextChanges mode). When false, GetDesiredSize may cap the height to + /// preserve scrollability. + /// + internal bool AllowAutoGrowth { get; set; } + public override string? Text { get => base.Text; From 2934909b96eac9fd61d192cd1033804bb670c7ee Mon Sep 17 00:00:00 2001 From: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com> Date: Thu, 30 Apr 2026 18:05:51 +0530 Subject: [PATCH 02/12] Fix updated. --- src/Controls/src/Core/Editor/Editor.Mapper.cs | 8 ++++++ src/Controls/src/Core/Editor/Editor.cs | 1 + src/Controls/src/Core/Editor/Editor.iOS.cs | 26 ------------------- .../PublicAPI/net-ios/PublicAPI.Unshipped.txt | 2 -- .../net-maccatalyst/PublicAPI.Unshipped.txt | 2 -- 5 files changed, 9 insertions(+), 30 deletions(-) diff --git a/src/Controls/src/Core/Editor/Editor.Mapper.cs b/src/Controls/src/Core/Editor/Editor.Mapper.cs index 0258acedebea..887be9816053 100644 --- a/src/Controls/src/Core/Editor/Editor.Mapper.cs +++ b/src/Controls/src/Core/Editor/Editor.Mapper.cs @@ -25,6 +25,14 @@ public partial class Editor } #endif +#if IOS || MACCATALYST + EditorHandler.Mapper.AppendToMapping(nameof(AutoSize), (handler, editor) => + { + if (handler.PlatformView is Microsoft.Maui.Platform.MauiTextView textView) + textView.AllowAutoGrowth = editor.AutoSize == EditorAutoSizeOption.TextChanges; + }); +#endif + #if IOS || ANDROID EditorHandler.Mapper.AppendToMapping(nameof(VisualElement.IsFocused), InputView.MapIsFocused); EditorHandler.Mapper.AppendToMapping(nameof(VisualElement.IsVisible), InputView.MapIsVisible); diff --git a/src/Controls/src/Core/Editor/Editor.cs b/src/Controls/src/Core/Editor/Editor.cs index b7f85625537d..38de223295cd 100644 --- a/src/Controls/src/Core/Editor/Editor.cs +++ b/src/Controls/src/Core/Editor/Editor.cs @@ -93,6 +93,7 @@ void UpdateAutoSizeOption() { if (AutoSize == EditorAutoSizeOption.TextChanges && this.IsShimmed()) InvalidateMeasure(); + Handler?.UpdateValue(nameof(AutoSize)); } /// diff --git a/src/Controls/src/Core/Editor/Editor.iOS.cs b/src/Controls/src/Core/Editor/Editor.iOS.cs index 1dfc99961e13..1430b10cb4dc 100644 --- a/src/Controls/src/Core/Editor/Editor.iOS.cs +++ b/src/Controls/src/Core/Editor/Editor.iOS.cs @@ -1,6 +1,4 @@ #nullable disable -using Microsoft.Maui.Platform; - namespace Microsoft.Maui.Controls { public partial class Editor @@ -15,29 +13,5 @@ public static void MapText(IEditorHandler handler, Editor editor) // Any text changes in the editor field require recalculating the CharacterSpacing by regenerating the attributed string to properly apply the spacing and override the current text formatting. handler?.UpdateValue(nameof(CharacterSpacing)); } - - protected override void OnHandlerChanged() - { - base.OnHandlerChanged(); - SyncAllowAutoGrowthToPlatform(); - } - - protected override void OnPropertyChanged(string propertyName = null) - { - base.OnPropertyChanged(propertyName); - - if (propertyName == nameof(AutoSize)) - { - SyncAllowAutoGrowthToPlatform(); - } - } - - void SyncAllowAutoGrowthToPlatform() - { - if (Handler?.PlatformView is MauiTextView textView) - { - textView.AllowAutoGrowth = AutoSize == EditorAutoSizeOption.TextChanges; - } - } } } diff --git a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt index 955b7c611b39..21d15383214b 100644 --- a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt @@ -6,5 +6,3 @@ override Microsoft.Maui.Controls.Platform.Compatibility.ShellTableViewController ~override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.DisconnectHandler(UIKit.UIView platformView) -> void override Microsoft.Maui.Controls.Platform.Compatibility.ShellItemRenderer.ViewDidAppear(bool animated) -> void ~override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRenderer.DidMoveToParentViewController(UIKit.UIViewController parent) -> void -override Microsoft.Maui.Controls.Editor.OnHandlerChanged() -> void -~override Microsoft.Maui.Controls.Editor.OnPropertyChanged(string propertyName = null) -> void diff --git a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt index 955b7c611b39..21d15383214b 100644 --- a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt @@ -6,5 +6,3 @@ override Microsoft.Maui.Controls.Platform.Compatibility.ShellTableViewController ~override Microsoft.Maui.Controls.Handlers.Items2.CollectionViewHandler2.DisconnectHandler(UIKit.UIView platformView) -> void override Microsoft.Maui.Controls.Platform.Compatibility.ShellItemRenderer.ViewDidAppear(bool animated) -> void ~override Microsoft.Maui.Controls.Platform.Compatibility.ShellSectionRenderer.DidMoveToParentViewController(UIKit.UIViewController parent) -> void -override Microsoft.Maui.Controls.Editor.OnHandlerChanged() -> void -~override Microsoft.Maui.Controls.Editor.OnPropertyChanged(string propertyName = null) -> void From d7b42a9e0ddead08d5626d40486991a25c96d149 Mon Sep 17 00:00:00 2001 From: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com> Date: Thu, 30 Apr 2026 18:10:40 +0530 Subject: [PATCH 03/12] changes updated. --- src/Controls/src/Core/Editor/Editor.Mapper.cs | 2 ++ src/Controls/src/Core/Editor/Editor.cs | 1 + 2 files changed, 3 insertions(+) diff --git a/src/Controls/src/Core/Editor/Editor.Mapper.cs b/src/Controls/src/Core/Editor/Editor.Mapper.cs index 887be9816053..d59db8daa7c7 100644 --- a/src/Controls/src/Core/Editor/Editor.Mapper.cs +++ b/src/Controls/src/Core/Editor/Editor.Mapper.cs @@ -29,7 +29,9 @@ public partial class Editor EditorHandler.Mapper.AppendToMapping(nameof(AutoSize), (handler, editor) => { if (handler.PlatformView is Microsoft.Maui.Platform.MauiTextView textView) + { textView.AllowAutoGrowth = editor.AutoSize == EditorAutoSizeOption.TextChanges; + } }); #endif diff --git a/src/Controls/src/Core/Editor/Editor.cs b/src/Controls/src/Core/Editor/Editor.cs index 38de223295cd..58454cc4a52d 100644 --- a/src/Controls/src/Core/Editor/Editor.cs +++ b/src/Controls/src/Core/Editor/Editor.cs @@ -93,6 +93,7 @@ void UpdateAutoSizeOption() { if (AutoSize == EditorAutoSizeOption.TextChanges && this.IsShimmed()) InvalidateMeasure(); + Handler?.UpdateValue(nameof(AutoSize)); } From 7d73cef9b76a5e38da421be3b82eced1e6a6caee Mon Sep 17 00:00:00 2001 From: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com> Date: Thu, 30 Apr 2026 19:05:14 +0530 Subject: [PATCH 04/12] Fix updated --- src/Controls/src/Core/Editor/Editor.Mapper.cs | 10 ---------- src/Controls/src/Core/Editor/Editor.iOS.cs | 11 +++++++++++ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Controls/src/Core/Editor/Editor.Mapper.cs b/src/Controls/src/Core/Editor/Editor.Mapper.cs index d59db8daa7c7..0258acedebea 100644 --- a/src/Controls/src/Core/Editor/Editor.Mapper.cs +++ b/src/Controls/src/Core/Editor/Editor.Mapper.cs @@ -25,16 +25,6 @@ public partial class Editor } #endif -#if IOS || MACCATALYST - EditorHandler.Mapper.AppendToMapping(nameof(AutoSize), (handler, editor) => - { - if (handler.PlatformView is Microsoft.Maui.Platform.MauiTextView textView) - { - textView.AllowAutoGrowth = editor.AutoSize == EditorAutoSizeOption.TextChanges; - } - }); -#endif - #if IOS || ANDROID EditorHandler.Mapper.AppendToMapping(nameof(VisualElement.IsFocused), InputView.MapIsFocused); EditorHandler.Mapper.AppendToMapping(nameof(VisualElement.IsVisible), InputView.MapIsVisible); diff --git a/src/Controls/src/Core/Editor/Editor.iOS.cs b/src/Controls/src/Core/Editor/Editor.iOS.cs index 1430b10cb4dc..b362f38a171c 100644 --- a/src/Controls/src/Core/Editor/Editor.iOS.cs +++ b/src/Controls/src/Core/Editor/Editor.iOS.cs @@ -3,6 +3,17 @@ namespace Microsoft.Maui.Controls { public partial class Editor { + static Editor() + { + EditorHandler.Mapper.AppendToMapping(nameof(AutoSize), (handler, editor) => + { + if (handler.PlatformView is Microsoft.Maui.Platform.MauiTextView textView) + { + textView.AllowAutoGrowth = editor.AutoSize == EditorAutoSizeOption.TextChanges; + } + }); + } + public static void MapText(EditorHandler handler, Editor editor) => MapText((IEditorHandler)handler, editor); From 5103c08e08cb6ebab0ae0b016798acf8382f55e5 Mon Sep 17 00:00:00 2001 From: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com> Date: Thu, 30 Apr 2026 19:46:00 +0530 Subject: [PATCH 05/12] Update EditorHandler.iOS.cs --- .../src/Handlers/Editor/EditorHandler.iOS.cs | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs b/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs index 0e8a9e909f43..f8d84c1851ff 100644 --- a/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs +++ b/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs @@ -54,24 +54,6 @@ public override bool NeedsContainer public override Size GetDesiredSize(double widthConstraint, double heightConstraint) { - // When the editor's content overflows its current frame (i.e., it's scrollable), - // cap the returned height to preserve scrollability. Without this, rotation triggers - // a re-measurement that returns the full content height, causing the editor - // to grow and lose scrollability (fixes #35114). - // Skip capping when AllowAutoGrowth is set (AutoSize=TextChanges mode), - // because in that mode the Editor is expected to grow to fit its content. - double capHeight = 0; - bool shouldCapHeight = false; - if (double.IsInfinity(heightConstraint) && !PlatformView.AllowAutoGrowth) - { - var currentHeight = (double)PlatformView.Bounds.Height; - if (currentHeight > 0 && PlatformView.ContentSize.Height > currentHeight) - { - shouldCapHeight = true; - capHeight = currentHeight; - } - } - if (double.IsInfinity(widthConstraint) || double.IsInfinity(heightConstraint)) { // If we drop an infinite value into base.GetDesiredSize for the Editor, we'll @@ -87,15 +69,25 @@ public override Size GetDesiredSize(double widthConstraint, double heightConstra if (double.IsInfinity(heightConstraint)) { - heightConstraint = sizeThatFits.Height; + var currentHeight = (double)PlatformView.Bounds.Height; + if (!PlatformView.AllowAutoGrowth + && currentHeight > 0 + && PlatformView.ContentSize.Height > currentHeight) + { + heightConstraint = currentHeight; + } + else + { + heightConstraint = sizeThatFits.Height; + } } } var result = base.GetDesiredSize(widthConstraint, heightConstraint); - if (shouldCapHeight && result.Height > capHeight) + if (result.Height > heightConstraint) { - return new Size(result.Width, capHeight); + return new Size(result.Width, heightConstraint); } return result; From d1a561c6886df5edd5e410a4e3a1745db1e5bd62 Mon Sep 17 00:00:00 2001 From: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com> Date: Thu, 30 Apr 2026 19:51:52 +0530 Subject: [PATCH 06/12] Update EditorHandler.iOS.cs --- src/Core/src/Handlers/Editor/EditorHandler.iOS.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs b/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs index f8d84c1851ff..db3f072d77eb 100644 --- a/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs +++ b/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs @@ -70,6 +70,10 @@ public override Size GetDesiredSize(double widthConstraint, double heightConstra if (double.IsInfinity(heightConstraint)) { var currentHeight = (double)PlatformView.Bounds.Height; + + // When content overflows the frame and auto-growth is off, cap the height + // to the current frame height to preserve scrollability after rotation (#35114). + // Skip when AllowAutoGrowth is set (AutoSize=TextChanges) — Editor should grow freely. if (!PlatformView.AllowAutoGrowth && currentHeight > 0 && PlatformView.ContentSize.Height > currentHeight) @@ -85,6 +89,8 @@ public override Size GetDesiredSize(double widthConstraint, double heightConstra var result = base.GetDesiredSize(widthConstraint, heightConstraint); + // UITextView (a UIScrollView subclass) ignores the height in SizeThatFits and always + // returns the full content height. Cap the result to enforce the constraint. if (result.Height > heightConstraint) { return new Size(result.Width, heightConstraint); From b28cea54576bfb31aa2671760634a61f0b799aa9 Mon Sep 17 00:00:00 2001 From: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com> Date: Tue, 5 May 2026 16:04:58 +0530 Subject: [PATCH 07/12] Update Editor.Mapper.cs --- src/Controls/src/Core/Editor/Editor.Mapper.cs | 10 ++++++++++ src/Controls/src/Core/Editor/Editor.iOS.cs | 11 ----------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/Controls/src/Core/Editor/Editor.Mapper.cs b/src/Controls/src/Core/Editor/Editor.Mapper.cs index 0258acedebea..e4147cb9e8b6 100644 --- a/src/Controls/src/Core/Editor/Editor.Mapper.cs +++ b/src/Controls/src/Core/Editor/Editor.Mapper.cs @@ -30,6 +30,16 @@ public partial class Editor EditorHandler.Mapper.AppendToMapping(nameof(VisualElement.IsVisible), InputView.MapIsVisible); #endif +#if IOS || MACCATALYST + EditorHandler.Mapper.AppendToMapping(nameof(AutoSize), (handler, editor) => + { + if (handler.PlatformView is Microsoft.Maui.Platform.MauiTextView textView) + { + textView.AllowAutoGrowth = editor.AutoSize == EditorAutoSizeOption.TextChanges; + } + }); +#endif + #if ANDROID EditorHandler.CommandMapper.PrependToMapping(nameof(IEditor.Focus), InputView.MapFocus); #endif diff --git a/src/Controls/src/Core/Editor/Editor.iOS.cs b/src/Controls/src/Core/Editor/Editor.iOS.cs index b362f38a171c..1430b10cb4dc 100644 --- a/src/Controls/src/Core/Editor/Editor.iOS.cs +++ b/src/Controls/src/Core/Editor/Editor.iOS.cs @@ -3,17 +3,6 @@ namespace Microsoft.Maui.Controls { public partial class Editor { - static Editor() - { - EditorHandler.Mapper.AppendToMapping(nameof(AutoSize), (handler, editor) => - { - if (handler.PlatformView is Microsoft.Maui.Platform.MauiTextView textView) - { - textView.AllowAutoGrowth = editor.AutoSize == EditorAutoSizeOption.TextChanges; - } - }); - } - public static void MapText(EditorHandler handler, Editor editor) => MapText((IEditorHandler)handler, editor); From 064487ccdb2489ce067143755b6f946aaf38ded6 Mon Sep 17 00:00:00 2001 From: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com> Date: Tue, 5 May 2026 16:16:37 +0530 Subject: [PATCH 08/12] Update Editor.iOS.cs --- src/Controls/src/Core/Editor/Editor.Mapper.cs | 8 +------- src/Controls/src/Core/Editor/Editor.iOS.cs | 8 ++++++++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Controls/src/Core/Editor/Editor.Mapper.cs b/src/Controls/src/Core/Editor/Editor.Mapper.cs index e4147cb9e8b6..e76abb40f447 100644 --- a/src/Controls/src/Core/Editor/Editor.Mapper.cs +++ b/src/Controls/src/Core/Editor/Editor.Mapper.cs @@ -31,13 +31,7 @@ public partial class Editor #endif #if IOS || MACCATALYST - EditorHandler.Mapper.AppendToMapping(nameof(AutoSize), (handler, editor) => - { - if (handler.PlatformView is Microsoft.Maui.Platform.MauiTextView textView) - { - textView.AllowAutoGrowth = editor.AutoSize == EditorAutoSizeOption.TextChanges; - } - }); + EditorHandler.Mapper.AppendToMapping(nameof(AutoSize), MapAutoSize); #endif #if ANDROID diff --git a/src/Controls/src/Core/Editor/Editor.iOS.cs b/src/Controls/src/Core/Editor/Editor.iOS.cs index 1430b10cb4dc..b15b478d1cec 100644 --- a/src/Controls/src/Core/Editor/Editor.iOS.cs +++ b/src/Controls/src/Core/Editor/Editor.iOS.cs @@ -3,6 +3,14 @@ namespace Microsoft.Maui.Controls { public partial class Editor { + internal static void MapAutoSize(IEditorHandler handler, Editor editor) + { + if (handler.PlatformView is Microsoft.Maui.Platform.MauiTextView textView) + { + textView.AllowAutoGrowth = editor.AutoSize == EditorAutoSizeOption.TextChanges; + } + } + public static void MapText(EditorHandler handler, Editor editor) => MapText((IEditorHandler)handler, editor); From c46c548bd08a092a547c67b7a73bc365c07bb4cb Mon Sep 17 00:00:00 2001 From: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com> Date: Tue, 5 May 2026 16:39:21 +0530 Subject: [PATCH 09/12] Update Editor.cs --- src/Controls/src/Core/Editor/Editor.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Controls/src/Core/Editor/Editor.cs b/src/Controls/src/Core/Editor/Editor.cs index 58454cc4a52d..b7f85625537d 100644 --- a/src/Controls/src/Core/Editor/Editor.cs +++ b/src/Controls/src/Core/Editor/Editor.cs @@ -93,8 +93,6 @@ void UpdateAutoSizeOption() { if (AutoSize == EditorAutoSizeOption.TextChanges && this.IsShimmed()) InvalidateMeasure(); - - Handler?.UpdateValue(nameof(AutoSize)); } /// From 819f6fe0f846790c4cc26f4e7be6299d0628c8ad Mon Sep 17 00:00:00 2001 From: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com> Date: Tue, 5 May 2026 16:47:11 +0530 Subject: [PATCH 10/12] Update Editor.iOS.cs --- src/Controls/src/Core/Editor/Editor.iOS.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Controls/src/Core/Editor/Editor.iOS.cs b/src/Controls/src/Core/Editor/Editor.iOS.cs index b15b478d1cec..93b1319df8f3 100644 --- a/src/Controls/src/Core/Editor/Editor.iOS.cs +++ b/src/Controls/src/Core/Editor/Editor.iOS.cs @@ -3,6 +3,7 @@ namespace Microsoft.Maui.Controls { public partial class Editor { + // TODO: Make this public in .NET 11 internal static void MapAutoSize(IEditorHandler handler, Editor editor) { if (handler.PlatformView is Microsoft.Maui.Platform.MauiTextView textView) From 885eb620824bb34b5032238c8d990a61c4e4b0f3 Mon Sep 17 00:00:00 2001 From: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com> Date: Wed, 6 May 2026 12:35:04 +0530 Subject: [PATCH 11/12] Addressed concerns. --- .../Elements/Editor/EditorTests.iOS.cs | 50 +++++++++++++++++++ .../TestCases.HostApp/Issues/Issue35114.cs | 2 +- .../Tests/Issues/Issue35114.cs | 2 +- .../src/Handlers/Editor/EditorHandler.iOS.cs | 8 ++- 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/src/Controls/tests/DeviceTests/Elements/Editor/EditorTests.iOS.cs b/src/Controls/tests/DeviceTests/Elements/Editor/EditorTests.iOS.cs index 1a234254f127..a9326b70579e 100644 --- a/src/Controls/tests/DeviceTests/Elements/Editor/EditorTests.iOS.cs +++ b/src/Controls/tests/DeviceTests/Elements/Editor/EditorTests.iOS.cs @@ -64,6 +64,56 @@ Task GetPlatformIsVisible(EditorHandler editorHandler) }); } + [Fact] + [Description("Editor with AutoSize=TextChanges should continue to grow after a simulated rotation (width constraint change)")] + public async Task AutoSizeTextChangesEditorGrowsAfterRotation() + { + // Regression test for https://github.com/dotnet/maui/issues/35114 + // Verifies that AllowAutoGrowth remains true after a width constraint change + // (which is what happens internally during portrait↔landscape rotation). + SetupBuilder(); + + var editor = new Editor + { + AutoSize = EditorAutoSizeOption.TextChanges, + Text = "Line1\nLine2\nLine3", + WidthRequest = 200, + }; + + var layout = new VerticalStackLayout + { + WidthRequest = 200, + HorizontalOptions = LayoutOptions.Start, + VerticalOptions = LayoutOptions.Start, + Children = { editor } + }; + + await AttachAndRun(layout, async (_) => + { + var frame = editor.Frame; + await WaitForUIUpdate(frame, editor); + var heightBeforeRotation = editor.Height; + + // Simulate rotation: portrait → landscape (widen) → portrait (narrow) + frame = editor.Frame; + layout.WidthRequest = 400; + await WaitForUIUpdate(frame, editor); + + frame = editor.Frame; + layout.WidthRequest = 200; + await WaitForUIUpdate(frame, editor); + + // After simulated rotation, typing more text should still grow the editor + frame = editor.Frame; + editor.Text += "\nLine4\nLine5\nLine6"; + await WaitForUIUpdate(frame, editor); + + Assert.True(editor.Height > heightBeforeRotation, + $"Editor with AutoSize=TextChanges should still grow after rotation. Before: {heightBeforeRotation}, After: {editor.Height}"); + }); + } + + [Category(TestCategory.Editor)] public class PlaceholderTests : ControlsHandlerTestBase { diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue35114.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue35114.cs index 9d098c6760ac..8ff1d79c5872 100644 --- a/src/Controls/tests/TestCases.HostApp/Issues/Issue35114.cs +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue35114.cs @@ -5,7 +5,7 @@ public class Issue35114 : ContentPage { public Issue35114() { - Title = "D2"; + Title = "Issue 35114"; var slider = new Slider { diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35114.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35114.cs index 4d2d6c69c903..206ee2006bd5 100644 --- a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35114.cs +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35114.cs @@ -44,7 +44,7 @@ public void EditorCanBeScrolledAfterRotation() var editorRectAfter = App.WaitForElement("TestEditor").GetRect(); var heightAfter = editorRectAfter.Height; - Assert.That(heightAfter, Is.EqualTo(heightBefore), + Assert.That(heightAfter, Is.EqualTo(heightBefore).Within(1), $"Editor height should not grow after rotation. Before: {heightBefore}, After: {heightAfter}"); } } diff --git a/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs b/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs index db3f072d77eb..3bd314c01e9b 100644 --- a/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs +++ b/src/Core/src/Handlers/Editor/EditorHandler.iOS.cs @@ -71,6 +71,9 @@ public override Size GetDesiredSize(double widthConstraint, double heightConstra { var currentHeight = (double)PlatformView.Bounds.Height; + // NOTE: Bounds and ContentSize reflect the pre-rotation frame at this point. + // The check is intentionally based on the previous layout state to detect + // scrollable Editors that should not grow after cache invalidation (#35114). // When content overflows the frame and auto-growth is off, cap the height // to the current frame height to preserve scrollability after rotation (#35114). // Skip when AllowAutoGrowth is set (AutoSize=TextChanges) — Editor should grow freely. @@ -89,8 +92,9 @@ public override Size GetDesiredSize(double widthConstraint, double heightConstra var result = base.GetDesiredSize(widthConstraint, heightConstraint); - // UITextView (a UIScrollView subclass) ignores the height in SizeThatFits and always - // returns the full content height. Cap the result to enforce the constraint. + // Cap applies even for finite constraints: UITextView.SizeThatFits (UIScrollView subclass) + // ignores the height argument and always returns full content height. + // Capping here ensures GetDesiredSize honours the caller's constraint. if (result.Height > heightConstraint) { return new Size(result.Width, heightConstraint); From 6ebe508a75a43c83057e5bb89b3f05e2f73407d3 Mon Sep 17 00:00:00 2001 From: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com> Date: Wed, 6 May 2026 14:17:07 +0530 Subject: [PATCH 12/12] Addressed copilot comments. --- src/Controls/tests/TestCases.HostApp/Issues/Issue35114.cs | 5 +++-- .../tests/TestCases.Shared.Tests/Tests/Issues/Issue35114.cs | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue35114.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue35114.cs index 8ff1d79c5872..cc37199e1f49 100644 --- a/src/Controls/tests/TestCases.HostApp/Issues/Issue35114.cs +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue35114.cs @@ -27,8 +27,9 @@ public Issue35114() { Children = { - new Label { Text = "1. Play with the value of the slider below and observe as the space between characters widens." }, - new Label { Text = "2. The tests fails if the space between characters does not change." }, + new Label { Text = "1. Drag the slider to the right to increase character spacing on the Editor." }, + new Label { Text = "2. Rotate the device to landscape and back to portrait." }, + new Label { Text = "3. The test fails if the Editor grows to full content height after rotation (it should remain scrollable)." }, slider, editor } diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35114.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35114.cs index 206ee2006bd5..b225f400ae1a 100644 --- a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35114.cs +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35114.cs @@ -13,6 +13,12 @@ public Issue35114(TestDevice device) : base(device) public override string Issue => "Editor can not be scrolled after rotating simulator"; + [TearDown] + public void TearDown() + { + App.SetOrientationPortrait(); + } + [Test] [Category(UITestCategories.Editor)] public void EditorCanBeScrolledAfterRotation()