Xamarin.iOS Storyboard Rendering Problem with NullReferenceException

Problems

Recently when trying to open iOS UI Designer to edit storyboard/xib file, I have encounter some problems. This issue is also reported in Xamarin BugZilla: https://bugzilla.xamarin.com/show_bug.cgi?id=59623

Problem 1: ViewControler is rendered but with error exclamation mark

There are many different errors but this is the most common error: System.NullReferenceException

Screen Shot 2017-11-04 at 9.33.17 AM.png

Problem 2: UI Designer took very long time to load and not able to render custom view

After UI Designer is startup, it will show a warning bar at the top. In this mode, all custom view is not rendered.

Screen Shot 2017-11-04 at 9.32.05 AM.png

Checking in the log files and you might get the following errors:

System.NullReferenceException: Object reference not set to an instance of an object
  at MonoTouch.Design.Client.IPhoneDesignerSession+<MaybeConvertToLatestXcode>c__async5.MoveNext () [0x0004c] in /Users/builder/data/lanes/4470/6c2f6737/source/md-addins/Xamarin.Designer.iOS/MonoTouch.Design.Client/IPhoneDesignerSession.cs:774

Reasons & Solutions

After checking into the log file, found out that the UI Designer actually call into UIViewController‘s (those that defined in the storyboard/xib) ViewDidLoad method. In the ViewDidLoad method, I have some code that is dependency injection which is not available during design time. This is the reason why there is NullReferenceException when render.

Attempt 1: Do not run code in ViewDidLoad during design time

I have defined a boolean IsDesignTime in AppDelegate.cs. By default it is set to true and it will set to false when called into FinishedLaunching method in AppDelegate. Then in ViewDidLoad method, I will check only when IsDesignTime is false, I will run the code.

// AppDelegate.cs 
public class AppDelegate : UIApplicationDelegate
 {
     public static bool IsDesignTime = false;
 
     public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
     {
         IsDesignTime = false;
         return true;
     }
...
}
// ViewController.cs 
public partial class ViewController : UIViewController
 {
     public override void ViewDidLoad()
     {
         base.ViewDidLoad();
 
         if (!AppDelegate.IsDesignTime)
         {
             // Do something
         }
     }
...
}

This method can solve the problem and the view is able to render correctly in UI Designer again. However, it is kind of troublesome to add this checking every time. In addition, this method seems not working for views that inherit from UITableViewController

Attempt 2: Set the ViewController DesignTimeVisible flag to false

Checking in the UI Designer, you will find that under the Toolbox, the ViewController is also showing as a custom component.

Screen Shot 2017-11-04 at 10.09.25 AM

This is the reason why the ViewController‘s ViewDidLoad method is getting call during design time.

To remove the screen from being use as a custom components, we will need manually add an DesignTimeVisible attribute for the ViewController class and set the flag to false.

[System.ComponentModel.DesignTimeVisible(false)]
public partial class ViewController : UIViewController


After that, clean and rebuild the solutions. The screen should not showing in the Toolbox‘s Custom Components section now. Also, it will no longer call into ViewDidLoad method during design time. Adding the attribute to all the screens that defined in storyboard/xib solve the issue for now.

 

One thought on “Xamarin.iOS Storyboard Rendering Problem with NullReferenceException”

  1. Thankyou!! Just got this error in an old project I reopened in VS for mac. I had a subclassed Viewcontroller, adding the designtimevisable attribute solved the issue.

    Like

Leave a comment