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 ec0d89980a9f..7de95e1d8c91 100644 --- a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellPageRendererTracker.cs +++ b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellPageRendererTracker.cs @@ -935,6 +935,14 @@ void AttachSearchController() } _searchController = new UISearchController(_resultsRenderer?.ViewController); + + // Fix for iPhone: Prevent the navigation bar from hiding during search presentation. + // When HidesNavigationBarDuringPresentation is true (the default), the search bar moves + // upward but the suggestions list doesn't follow, creating a visible gap. + // Setting these properties to false keeps the suggestions list attached to the search bar. + // iPad doesn't have this issue because the navigation bar layout differs. + _searchController.HidesNavigationBarDuringPresentation = false; + _searchController.ObscuresBackgroundDuringPresentation = false; var visibility = SearchHandler.SearchBoxVisibility; if (visibility != SearchBoxVisibility.Hidden) { diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue32930.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue32930.xaml new file mode 100644 index 000000000000..171d170ded1a --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue32930.xaml @@ -0,0 +1,25 @@ + + + + + + + + + + + + diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue32930.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue32930.xaml.cs new file mode 100644 index 000000000000..61f14d694842 --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue32930.xaml.cs @@ -0,0 +1,43 @@ +namespace Maui.Controls.Sample.Issues; + +[Issue(IssueTracker.Github, 32930, "[iOS] SearchHandler suggestions list does not follow the search bar upward movement on iPhone, creating a layout gap", PlatformAffected.iOS)] +public partial class Issue32930 : Shell +{ + public Issue32930() + { + InitializeComponent(); + } +} + +public class Issue32930SearchHandler : SearchHandler +{ + static readonly List _allItems = new() + { + "Apple", + "Banana", + "Cherry", + "Date", + "Elderberry", + "Fig", + "Grape" + }; + + public Issue32930SearchHandler() + { + ItemsSource = _allItems; + } + + protected override void OnQueryChanged(string oldValue, string newValue) + { + base.OnQueryChanged(oldValue, newValue); + + if (string.IsNullOrEmpty(newValue)) + { + ItemsSource = _allItems; + } + else + { + ItemsSource = _allItems.Where(s => s.Contains(newValue, StringComparison.OrdinalIgnoreCase)).ToList(); + } + } +} diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32930.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32930.cs new file mode 100644 index 000000000000..bd0e80602747 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32930.cs @@ -0,0 +1,35 @@ +#if IOS +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue32930 : _IssuesUITest +{ + public Issue32930(TestDevice testDevice) : base(testDevice) + { + } + + public override string Issue => "[iOS] SearchHandler suggestions list does not follow the search bar upward movement on iPhone, creating a layout gap"; + + [Test] + [Category(UITestCategories.Shell)] + public void SearchHandlerSuggestionsListFollowsSearchBar() + { + // Wait for the page to load + App.WaitForElement("Instructions"); + + // Enter text in the search handler to trigger suggestions display + App.EnterText(AppiumQuery.ByXPath("//XCUIElementTypeSearchField"), "A"); + + // Wait for suggestions to appear + App.WaitForElement("Apple"); + + // Verify the suggestions list appears correctly + // If the fix works, the suggestions list should be visible and positioned directly under the search bar + // We use screenshot verification to ensure there is no visible gap between the search bar and suggestions + VerifyScreenshot(); + } +} +#endif