diff --git a/src/Controls/tests/TestCases.HostApp/Issues/EditorTextChangedIOS26.xaml b/src/Controls/tests/TestCases.HostApp/Issues/EditorTextChangedIOS26.xaml new file mode 100644 index 000000000000..a40c87c5c6df --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/EditorTextChangedIOS26.xaml @@ -0,0 +1,32 @@ + + + + + + + + diff --git a/src/Controls/tests/TestCases.HostApp/Issues/EditorTextChangedIOS26.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/EditorTextChangedIOS26.xaml.cs new file mode 100644 index 000000000000..8a240c74c387 --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/EditorTextChangedIOS26.xaml.cs @@ -0,0 +1,21 @@ +namespace Maui.Controls.Sample.Issues +{ + [Issue(IssueTracker.Github, 0, "Editor TextChanged event not firing on iOS 26.1 release build", + PlatformAffected.iOS)] + public partial class EditorTextChangedIOS26 : ContentPage + { + private int _eventCount = 0; + + public EditorTextChangedIOS26() + { + InitializeComponent(); + } + + private void OnEditorTextChanged(object sender, TextChangedEventArgs e) + { + _eventCount++; + EventCountLabel.Text = $"TextChanged event count: {_eventCount}"; + LastTextLabel.Text = $"Last text: {(string.IsNullOrEmpty(e.NewTextValue) ? "(empty)" : e.NewTextValue)}"; + } + } +} diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/EditorTextChangedIOS26.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/EditorTextChangedIOS26.cs new file mode 100644 index 000000000000..0affde3ef8cb --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/EditorTextChangedIOS26.cs @@ -0,0 +1,48 @@ +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues +{ + internal class EditorTextChangedIOS26 : _IssuesUITest + { + public override string Issue => "Editor TextChanged event not firing on iOS 26.1 release build"; + + public EditorTextChangedIOS26(TestDevice device) : base(device) + { + } + + [Test] + [Category(UITestCategories.Editor)] + public void EditorTextChangedEventShouldFireOnTextInput() + { + // Wait for the editor to be visible + App.WaitForElement("TestEditor"); + + // Verify initial state + var initialCount = App.FindElement("EventCountLabel").GetText(); + Assert.That(initialCount, Is.EqualTo("TextChanged event count: 0")); + + // Type text in the editor + App.Tap("TestEditor"); + App.EnterText("TestEditor", "Hello"); + + // Wait a bit for the event to fire + App.WaitForElement("EventCountLabel"); + + // Verify that TextChanged event was fired + var eventCount = App.FindElement("EventCountLabel").GetText(); + Assert.That(eventCount, Does.Contain("TextChanged event count:")); + + // The count should be greater than 0, indicating the event fired + // Extract the number from "TextChanged event count: X" + var countText = eventCount.Replace("TextChanged event count:", "").Trim(); + int count = int.Parse(countText); + Assert.That(count, Is.GreaterThan(0), "TextChanged event should have fired at least once"); + + // Verify the text was captured + var lastText = App.FindElement("LastTextLabel").GetText(); + Assert.That(lastText, Does.Contain("Hello"), "Last text should contain the entered text"); + } + } +} diff --git a/src/Core/src/Platform/iOS/MauiTextView.cs b/src/Core/src/Platform/iOS/MauiTextView.cs index abd5be6475b1..4ca36316f9e2 100644 --- a/src/Core/src/Platform/iOS/MauiTextView.cs +++ b/src/Core/src/Platform/iOS/MauiTextView.cs @@ -154,6 +154,7 @@ void HidePlaceholderIfTextIsPresent(string? value) _placeholderLabel.Hidden = !string.IsNullOrEmpty(value); } + [UnconditionalSuppressMessage("Memory", "MEM0003", Justification = "Event handler for UITextView.Changed - proven safe in test: MemoryTests.HandlerDoesNotLeak")] void OnChanged(object? sender, EventArgs e) { HidePlaceholderIfTextIsPresent(Text);