NullReferenceException in DrawLabel on iOS
Opened this issue · 0 comments
Description
Returning to a Xamarin Shell page where a Forms9 label has been shown and then hidden seems to cause a NullReferenceException.
Steps to Reproduce
ShellContent firstPage;
ShellContent secondPage;
label.IsVisible = true;
await Task.Delay(100);
label.IsVisible = false;
await GoToAsync($"//{secondPage.Route}");
firstPage.IsVisible = false;
await Task.Delay(100);
firstPage.IsVisible = true;
await GoToAsync($"//{firstPage.Route}");
Expected Behavior
FirstPage is shown
Actual Behavior
System.NullReferenceException: Object reference not set to an instance of an object
at Forms9Patch.iOS.LabelRenderer.DrawLabel (System.Double width, System.Double height) [0x0001e] in <2738c9ce95a3438fb36953f241f4498f>:0
at Forms9Patch.iOS.LabelRenderer.LayoutSubviews () [0x0001d] in <2738c9ce95a3438fb36953f241f4498f>:0
at (wrapper managed-to-native) ObjCRuntime.Messaging.void_objc_msgSend(intptr,intptr)
at CoreAnimation.CALayer.LayoutSublayers () [0x00008] in /Library/Frameworks/Xamarin.iOS.framework/Versions/16.4.0.15/src/Xamarin.iOS/CoreAnimation/CALayer.g.cs:456
at Xamarin.Forms.Platform.iOS.VisualElementTracker+<>c__DisplayClass32_0.<OnUpdateNativeControl>g__update|0 () [0x0015d] in D:\a\1\s\Xamarin.Forms.Platform.iOS\VisualElementTracker.cs:277
at Xamarin.Forms.Platform.iOS.VisualElementTracker.OnUpdateNativeControl (CoreAnimation.CALayer caLayer) [0x002be] in D:\a\1\s\Xamarin.Forms.Platform.iOS\VisualElementTracker.cs:361
at Xamarin.Forms.Platform.iOS.VisualElementTracker.UpdateNativeControl () [0x00060] in D:\a\1\s\Xamarin.Forms.Platform.iOS\VisualElementTracker.cs:411
at Xamarin.Forms.Platform.iOS.VisualElementTracker.SetElement (Xamarin.Forms.VisualElement oldElement, Xamarin.Forms.VisualElement newElement) [0x00038] in D:\a\1\s\Xamarin.Forms.Platform.iOS\VisualElementTracker.cs:387
at Xamarin.Forms.Platform.iOS.VisualElementTracker..ctor (Xamarin.Forms.Platform.iOS.IVisualElementRenderer renderer, System.Boolean trackFrame) [0x0006b] in D:\a\1\s\Xamarin.Forms.Platform.iOS\VisualElementTracker.cs:56
at Xamarin.Forms.Platform.iOS.VisualElementTracker..ctor (Xamarin.Forms.Platform.iOS.IVisualElementRenderer renderer) [0x00000] in D:\a\1\s\Xamarin.Forms.Platform.iOS\VisualElementTracker.cs:42
at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x000ef] in D:\a\1\s\Xamarin.Forms.Platform.iOS\VisualElementRenderer.cs:276
at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.iOS.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00000] in D:\a\1\s\Xamarin.Forms.Platform.iOS\VisualElementRenderer.cs:158
at Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x00032] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Platform.cs:240
at Xamarin.Forms.Platform.iOS.VisualElementPackager.OnChildAdded (Xamarin.Forms.VisualElement view) [0x0003e] in D:\a\1\s\Xamarin.Forms.Platform.iOS\VisualElementPackager.cs:119
at Xamarin.Forms.Platform.iOS.VisualElementPackager.Load () [0x0001e] in D:\a\1\s\Xamarin.Forms.Platform.iOS\VisualElementPackager.cs:51
at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].SetElement (TElement element) [0x0012e] in D:\a\1\s\Xamarin.Forms.Platform.iOS\VisualElementRenderer.cs:283
at Xamarin.Forms.Platform.iOS.VisualElementRenderer`1[TElement].Xamarin.Forms.Platform.iOS.IVisualElementRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x00000] in D:\a\1\s\Xamarin.Forms.Platform.iOS\VisualElementRenderer.cs:158
at Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x00032] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Platform.cs:240
at Xamarin.Forms.Platform.iOS.VisualElementPackager.OnChildAdded (Xamarin.Forms.VisualElement view) [0x0003e] in D:\a\1\s\Xamarin.Forms.Platform.iOS\VisualElementPackager.cs:119
at Xamarin.Forms.Platform.iOS.VisualElementPackager.Load () [0x0001e] in D:\a\1\s\Xamarin.Forms.Platform.iOS\VisualElementPackager.cs:51
at Xamarin.Forms.Platform.iOS.PageRenderer.ViewDidLoad () [0x0008f] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\PageRenderer.cs:251
at (wrapper managed-to-native) ObjCRuntime.Messaging.IntPtr_objc_msgSendSuper(intptr,intptr)
at UIKit.UIViewController.get_View () [0x0002a] in /Library/Frameworks/Xamarin.iOS.framework/Versions/16.4.0.15/src/Xamarin.iOS/UIKit/UIViewController.g.cs:2938
at Xamarin.Forms.Platform.iOS.PageRenderer.get_NativeView () [0x00000] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\PageRenderer.cs:103
at Xamarin.Forms.Platform.iOS.PageRenderer.SetElement (Xamarin.Forms.VisualElement element) [0x0003d] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\PageRenderer.cs:119
at Xamarin.Forms.Platform.iOS.Platform.CreateRenderer (Xamarin.Forms.VisualElement element) [0x00032] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Platform.cs:240
at Xamarin.Forms.Platform.iOS.ShellSectionRootRenderer.SetPageRenderer (Xamarin.Forms.Page page, Xamarin.Forms.ShellContent shellContent) [0x00013] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ShellSectionRootRenderer.cs:497
at Xamarin.Forms.Platform.iOS.ShellSectionRootRenderer.LoadRenderers () [0x0009c] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ShellSectionRootRenderer.cs:244
at Xamarin.Forms.Platform.iOS.ShellSectionRootRenderer.ViewDidLoad () [0x00077] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ShellSectionRootRenderer.cs:81
at (wrapper managed-to-native) UIKit.UIApplication.xamarin_UIApplicationMain(int,intptr,intptr,intptr,intptr&)
at UIKit.UIApplication.UIApplicationMain (System.Int32 argc, System.String[] argv, System.IntPtr principalClassName, System.IntPtr delegateClassName) [0x00008] in /Library/Frameworks/Xamarin.iOS.framework/Versions/16.4.0.15/src/Xamarin.iOS/UIKit/UIApplication.cs:58
at UIKit.UIApplication.Main (System.String[] args, System.Type principalClass, System.Type delegateClass) [0x0003b] in /Library/Frameworks/Xamarin.iOS.framework/Versions/16.4.0.15/src/Xamarin.iOS/UIKit/UIApplication.cs:94
at Forms9Issue.iOS.Application.Main (System.String[] args) [0x00001] in C:\Users\mattheww\source\repos\Forms9Issue\Forms9Issue\Forms9Issue.iOS\Main.cs:17
Basic Information
-
Version with issue: 2.4.9
-
Last known good version: Unknown
-
IDE: Visual Studio 2022 version 17.7.5 on Windows 10.0.19045 Build 19045
-
Platform Target Frameworks:
- iOS: 8.0, 16.4
-
Nuget Packages: Forms9Patch, Xamarin.Forms, Xamarin.Essentials
-
Affected Devices: All, including simulators, as far as I can tell
Reproduction Link
https://github.com/mattheww-skyward/forms9patch-label-nullref
Workaround
None as yet besides using a regular label.
It's possible that hiding/showing the ShellContent, which seems to be a necessary step, is the wrong approach and could be avoided entirely.
Notes
_currentDrawState is null on line 47 of LabelRenderer.DrawLabel().
As best I can tell, that implies that OnElementChanged() must not have been called, or called with a null NewElement. So I think it should be sufficient to move the _currentDrawState.IsBlank check to the end, or to add an explicit null check as is done in Android's LabelRenderer.DrawLabel()?
I'd be happy to create a pull request, but I've been having trouble building the solution to confirm my theory.