diff --git a/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchBarClearButtonShouldBeVisibleWithText.png b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchBarClearButtonShouldBeVisibleWithText.png new file mode 100644 index 000000000000..b6ef2e77f979 Binary files /dev/null and b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchBarClearButtonShouldBeVisibleWithText.png differ diff --git a/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchBarClearButtonShouldDisappearAfterClearingInput.png b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchBarClearButtonShouldDisappearAfterClearingInput.png new file mode 100644 index 000000000000..6e9c3287db97 Binary files /dev/null and b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchBarClearButtonShouldDisappearAfterClearingInput.png differ diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue34422.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue34422.cs new file mode 100644 index 000000000000..63fb9e2df749 --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue34422.cs @@ -0,0 +1,50 @@ +namespace Maui.Controls.Sample.Issues; + +[Issue(IssueTracker.Github, 34422, "SearchBar clear button still appears on MacCatalyst after clearing input", PlatformAffected.macOS)] +public class Issue34422 : ContentPage +{ + readonly SearchBar _searchBar; + + public Issue34422() + { + _searchBar = new SearchBar + { + Placeholder = "Search...", + AutomationId = "TestSearchBar" + }; + + var addTextButton = new Button + { + Text = "Add Text", + AutomationId = "AddTextButton" + }; + + addTextButton.Clicked += (s, e) => + { + _searchBar.Text = "Search text"; + }; + + var clearButton = new Button + { + Text = "Clear SearchBar Text", + AutomationId = "ClearButton" + }; + + clearButton.Clicked += (s, e) => + { + _searchBar.Text = string.Empty; + }; + + Content = new VerticalStackLayout + { + Padding = new Thickness(20), + Spacing = 10, + Children = + { + _searchBar, + addTextButton, + clearButton + } + }; + } +} diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SearchBarClearButtonShouldBeVisibleWithText.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SearchBarClearButtonShouldBeVisibleWithText.png new file mode 100644 index 000000000000..53e2df90416f Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SearchBarClearButtonShouldBeVisibleWithText.png differ diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SearchBarClearButtonShouldDisappearAfterClearingInput.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SearchBarClearButtonShouldDisappearAfterClearingInput.png new file mode 100644 index 000000000000..941c51781046 Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/SearchBarClearButtonShouldDisappearAfterClearingInput.png differ diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34422.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34422.cs new file mode 100644 index 000000000000..7c57fa8ddc97 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34422.cs @@ -0,0 +1,34 @@ +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue34422 : _IssuesUITest +{ + public Issue34422(TestDevice device) : base(device) { } + + public override string Issue => "SearchBar clear button still appears on MacCatalyst after clearing input"; + + [Test, Order(1)] + [Category(UITestCategories.SearchBar)] + public void SearchBarClearButtonShouldBeVisibleWithText() + { + App.WaitForElement("TestSearchBar"); + App.Tap("TestSearchBar"); + App.Tap("AddTextButton"); + VerifyScreenshot(); + } + + [Test, Order(2)] + [Category(UITestCategories.SearchBar)] + public void SearchBarClearButtonShouldDisappearAfterClearingInput() + { + // First add text so the clear button appears + App.WaitForElement("TestSearchBar"); + App.Tap("TestSearchBar"); + App.Tap("AddTextButton"); + App.Tap("ClearButton"); + VerifyScreenshot(); + } +} diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SearchBarClearButtonShouldBeVisibleWithText.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SearchBarClearButtonShouldBeVisibleWithText.png new file mode 100644 index 000000000000..a48ab8353549 Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SearchBarClearButtonShouldBeVisibleWithText.png differ diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SearchBarClearButtonShouldDisappearAfterClearingInput.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SearchBarClearButtonShouldDisappearAfterClearingInput.png new file mode 100644 index 000000000000..1c355cdc7ef4 Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/SearchBarClearButtonShouldDisappearAfterClearingInput.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchBarClearButtonShouldBeVisibleWithText.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchBarClearButtonShouldBeVisibleWithText.png new file mode 100644 index 000000000000..28a770dbc0d7 Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchBarClearButtonShouldBeVisibleWithText.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchBarClearButtonShouldDisappearAfterClearingInput.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchBarClearButtonShouldDisappearAfterClearingInput.png new file mode 100644 index 000000000000..3143bd2685e8 Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchBarClearButtonShouldDisappearAfterClearingInput.png differ diff --git a/src/Core/src/Handlers/SearchBar/SearchBarHandler.iOS.cs b/src/Core/src/Handlers/SearchBar/SearchBarHandler.iOS.cs index d304bc5aa273..34f92404136b 100644 --- a/src/Core/src/Handlers/SearchBar/SearchBarHandler.iOS.cs +++ b/src/Core/src/Handlers/SearchBar/SearchBarHandler.iOS.cs @@ -18,7 +18,6 @@ protected override MauiSearchBar CreatePlatformView() _editor = searchBar.GetSearchTextField(); - return searchBar; } @@ -154,6 +153,9 @@ internal static void MapSelectionLength(ISearchBarHandler handler, ISearchBar se public static void MapCancelButtonColor(ISearchBarHandler handler, ISearchBar searchBar) { handler.PlatformView?.UpdateCancelButton(searchBar); + if (handler is SearchBarHandler searchBarHandler) + handler.PlatformView?.UpdateClearButtonVisibility(!string.IsNullOrEmpty(searchBar.Text)); + } internal static void MapSearchIconColor(ISearchBarHandler handler, ISearchBar searchBar) @@ -277,6 +279,7 @@ void OnEditingChanged(object? sender, EventArgs e) if (Handler is SearchBarHandler handler) { handler.UpdateCancelButtonVisibility(); + handler.PlatformView?.UpdateClearButtonVisibility(!string.IsNullOrEmpty(VirtualView?.Text)); } } diff --git a/src/Core/src/Platform/iOS/SearchBarExtensions.cs b/src/Core/src/Platform/iOS/SearchBarExtensions.cs index a8b498e4ed62..3af31e1cf07d 100644 --- a/src/Core/src/Platform/iOS/SearchBarExtensions.cs +++ b/src/Core/src/Platform/iOS/SearchBarExtensions.cs @@ -99,6 +99,24 @@ public static void UpdateFont(this UISearchBar uiSearchBar, ITextStyle textStyle textField.UpdateFont(textStyle, fontManager); } + internal static void UpdateClearButtonVisibility(this UISearchBar uiSearchBar, bool hasText) + { + if (OperatingSystem.IsMacCatalyst()) + { + var clearButton = uiSearchBar.GetClearButton(); + + if (clearButton != null) + { + var shouldHide = !hasText; + + if (clearButton.Hidden != shouldHide) + { + clearButton.Hidden = shouldHide; + } + } + } + } + public static void UpdateVerticalTextAlignment(this UISearchBar uiSearchBar, ISearchBar searchBar) { uiSearchBar.UpdateVerticalTextAlignment(searchBar, null); @@ -460,5 +478,7 @@ static UITextPosition GetSelectionEnd(UITextField textField, UITextPosition star var end = textField.GetPosition(start, endOffset - startOffset); return end ?? start; } + internal static UIButton? GetClearButton(this UISearchBar searchBar) => + searchBar.GetSearchTextField()?.ValueForKey(new NSString("clearButton")) as UIButton; } } \ No newline at end of file