[IOS] KeyboardAutoScrollManager NullReferenceException when focussing Editor/Entry in modal bottom sheet
Description
When using [The49.Maui.BottomSheet](https://github.com/the49ltd/The49.Maui.BottomSheet) to display a BottomSheet, I have discovered a crash on iOS that is happening within the KeyboardAutoScrollManager.AdjustPosition method.
I understand this is caused by working with an external library, however a NullReferenceException being thrown internally by Maui clearly indicates an issue that could affect peoples apps in the wild.
Steps to Reproduce
This issue only occurs when the page calling the BottomSheet is itself a modal page. If there is only 1 page on the navigation stack the controls work correctly & no crash.
- Add a page to the modal stack
- From that page display a bottom sheet
- On that bottom sheet add an
Editor/Entry - Focus the control
Expected: The control is focussed, keyboard displayed and you can enter text
Actual: The following crash happens:
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.Maui.Platform.KeyboardAutoManagerScroll.AdjustPosition()
at Microsoft.Maui.Platform.KeyboardAutoManagerScroll.AdjustPositionDebounce()
at Microsoft.Maui.Platform.KeyboardAutoManagerScroll.DidUITextBeginEditing(NSNotification notification)
at ObjCRuntime.Runtime.ThrowException(IntPtr gchandle) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/ObjCRuntime/Runtime.cs:line 2594
at UIKit.UIApplication.UIApplicationMain(Int32 argc, String[] argv, IntPtr principalClassName, IntPtr delegateClassName) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UIApplication.cs:line 60
at UIKit.UIApplication.Main(String[] args, Type principalClass, Type delegateClass) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UIApplication.cs:line 94
at KeyboardAutoScrollRepro.Program.Main(String[] args) in /Users/axemasta/Documents/Dev/Projects/Maui/KeyboardAutoScrollRepro/KeyboardAutoScrollRepro/Platforms/iOS/Program.cs:line 13
2024-04-09 14:25:19.623589+0100 KeyboardAutoScrollRepro[88641:22091147] Unhandled managed exception: Object reference not set to an instance of an object. (System.NullReferenceException)
at Microsoft.Maui.Platform.KeyboardAutoManagerScroll.AdjustPosition()
at Microsoft.Maui.Platform.KeyboardAutoManagerScroll.AdjustPositionDebounce()
at Microsoft.Maui.Platform.KeyboardAutoManagerScroll.DidUITextBeginEditing(NSNotification notification)
at ObjCRuntime.Runtime.ThrowException(IntPtr gchandle) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/ObjCRuntime/Runtime.cs:line 2594
at UIKit.UIApplication.UIApplicationMain(Int32 argc, String[] argv, IntPtr principalClassName, IntPtr delegateClassName) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UIApplication.cs:line 60
at UIKit.UIApplication.Main(String[] args, Type principalClass, Type delegateClass) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UIApplication.cs:line 94
at KeyboardAutoScrollRepro.Program.Main(String[] args) in /Users/axemasta/Documents/Dev/Projects/Maui/KeyboardAutoScrollRepro/KeyboardAutoScrollRepro/Platforms/iOS/Program.cs:line 13
Link to public reproduction project repository
https://github.com/Axemasta/KeyboardAutoScrollRepro
Version with bug
8.0.14 SR3.1
Is this a regression from previous behavior?
Not sure, did not test other versions
Last version that worked well
Unknown/Other
Affected platforms
iOS
Affected platform versions
iOS 17.2
Did you find any workaround?
This works when the presenting page is not modal:
In this example I have set the Application.MainPage to the page responsible for showing the dialogs. As you can see the dialogs appear and the textfields can be interacted with.
Relevant log output
No response
Coud be because of this change.
the usage of view is not checked for null in this class even if declared as
static UIView? View;
In our app we are also facing this even after BottomSheet was closed or never opened. Looks like SearchHandler is facing a similar Issue. After Navigating away from a Page that had focus in SearchHandler we get this callstack
Microsoft.Maui.Platform.KeyboardAutoManagerScroll.AdjustPosition() in Microsoft.Maui.Platform.KeyboardAutoManagerScroll.AdjustPositionDebounce() in System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start<Microsoft.Maui.Platform.KeyboardAutoManagerScroll.<AdjustPositionDebounce>d__38>(Microsoft.Maui.Platform.KeyboardAutoManagerScroll stateMachine) in System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start<Microsoft.Maui.Platform.KeyboardAutoManagerScroll.<AdjustPositionDebounce>d__38>(Microsoft.Maui.Platform.KeyboardAutoManagerScroll stateMachine) in Microsoft.Maui.Platform.KeyboardAutoManagerScroll.AdjustPositionDebounce() in Microsoft.Maui.Platform.KeyboardAutoManagerScroll.WillKeyboardShow() in System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start<Microsoft.Maui.Platform.KeyboardAutoManagerScroll.<WillKeyboardShow>d__31>(Microsoft.Maui.Platform.KeyboardAutoManagerScroll stateMachine) in System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Start<Microsoft.Maui.Platform.KeyboardAutoManagerScroll.<WillKeyboardShow>d__31>(Microsoft.Maui.Platform.KeyboardAutoManagerScroll stateMachine) in Microsoft.Maui.Platform.KeyboardAutoManagerScroll.WillKeyboardShow(Foundation.NSNotification notification) in Foundation.InternalNSNotificationHandler.Post(Foundation.NSNotification s) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/Foundation/NSNotificationCenter.cs:49 UIKit.UIApplication.xamarin_UIApplicationMain() in UIKit.UIApplication.UIApplicationMain(int argc, string[] argv, System.IntPtr principalClassName, System.IntPtr delegateClassName) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UIApplication.cs:58 UIKit.UIApplication.Main(string[] args, System.Type principalClass, System.RuntimeType delegateClass) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UIApplication.cs:94 xxx.Program.Main(string[] args) in xxx/Platforms/iOS/Program.cs:15
Looked a bit deeper into this. In case of SearchHandler ContainerView.Window is null
resulting in a nullpointer when doing
var intersectRect = CGRect.Intersect(KeyboardFrame, window.Frame);
In outr Usecase we have a Shell with Tabs. On Tab Contains a Searchhandler, when navigating awaiy from tab to the other while Keyboard is showing and then navigating back to this tab the exception get triggered. Looks like it happens when focus is still in SearchHandler
Can repro this issue at iOS platform on the MauiVersion(8.0.7 & 8.0.14).
Adding a null check to the ContainerView.Window appears to fix the issue.
I pulled the bottom sheets library into the maui controls sample and have been able to get it working. I'll raise a pr!