Let's start with the iOS implementation.
First things first:
If you followed the previous tutorial, you'll need to inherit the AppDelegate class from MvxApplicationDelegate (as per outlined in the TipCalc tutorial, the Nuget didn't help up update this part :( ).
Next, you'll need to override the FinishedLaunching function to this:
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
// Override point for customization after application launch.
// If not required for your application you can safely delete this method
Window = new UIWindow(UIScreen.MainScreen.Bounds);
var presenter = new MvxIosViewPresenter(this, Window);
var setup = new Setup(this, presenter);
var startup = Mvx.Resolve<IMvxAppStart>();
Once you've done the above, let's start adding the MainView, ConfigurationView and InvoicesView. Simply Right Click -> Add Class and add a StoryboardViewController for each of the 3 views. Remember to add a ViewController to each Storyboard and change the class and storyboardId to each respective MainView, ConfigurationView and InvoicesView.
And for each MainView, ConfigurationView and InvoicesView, add the [MvxFromStoryboard] attribute to the class.
Okay, just so we can differentiate between ConfigurationView and InvoicesView when we switch tabs, at each storyboard, add a label with the text 'Configuration' and 'Invoices' respectively.
Alright with that out of the way, we can start actually implementing the TabBar.
In MvvmCross5, they have added a new default presenter which makes our life a whole lot easier in implementing the default navigation methods (tabbar, stack and modal). Right now, we'll be playing around with the TabBar. More info can be found at MvvmCross' documentation.
Set Root Presentation
Just like in the Android project, our MainView will be our Root.
So in MainView.cs, add the [MvxRootPresentation] attribute.
And since InvoicesView and ConfigurationView will be our tabs, then:
Add [MvxTabPresentation(TabName = "Configuration")] to ConfigurationView
Add [MvxTabPresentation(TabName = "Invoices")] to InvoicesView
That's it. We're done! Well, not so.
If you try to run the app, you'll only get a blank screen.
This ViewPresenter have a gotcha, which isn't very intuitive, in which we NEED to call the ShowViewModel() method to each child views before the root view will show the links to each child views in the tab bar.
Hence, let's do that.
Inside the MainViewModel(), let's add the function ShowInitialViewModelsCommand() that will be used by our root view, like so:
private IMvxCommand _showInitialViewModelsCommand;
public IMvxCommand ShowInitialViewModelsCommand
return _showInitialViewModelsCommand ?? (_showInitialViewModelsCommand = new MvxCommand(ShowInitialViewModels));
private void ShowInitialViewModels()
...And in our MainView.cs, let's override the ViewWillAppear method and trigger the ShowInitialViewModelsCommand. We'll add a bit more functionality so that the command will only be triggered at the first time the view is seen by the user.
private bool _isPresentedFirstTime = true;
public override void ViewWillAppear(bool animated)
if (ViewModel != null && _isPresentedFirstTime)
_isPresentedFirstTime = false;
Now that we're done, try running your iOS app again. It should work this time :)