diff --git a/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellSearchView.cs b/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellSearchView.cs index cd54cebd2b6b..8af2e319b6ec 100644 --- a/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellSearchView.cs +++ b/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellSearchView.cs @@ -184,7 +184,7 @@ protected virtual void LoadView(SearchHandler searchHandler) int padding = (int)context.ToPixels(8); - _searchButton = CreateImageButton(context, searchHandler, SearchHandler.QueryIconProperty, Resource.Drawable.abc_ic_search_api_material, padding, 0, "SearchIcon"); + _searchButton = CreateImageButton(context, searchHandler, SearchHandler.QueryIconProperty, Resource.Drawable.abc_ic_search_api_material, padding, 0, "SearchIcon", searchHandler.TextColor?.ToPlatform()); lp = new LinearLayout.LayoutParams(0, LP.MatchParent) { @@ -211,8 +211,8 @@ protected virtual void LoadView(SearchHandler searchHandler) // A note on accessibility. The _textBlocks hint is what android defaults to reading in the screen // reader. Therefore, we do not need to set something else. - _clearButton = CreateImageButton(context, searchHandler, SearchHandler.ClearIconProperty, Resource.Drawable.abc_ic_clear_material, 0, padding, nameof(SearchHandler.ClearIcon)); - _clearPlaceholderButton = CreateImageButton(context, searchHandler, SearchHandler.ClearPlaceholderIconProperty, -1, 0, padding, nameof(SearchHandler.ClearPlaceholderIcon)); + _clearButton = CreateImageButton(context, searchHandler, SearchHandler.ClearIconProperty, Resource.Drawable.abc_ic_clear_material, 0, padding, nameof(SearchHandler.ClearIcon), searchHandler.CancelButtonColor?.ToPlatform()); + _clearPlaceholderButton = CreateImageButton(context, searchHandler, SearchHandler.ClearPlaceholderIconProperty, -1, 0, padding, nameof(SearchHandler.ClearPlaceholderIcon), searchHandler.TextColor?.ToPlatform()); linearLayout.AddView(_searchButton); linearLayout.AddView(_textBlock); @@ -245,12 +245,62 @@ protected virtual void OnSearchHandlerPropertyChanged(object sender, PropertyCha { _textBlock.Enabled = SearchHandler.IsSearchEnabled; } - else if (e.PropertyName == SearchHandler.ClearPlaceholderEnabledProperty.PropertyName) + else if (e.PropertyName == SearchHandler.QueryIconProperty.PropertyName) { + ApplyImageSource(_searchButton, SearchHandler.QueryIcon, Resource.Drawable.abc_ic_search_api_material, SearchHandler.TextColor?.ToPlatform()); + } + else if (e.PropertyName == SearchHandler.ClearIconProperty.PropertyName) + { + ApplyImageSource(_clearButton, SearchHandler.ClearIcon, Resource.Drawable.abc_ic_clear_material, SearchHandler.CancelButtonColor?.ToPlatform()); + } + else if (e.PropertyName == SearchHandler.ClearPlaceholderIconProperty.PropertyName) + { + ApplyImageSource(_clearPlaceholderButton, SearchHandler.ClearPlaceholderIcon, -1, SearchHandler.TextColor?.ToPlatform()); UpdateClearButtonState(); } } + void ApplyImageSource(AImageButton button, ImageSource image, int defaultImage, AColor? tint = null) + { + if (button is null) + { + return; + } + + void ApplyTint() + { + if (tint.HasValue) + { + button.Drawable?.Mutate(); + button.Drawable?.SetColorFilter(tint.Value, FilterMode.SrcIn); + } + } + + if (image is not null) + { + AutomationPropertiesProvider.SetContentDescription(button, image, null, null); + image.LoadImage(MauiContext, (r) => + { + if (_disposed) + { + return; + } + + button.SetImageDrawable(r?.Value); + ApplyTint(); + }); + } + else if (defaultImage > 0 && ContextCompat.GetDrawable(Context, defaultImage) is Drawable defaultDrawable) + { + button.SetImageDrawable(defaultDrawable); + ApplyTint(); + } + else + { + button.SetImageDrawable(null); + } + } + protected override async void OnAttachedToWindow() { base.OnAttachedToWindow(); @@ -317,7 +367,7 @@ protected virtual void OnSearchButtonClicked(object sender, EventArgs e) { } - AImageButton CreateImageButton(Context context, BindableObject bindable, BindableProperty property, int defaultImage, int leftMargin, int rightMargin, string tag) + AImageButton CreateImageButton(Context context, BindableObject bindable, BindableProperty property, int defaultImage, int leftMargin, int rightMargin, string tag, AColor? tint = null) { var result = new AImageButton(context); result.Tag = tag; @@ -325,23 +375,7 @@ AImageButton CreateImageButton(Context context, BindableObject bindable, Bindabl result.Focusable = false; result.SetScaleType(ImageView.ScaleType.FitCenter); - if (bindable.GetValue(property) is ImageSource image) - { - AutomationPropertiesProvider.SetContentDescription(result, image, null, null); - - image.LoadImage(MauiContext, (r) => - { - result.SetImageDrawable(r?.Value); - }); - } - else if (defaultImage > 0 && ContextCompat.GetDrawable(Context, defaultImage) is Drawable defaultDrawable) - { - result.SetImageDrawable(defaultDrawable); - } - else - { - result.SetImageDrawable(null); - } + ApplyImageSource(result, bindable.GetValue(property) as ImageSource, defaultImage, tint); var lp = new LinearLayout.LayoutParams((int)Context.ToPixels(22), LP.MatchParent) { diff --git a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellPageRendererTracker.cs b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellPageRendererTracker.cs index 0f86606b8330..550f6284d4d9 100644 --- a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellPageRendererTracker.cs +++ b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellPageRendererTracker.cs @@ -948,6 +948,18 @@ protected virtual void OnSearchHandlerPropertyChanged(object sender, PropertyCha { UpdateAutomationId(); } + else if (e.PropertyName == SearchHandler.QueryIconProperty.PropertyName) + { + UpdateSearchBarIcon(_searchController.SearchBar, _searchHandler.QueryIcon, UISearchBarIcon.Search); + } + else if (e.PropertyName == SearchHandler.ClearIconProperty.PropertyName) + { + UpdateSearchBarIcon(_searchController.SearchBar, _searchHandler.ClearIcon, UISearchBarIcon.Clear); + } + else if (e.PropertyName == SearchHandler.ClearPlaceholderIconProperty.PropertyName) + { + UpdateSearchBarIcon(_searchController.SearchBar, _searchHandler.ClearPlaceholderIcon, UISearchBarIcon.Bookmark); + } } void UpdateAutomationId() @@ -1179,10 +1191,59 @@ void SetSearchBarIcon(UISearchBar searchBar, ImageSource source, UISearchBarIcon searchBar.SetImageforSearchBarIcon(newResult, icon, UIControlState.Normal); searchBar.SetImageforSearchBarIcon(newResult, icon, UIControlState.Highlighted); searchBar.SetImageforSearchBarIcon(newResult, icon, UIControlState.Selected); + + // iOS caches the clear button image once it has been shown. After the button + // has appeared (user typed text), SetImageforSearchBarIcon alone won't refresh + // it. Directly update the button subview so dynamic changes are reflected. + if (icon is UISearchBarIcon.Clear) + { + UpdateClearButtonImage(searchBar, newResult); + } } }); } + // Directly updates the clear button (X) inside UISearchBar's UITextField subview. + // This is required because iOS does not re-apply SetImageforSearchBarIcon to a + // clear button that is already visible on screen. + // + // NOTE: "searchField" and "clearButton" are private UIKit KVC keys. Apple does not + // expose these as public API. They have been stable across iOS versions and are a + // well-established pattern in Xamarin/MAUI, but could break in a future OS release. + static void UpdateClearButtonImage(UISearchBar searchBar, UIImage? image) + { + if (searchBar.ValueForKey(new NSString("searchField")) is UITextField textField && + textField.ValueForKey(new NSString("clearButton")) is UIButton clearButton) + { + clearButton.SetImage(image, UIControlState.Normal); + clearButton.SetImage(image, UIControlState.Highlighted); + } + } + + void UpdateSearchBarIcon(UISearchBar searchBar, ImageSource? source, UISearchBarIcon icon) + { + if (source is not null) + { + SetSearchBarIcon(searchBar, source, icon); + } + else + { + // Reset to default system icon by clearing the custom image + searchBar.SetImageforSearchBarIcon(null, icon, UIControlState.Normal); + searchBar.SetImageforSearchBarIcon(null, icon, UIControlState.Highlighted); + searchBar.SetImageforSearchBarIcon(null, icon, UIControlState.Selected); + + if (icon is UISearchBarIcon.Clear) + { + // UIKit caches the clear button image once it is on-screen, so + // SetImageforSearchBarIcon(null, ...) alone will not update the visible + // button. Restore the system default SF Symbol so the button shows the + // standard 'X' instead of becoming imageless. + UpdateClearButtonImage(searchBar, UIImage.GetSystemImage("multiply.circle.fill")); + } + } + } + void OnPageLoaded(object? sender, EventArgs e) { if (sender is Page page) diff --git a/src/Controls/src/Core/Handlers/Shell/ShellItemHandler.Windows.cs b/src/Controls/src/Core/Handlers/Shell/ShellItemHandler.Windows.cs index fe2242915904..435c134ab5db 100644 --- a/src/Controls/src/Core/Handlers/Shell/ShellItemHandler.Windows.cs +++ b/src/Controls/src/Core/Handlers/Shell/ShellItemHandler.Windows.cs @@ -543,6 +543,12 @@ void OnCurrentSearchHandlerPropertyChanged(object? sender, PropertyChangedEventA case nameof(SearchHandler.VerticalTextAlignment): autoSuggestBox.UpdateSearchHandlerVerticalTextAlignment(_currentSearchHandler); break; + case nameof(SearchHandler.QueryIcon): + UpdateQueryIcon(); + break; + // TODO: ClearIcon and ClearPlaceholderIcon are not supported on Windows + // (AutoSuggestBox has no built-in clear/placeholder icon API). + // Tracked in: https://github.com/dotnet/maui/issues/28619 } } diff --git a/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchHandlerClearIconUpdatesAtRuntime.png b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchHandlerClearIconUpdatesAtRuntime.png new file mode 100644 index 000000000000..4f47e06a0255 Binary files /dev/null and b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchHandlerClearIconUpdatesAtRuntime.png differ diff --git a/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchHandlerClearPlaceholderIconUpdatesAtRuntime.png b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchHandlerClearPlaceholderIconUpdatesAtRuntime.png new file mode 100644 index 000000000000..48ace269f70e Binary files /dev/null and b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchHandlerClearPlaceholderIconUpdatesAtRuntime.png differ diff --git a/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchHandlerQueryIconUpdatesAtRuntime.png b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchHandlerQueryIconUpdatesAtRuntime.png new file mode 100644 index 000000000000..beb98a3b2e7f Binary files /dev/null and b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchHandlerQueryIconUpdatesAtRuntime.png differ diff --git a/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchHandlerResetAllRestoresDefaultIcons.png b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchHandlerResetAllRestoresDefaultIcons.png new file mode 100644 index 000000000000..ce6cff55ef69 Binary files /dev/null and b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/SearchHandlerResetAllRestoresDefaultIcons.png differ diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue35736.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue35736.cs new file mode 100644 index 000000000000..0972a415bb8f --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue35736.cs @@ -0,0 +1,146 @@ +namespace Maui.Controls.Sample.Issues; + +[Issue(IssueTracker.Github, 35736, "SearchHandler QueryIcon, ClearIcon, ClearPlaceholderIcon need to update visually at runtime", PlatformAffected.iOS | PlatformAffected.Android | PlatformAffected.UWP)] +public class Issue35736 : Shell +{ + public Issue35736() + { + var page = new Issue35736Page(); + Items.Add(new ShellContent + { + Title = "Search Icon Test", + Content = page + }); + } + + public class Issue35736Page : ContentPage + { + readonly SearchHandler _searchHandler; + bool _useAltQueryIcon; + bool _useAltClearIcon; + bool _useAltClearPlaceholderIcon; + bool _clearPlaceholderEnabled = true; + + readonly Label _queryIconLabel; + readonly Label _clearIconLabel; + readonly Label _clearPlaceholderIconLabel; + readonly Label _clearPlaceholderEnabledLabel; + readonly Button _toggleClearPlaceholderEnabledBtn; + + public Issue35736Page() + { + Title = "Search Icon Test"; + + _searchHandler = new SearchHandler + { + Placeholder = "Search items...", + AutomationId = "Issue35736SearchHandler", + QueryIcon = ImageSource.FromFile("bank.png"), + ClearIcon = ImageSource.FromFile("bank.png"), + ClearPlaceholderIcon = ImageSource.FromFile("bank.png"), + ClearPlaceholderEnabled = true, + ShowsResults = false, + }; + + Shell.SetSearchHandler(this, _searchHandler); + + _queryIconLabel = new Label { AutomationId = "Issue35736QueryIconLabel", Text = "QueryIcon: bank.png" }; + _clearIconLabel = new Label { AutomationId = "Issue35736ClearIconLabel", Text = "ClearIcon: bank.png" }; + _clearPlaceholderIconLabel = new Label { AutomationId = "Issue35736ClearPlaceholderIconLabel", Text = "ClearPlaceholderIcon: bank.png" }; + _clearPlaceholderEnabledLabel = new Label { AutomationId = "Issue35736ClearPlaceholderEnabledLabel", Text = "ClearPlaceholderEnabled: True" }; + + var toggleQueryIconBtn = new Button { Text = "Toggle QueryIcon", AutomationId = "Issue35736ToggleQueryIcon" }; + toggleQueryIconBtn.Clicked += OnToggleQueryIcon; + + var toggleClearIconBtn = new Button { Text = "Toggle ClearIcon", AutomationId = "Issue35736ToggleClearIcon" }; + toggleClearIconBtn.Clicked += OnToggleClearIcon; + + var toggleClearPlaceholderIconBtn = new Button { Text = "Toggle ClearPlaceholderIcon", AutomationId = "Issue35736ToggleClearPlaceholderIcon" }; + toggleClearPlaceholderIconBtn.Clicked += OnToggleClearPlaceholderIcon; + + _toggleClearPlaceholderEnabledBtn = new Button + { + Text = "Toggle ClearPlaceholderEnabled (Current: True)", + AutomationId = "Issue35736ToggleClearPlaceholderEnabled" + }; + _toggleClearPlaceholderEnabledBtn.Clicked += OnToggleClearPlaceholderEnabled; + + var resetBtn = new Button { Text = "Reset All to Defaults", AutomationId = "Issue35736ResetAll" }; + resetBtn.Clicked += OnResetAll; + + Content = new ScrollView + { + Content = new VerticalStackLayout + { + Padding = new Thickness(30, 0), + Spacing = 15, + Children = + { + new Label { Text = "SearchHandler Icon Demo", FontSize = 20, FontAttributes = FontAttributes.Bold, HorizontalOptions = LayoutOptions.Center }, + new VerticalStackLayout + { + Spacing = 4, + Children = { _queryIconLabel, _clearIconLabel, _clearPlaceholderIconLabel, _clearPlaceholderEnabledLabel } + }, + toggleQueryIconBtn, + toggleClearIconBtn, + toggleClearPlaceholderIconBtn, + _toggleClearPlaceholderEnabledBtn, + resetBtn, + } + } + }; + } + + void OnToggleQueryIcon(object sender, EventArgs e) + { + _useAltQueryIcon = !_useAltQueryIcon; + var icon = _useAltQueryIcon ? "calculator.png" : "bank.png"; + _searchHandler.QueryIcon = ImageSource.FromFile(icon); + _queryIconLabel.Text = $"QueryIcon: {icon}"; + } + + void OnToggleClearIcon(object sender, EventArgs e) + { + _useAltClearIcon = !_useAltClearIcon; + var icon = _useAltClearIcon ? "calculator.png" : "bank.png"; + _searchHandler.ClearIcon = ImageSource.FromFile(icon); + _clearIconLabel.Text = $"ClearIcon: {icon}"; + } + + void OnToggleClearPlaceholderIcon(object sender, EventArgs e) + { + _useAltClearPlaceholderIcon = !_useAltClearPlaceholderIcon; + var icon = _useAltClearPlaceholderIcon ? "calculator.png" : "bank.png"; + _searchHandler.ClearPlaceholderIcon = ImageSource.FromFile(icon); + _clearPlaceholderIconLabel.Text = $"ClearPlaceholderIcon: {icon}"; + } + + void OnToggleClearPlaceholderEnabled(object sender, EventArgs e) + { + _clearPlaceholderEnabled = !_clearPlaceholderEnabled; + _searchHandler.ClearPlaceholderEnabled = _clearPlaceholderEnabled; + _clearPlaceholderEnabledLabel.Text = $"ClearPlaceholderEnabled: {_clearPlaceholderEnabled}"; + _toggleClearPlaceholderEnabledBtn.Text = $"Toggle ClearPlaceholderEnabled (Current: {_clearPlaceholderEnabled})"; + } + + void OnResetAll(object sender, EventArgs e) + { + _useAltQueryIcon = false; + _useAltClearIcon = false; + _useAltClearPlaceholderIcon = false; + _clearPlaceholderEnabled = true; + + _searchHandler.QueryIcon = null; + _searchHandler.ClearIcon = null; + _searchHandler.ClearPlaceholderIcon = null; + _searchHandler.ClearPlaceholderEnabled = true; + + _queryIconLabel.Text = "QueryIcon: default"; + _clearIconLabel.Text = "ClearIcon: default"; + _clearPlaceholderIconLabel.Text = "ClearPlaceholderIcon: default"; + _clearPlaceholderEnabledLabel.Text = "ClearPlaceholderEnabled: True"; + _toggleClearPlaceholderEnabledBtn.Text = "Toggle ClearPlaceholderEnabled (Current: True)"; + } + } +} diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35736.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35736.cs new file mode 100644 index 000000000000..097d981a0512 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue35736.cs @@ -0,0 +1,75 @@ +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue35736 : _IssuesUITest +{ + public Issue35736(TestDevice device) : base(device) { } + + public override string Issue => "SearchHandler QueryIcon, ClearIcon, ClearPlaceholderIcon need to update visually at runtime"; + + [Test] + [Category(UITestCategories.Shell)] + public void SearchHandlerQueryIconUpdatesAtRuntime() + { + App.WaitForElement("Issue35736QueryIconLabel"); + + App.Tap("Issue35736ToggleQueryIcon"); + App.WaitForElement("Issue35736QueryIconLabel"); + + VerifyScreenshot(); + } + + [Test] + [Category(UITestCategories.Shell)] +#if WINDOWS + [Ignore("ClearPlaceholderIcon is not displayed in Shell SearchHander : https://github.com/dotnet/maui/issues/28619")] +#endif + public void SearchHandlerClearPlaceholderIconUpdatesAtRuntime() + { + App.WaitForElement("Issue35736ClearPlaceholderIconLabel"); + + App.Tap("Issue35736ToggleClearPlaceholderIcon"); + App.WaitForElement("Issue35736ClearPlaceholderIconLabel"); + + VerifyScreenshot(); + } + + [Test] + [Category(UITestCategories.Shell)] +#if WINDOWS + [Ignore("ClearIcon is not displayed in Shell SearchHander : https://github.com/dotnet/maui/issues/28619")] +#endif + public void SearchHandlerClearIconUpdatesAtRuntime() + { + App.WaitForElement("Issue35736ClearIconLabel"); + + App.Tap("Issue35736ToggleClearIcon"); + // Type text so the clear (X) button becomes visible + App.EnterTextInShellSearchHandler("A"); + + App.WaitForElement("Issue35736ClearIconLabel"); + + VerifyScreenshot(); + } + + [Test] + [Category(UITestCategories.Shell)] + public void SearchHandlerResetAllRestoresDefaultIcons() + { + App.WaitForElement("Issue35736QueryIconLabel"); + + // Change all icons first (including ClearIcon) + App.Tap("Issue35736ToggleQueryIcon"); + App.Tap("Issue35736ToggleClearIcon"); + App.Tap("Issue35736ToggleClearPlaceholderIcon"); + + // Reset all back to defaults + App.Tap("Issue35736ResetAll"); + App.WaitForElement("Issue35736QueryIconLabel"); + + VerifyScreenshot(); + } +} diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchHandlerClearIconUpdatesAtRuntime.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchHandlerClearIconUpdatesAtRuntime.png new file mode 100644 index 000000000000..fd8411d292cc Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchHandlerClearIconUpdatesAtRuntime.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchHandlerClearPlaceholderIconUpdatesAtRuntime.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchHandlerClearPlaceholderIconUpdatesAtRuntime.png new file mode 100644 index 000000000000..e70508230eba Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchHandlerClearPlaceholderIconUpdatesAtRuntime.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchHandlerQueryIconUpdatesAtRuntime.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchHandlerQueryIconUpdatesAtRuntime.png new file mode 100644 index 000000000000..466f1e729931 Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchHandlerQueryIconUpdatesAtRuntime.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchHandlerResetAllRestoresDefaultIcons.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchHandlerResetAllRestoresDefaultIcons.png new file mode 100644 index 000000000000..330f03797903 Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/SearchHandlerResetAllRestoresDefaultIcons.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchHandlerClearIconUpdatesAtRuntime.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchHandlerClearIconUpdatesAtRuntime.png new file mode 100644 index 000000000000..d892e11b9a88 Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchHandlerClearIconUpdatesAtRuntime.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchHandlerClearPlaceholderIconUpdatesAtRuntime.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchHandlerClearPlaceholderIconUpdatesAtRuntime.png new file mode 100644 index 000000000000..36da344c333f Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchHandlerClearPlaceholderIconUpdatesAtRuntime.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchHandlerQueryIconUpdatesAtRuntime.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchHandlerQueryIconUpdatesAtRuntime.png new file mode 100644 index 000000000000..1519dd84d791 Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchHandlerQueryIconUpdatesAtRuntime.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchHandlerResetAllRestoresDefaultIcons.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchHandlerResetAllRestoresDefaultIcons.png new file mode 100644 index 000000000000..b01effab208d Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/SearchHandlerResetAllRestoresDefaultIcons.png differ