Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewModel is null during ViewDidLoad

I am getting started with MvvmCross in iOS.

public class MainView : MvxTabBarViewController
{
    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        var vm = (MainViewModel)this.ViewModel;
        if (vm == null)
            return;
    }
}

Setting a breakpoint to the line where access the ViewModel, shows me, that ViewModel is null.

I can workaround this by calling ViewDidLoad() in the constructor. Then, ViewModel is null during the constructor call, but valid in the default ViewDidLoad call. But that looks like a workaround. can anybody help?

like image 369
esskar Avatar asked May 15 '15 08:05

esskar


1 Answers

I'm guessing here the problem here will be specific to the way that TabBarViewController is constructed.

ViewDidLoad is a virtual method and it is called the first time the View is accessed.

In the case of TabBarViewController this happens during the iOS base View constructor - i.e. it occurs before the class itself has had its constructor called.

The only way around this I've found is to add a check against the situation in ViewDidLoad, and to make a second call to ViewDidLoad during the class constructor.

You can see this in action N-25 - https://github.com/MvvmCross/NPlus1DaysOfMvvmCross/blob/976ede3aafd3a7c6e06717ee48a9a45f08eedcd0/N-25-Tabbed/Tabbed.Touch/Views/FirstView.cs#L17

Something like:

public class MainView : MvxTabBarViewController
{
    private bool _constructed;

    public MainView()
    {
            _constructed = true;

            // need this additional call to ViewDidLoad because UIkit creates the view before the C# hierarchy has been constructed
            ViewDidLoad();
    }

    public override void ViewDidLoad()
    {
        if (!_constructed)
            return;

        base.ViewDidLoad();

        var vm = (MainViewModel)this.ViewModel;
        if (vm == null)
            return;
    }
}
like image 150
Stuart Avatar answered Nov 02 '22 21:11

Stuart