diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28986_ContentPage.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28986_ContentPage.cs index a893469f5c75..49e23c22f925 100644 --- a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28986_ContentPage.cs +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28986_ContentPage.cs @@ -130,5 +130,36 @@ public void SafeAreaPerEdgeValidation() Assert.That(containerPositionWithoutSoftInput.Height, Is.EqualTo(containerPosition.Height), "ContentGrid height should return to original when Soft Input is dismissed with Container edges"); }); } + + [Test] + [Category(UITestCategories.SafeAreaEdges)] + public void SafeAreaNoWhiteSpaceAfterKeyboardDismissAndEdgeToggle() + { + App.WaitForElement("ContentGrid"); + + App.Tap("GridResetAllButton"); + var baselinePosition = App.WaitForElement("ContentGrid").GetRect(); + + App.Tap("SoftInputTestEntry"); + App.RetryAssert(() => + { + var withKeyboard = App.WaitForElement("ContentGrid").GetRect(); + Assert.That(withKeyboard.Height, Is.LessThan(baselinePosition.Height), + "ContentGrid should shrink when keyboard is showing with SafeAreaEdges=All"); + }); + + App.Tap("GridSetContainerButton"); + App.DismissKeyboard(); + App.Tap("GridResetAllButton"); + + App.RetryAssert(() => + { + var finalPosition = App.WaitForElement("ContentGrid").GetRect(); + Assert.That(finalPosition.Height, Is.EqualTo(baselinePosition.Height).Within(1), + "ContentGrid height should match baseline after toggling edges with keyboard dismiss — no white space (#34846)"); + Assert.That(finalPosition.Y, Is.EqualTo(baselinePosition.Y).Within(1), + "ContentGrid Y should match baseline after toggling edges with keyboard dismiss"); + }); + } } #endif diff --git a/src/Core/src/Platform/iOS/MauiView.cs b/src/Core/src/Platform/iOS/MauiView.cs index addbaed6dac8..abea7f814163 100644 --- a/src/Core/src/Platform/iOS/MauiView.cs +++ b/src/Core/src/Platform/iOS/MauiView.cs @@ -323,6 +323,13 @@ void UnsubscribeFromKeyboardNotifications() NSNotificationCenter.DefaultCenter.RemoveObserver(hideObserver); _keyboardWillHideObserver = null; } + + // Clear stale keyboard state so that re-subscribing later doesn't + // pick up a phantom keyboard frame from a previous session (#34846). + if (_isKeyboardShowing) + { + ClearKeyboardState(); + } } void UpdateKeyboardSubscription() @@ -353,7 +360,9 @@ void OnKeyboardWillShow(NSNotification notification) } } - void OnKeyboardWillHide(NSNotification notification) + void OnKeyboardWillHide(NSNotification notification) => ClearKeyboardState(); + + void ClearKeyboardState() { _safeAreaInvalidated = true; _keyboardFrame = CGRect.Empty;