3therk1ll
3therk1ll

Reputation: 2421

Null reference exception in Xamarin iOS app

I am trying to set global variables such as colour in my app. Namely the navigation bar, the colours for which I am having to set individually in each view controller. I have created a helper class, UIHelper.cs to set these values and then call them elsewhere. In my MainViewController.cs, I am creating an instance of UIHelper and calling it in this line: this.NavigationController.NavigationBar.BarTintColor = uiHelper.SetNavBarRGB();

But this is throwing a System.NullReferenceException.

System.NullReferenceException: Object reference not set to an instance of an object
  at NoteTaker.iOS.MainViewController.ViewDidLoad () [0x00018] in /Users/richardcurteis/Development/XamarinProjects/NoteTaker/iOS/MainViewController_.cs:28
  at at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in /Users/builder/data/lanes/2377/73229919/source/maccore/src/UIKit/UIApplication.cs:77
  at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/2377/73229919/source/maccore/src/UIKit/UIApplication.cs:61
  at NoteTaker.iOS.Application.Main (System.String[] args) [0x00013] in /Users/richardcurteis/Development/XamarinProjects/NoteTaker/iOS/Main.cs:17

MainViewController.cs

using System;
using System.CodeDom.Compiler;
using UIKit;
using System.Collections.Generic;

namespace NoteTaker.iOS
{
    partial class MainViewController : UIViewController
    {
        List<Note> notes;
        UITableView table;
        UIHelper uiHelper;


        public MainViewController (IntPtr handle) : base (handle)
        {
            notes = new List<Note> ();
            UIHelper uiHelper = new UIHelper();
        }

        public override void ViewDidLoad ()

        {
            base.ViewDidLoad ();

            //this.NavigationController.NavigationBar.BarTintColor = UIColor.FromRGB (255,0,255);
            this.NavigationController.NavigationBar.BarTintColor = uiHelper.SetNavBarRGB(); // Exception being thrown here
            this.Title = "Notes";
            this.NavigationController.NavigationBar.TitleTextAttributes = new UIStringAttributes () { ForegroundColor = UIColor.White };

            table = new UITableView () {
                Frame = new CoreGraphics.CGRect (0, this.NavigationController.NavigationBar.Frame.Bottom, this.View.Bounds.Width, this.View.Bounds.Height - this.NavigationController.NavigationBar.Frame.Height),
            };
            this.View.Add (table);

            var addButton = new UIBarButtonItem (UIBarButtonSystemItem.Add);
            addButton.TintColor = UIColor.White;

            this.NavigationItem.RightBarButtonItems = new UIBarButtonItem[] { addButton };
            addButton.Clicked += (sender, e) => {
                this.NavigationController.PushViewController (new NoteViewController(), true);
            };

            notes = Database.getNotes ();
            table.Source = new NotesTableViewSource (notes, this);
        }

        public override void ViewWillAppear (bool animated)
        {
            base.ViewWillAppear (animated);
            notes = Database.getNotes ();
            table.Source = new NotesTableViewSource(notes, this );
        }
    }
}

UIHelper.cs

using System;
using UIKit;

namespace NoteTaker.iOS
{
    public class UIHelper : UIInputViewController
    {
        public UIHelper ()
        {
        }

        public UIColor SetNavBarRGB ()
        {
            var uiColour = UIColor.FromRGB (255, 0, 255);
            return uiColour;
        }
    }
}

Upvotes: 1

Views: 2602

Answers (2)

Jens Meinecke
Jens Meinecke

Reputation: 2940

You have a conflict:

You declare uiHelper as a field in the class definition:

partial class MainViewController : UIViewController
{
    List<Note> notes;
    UITableView table;
    UIHelper uiHelper;

and then in the constructor you declare another variable with the same name:

public MainViewController (IntPtr handle) : base (handle)
{
        notes = new List<Note> ();
        UIHelper uiHelper = new UIHelper();
}

This causes a local uiHelper to be declared and assigned within the scope of the constructor only, but the class' field uiHelper is never touched. Hence it is null in the ViewLoad()method. Just remove the type in the constructor and you'll be fine:

public MainViewController (IntPtr handle) : base (handle)
{
        notes = new List<Note> ();
        uiHelper = new UIHelper();
}

Upvotes: 2

Abhinav Galodha
Abhinav Galodha

Reputation: 9878

Does you MainViewController Constructor (MainViewController (IntPtr handle)) even gets called?

Can you try checking against null for uiHelper variable, and if it is null, then initializing a new instance from UIHelper class.

 public override void ViewDidLoad ()

        {
            base.ViewDidLoad ();
             If(uiHelper == null)
             {
                 uiHelper = new UIHelper(); 
             }
            //this.NavigationController.NavigationBar.BarTintColor = UIColor.FromRGB (255,0,255);
            this.NavigationController.NavigationBar.BarTintColor = uiHelper.SetNavBarRGB(); // Exception being thrown here
            this.Title = "Notes";
            this.NavigationController.NavigationBar.TitleTextAttributes = new UIStringAttributes () { ForegroundColor = UIColor.White };

            table = new UITableView () {
                Frame = new CoreGraphics.CGRect (0, this.NavigationController.NavigationBar.Frame.Bottom, this.View.Bounds.Width, this.View.Bounds.Height - this.NavigationController.NavigationBar.Frame.Height),
            };
            this.View.Add (table);

            var addButton = new UIBarButtonItem (UIBarButtonSystemItem.Add);
            addButton.TintColor = UIColor.White;

            this.NavigationItem.RightBarButtonItems = new UIBarButtonItem[] { addButton };
            addButton.Clicked += (sender, e) => {
                this.NavigationController.PushViewController (new NoteViewController(), true);
            };

            notes = Database.getNotes ();
            table.Source = new NotesTableViewSource (notes, this);
        }

Upvotes: 1

Related Questions