Search code examples
iosxamarinmvvmcross

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?


Solution

  • 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;
        }
    }