Using a iOS UITabBar with MVVMCross MvxViewController not MvxTabBarViewController - xamarin.ios

We have a 4 views that are considered siblings in the UX design and so we would like to display them on a TabBar in iOS. We already have them in a NavigationDrawer in Android.
Lets call them
Customer
CustomerOrders
CustomerHistory
Returns
These are represented by 4 separate ViewModels. Looking at the MvxTabBarViewController samples I have to created a Uber ViewModel that exposes all 4 ViewModels as properties. Then attach the 4 views (MvxViewControllers) to a Parent View (MvxTabViewController).
UPDATE
I don't want to create a ViewModel just to support iOS' way of doing things.
I tried creating a UITabBar as a standalone view but that fails to deal with more than 5 items.
I have given up trying to fight the toolbar and am going to create a iOS specific ViewModel to host the Customer, CustomerOrders, CustomerHistory and Returns ViewModels. That is how the MvxTabViewController wants me to do it so I will. Getting that to work involves some MVVMCross configuration that I think is best handled by a new question. Once created I will link to it from here New question
Any suggestions?

Related

Developing Xamarin.iOS application using MVVMCross and Storyboards

I am trying to understand how storyboards work in iOS development and how MVVMCross fits in. I thought the best solution would be to build an iOS version of the MVVMCRoss TipCalc Tutorial
I am using Storyboards as you cannot edit XIBs in Visual Studio. My current thinking is one Storyboard per screen.
I have it working but it feels like i did it with more luck than judgement. Therefore I want to check my understanding.
In TipCalc.UI.Touch I have
TipViewController.cs
TipViewController.storyboard
I have added a custom Mvx View Container as suggested in this SO answer. In the CreateViewOfType method of that container I am calling Storyboard.InstantiateViewController and casting that to an IMvxTouchView.
How can a controller be a View as well?
I am planning on having a "View" per storyboard.
If you have multiple views in a storyboard, would you have a controller per view?
When I bring up the Properties window for a "View" in the storyboard designer it has a Name and a class in the Identity section. What is the purpose of the Class property? Does that create a code-behind file?
I am creating the View-to-ViewModel bindings in the ViewDidLoad method of the Controller
public override void ViewDidLoad()
{
base.ViewDidLoad();
this.CreateBinding(this.tipValueText).To<TipViewModel>(vm => vm.Tip).Apply();
this.CreateBinding(this.subTotalTextBox).To<TipViewModel>(vm => vm.SubTotal).Apply();
this.CreateBinding(this.generositySlider).To<TipViewModel>(vm => vm.Generosity).Apply();
}
These bindings work but again I just wanted to check that it is how others do it too.
The iOS ViewController is actually the View in an MVVMCross application. You can think of the view controller as the code behind for the view (so just like a Windows Phone/Windows Store app will have a XAML and related .cs file, or an Android app will have an axml and a java view class)
Yes, when using multiple views in a single storyboard each one will actually be a viewcontroller (since that's what a screen in a storyboard is)
The class property defines which viewcontroller class the layout in the storyboard uses (so which code behind class to use, and if it doesn't exist it will be created)
I prefer a single storyboard as most of my apps don't have too many screens so these are the steps I follow when creating a View in an existing storyboard
Add a ViewController
Type in the view name in the Class field (this name would correspond to the ViewModel name, so HomeView for HomeViewModel, etc.). As soon as you hit enter the ViewController class should be created.
Type in the same view name as the Storyboard Id (this is used to fetch that view)
Add controls and set their names. Setting a control's name will updated the .designer file that was created for the ViewController
Create the ViewDidLoad override in the ViewController class and set up my bindings
If you use a storyboard per view, creating that storyboard with the correct name (HomeView for example) should create the ViewController and designer files for you and give you a storyboard with that one viewcontroller ready to go
edit:
in your bindings, you can use one set.Apply(); at the end

Universal app with PCL - navigate to proper View

I have question whether it is possible somehow use this project structure and within some ViewModel navigate to specific View from Core.Windows/Core.WindowsPhone.
1. PCL libraries
Core (PCL for universal apps)
ViewModel
Core.Windows (PCL) - reference to Core
View
Core.WindowsPhone (PCL) - reference to Core
View
I need to keep View in PCL because I use the same View for some other projects.
2. Universal app
Windows - reference to Core, Core.Windows
WindowsPhone - reference to Core, Core.WindowsPhone
Shared
Yes I think it is possible.
I have a similar requirements in my solution (using same View for different apps)
Basicly I suggest the following:
1) Create a NavigationService abstract class and/or INavigationService interface in Core (PCL for universal apps with ViewModels).
2) Create WindowsNavigationService and WindowsPhoneNavigationService classes in Core.Windows and Core.WindowsPhone which derive from NavigationService in 1)
This classes can do the following:
1) Hold an instance of
Dictionary<ViewModelBase,Page> mapDictionary
ViewModelBase is a base class for your viewmodel (I suppose you have one).
2) Register the data in mapDictionary: e.g. add View and corresponding ViewModel to it
3) Perform navigation buy holding the instance of Frame: e.g. NavigateTo, GoBack and so on
4) Bind the ViewModel to View.
After that you can Hold a NavigationService in your ViewModels and perform navigation between them.
If you are interested in such approach I suggest to waste some time and take a look at https://github.com/MvvmCross/MvvmCross - this can give you ideas about how you can build your architecture.
Also interesting post about PCL (with sample code demonstrating described approach): http://msdn.microsoft.com/en-us/magazine/hh852593.aspx
Source code for the article: http://download.microsoft.com/download/6/2/D/62D36C65-4C36-429A-8711-F657D34AB4BC/Code_KeanPCL0312.zip

Showing a UIWebView in Cocos2d 2.x project

I'd like to display a UIWebView within a CCLayer for a Cocos2d 2.x project. I found the CCUIViewWrapper, but didn't get it to work with 2.x.
I don't really care about handling rotation and animation. I just wan't to display content from a web page on layer and also have a sprite to be able to go back to the previous scene.
Please help!
// Johan
If you don't want to use new version 2.0 features (I'm not using them myself at this point), then you can mix UIViews with Cocos by simply adding other views to your root view controller. After all, Cocos is itself a single view on the controller (if that's how you have it set up), and just add another view.
You can then easily tell the view controller to show the other UIViews by using the NSNotificationCenter, which I recommend in general over trying to communicate with the view controller from the Cocos layer.

UISplitViewController problems with IOS 5.1

I have a problem,
I am programming with Monotouch 5.2.8 for IOS 5.1.
But since the IOS 5.1 update my iPad configs the UISplitViewController so it is docked on the
left side instead of presented as a popover.
It works with IOS 5.0 but in 5.1 i got this problem.
Here is the source code for my UISplitViewController:
splitViewController = new UISplitViewController ();
splitViewController.WeakDelegate = detailViewController;
splitViewController.ViewControllers = new UIViewController[] {
navigationController,
detailViewController
};
From Apple's iOS 5.1 SDK release notes:
In 5.1 the UISplitViewController class adopts the sliding presentation
style when presenting the left view (previously only seen in Mail).
This style is used when presentation is initiated either by the
existing bar button item provided by the delegate methods or by a
swipe gesture within the right view. No additional API adoption is
required to obtain this behavior, and all existing API, including that
of the UIPopoverController instance provided by the delegate, will
continue to work as before. If the gesture cannot be supported in your
app, set the presentsWithGesture property of your split view
controller to NO to disable the gesture. However, disabling the
gesture is discouraged because its use preserves a consistent user
experience across all applications.
Here (login required).
UPDATE:
From what I understand on the above, we can kiss the automatic popover appearance of the master controller goodbye in iOS 5.1.
The only way I see is possible to keep the "old" appearance, is by implementing our own UIPopoverController and taking advantage of the ShouldHideViewController delegate method. Thankfully with MonoTouch, we have that method available as a property in the UISplitViewController class, making things a bit simpler.
I do get a strange behavior though. With iOS SDK 5.1 on my Mac and iOS 5.1 on my iPad; on the device, I get the "sliding" appearance, while on the simulator I get the "old", popover appearance. This is with MonoTouch 5.2.4, which is the latest stable version. Also, it does not contain a PresentsWithGesture property. I tried setting its value to false through MonoTouch.ObjCRuntime messaging, but no luck. The selector keeps returning true. So I cannot deactivate the swipe gesture.
Even tried creating my own UIPopoverController and assigning it as the master in the split controller to see what happens. Doesn't work because UIPopoverController is not a UIViewController...
Some useful info in this question, for ObjC.
Turns out you can disable the presentsWithGesture in the application delegate, but once the view controllers have been presented, there is no changing it.
I needed to disable the appearance of the left view controller during a login process, but turns out I can't enable it later.

What is the correct way to switch between UIViewControllers without using a navigation controller or loading views modally

I'm trying to accomplish switching views without using a navigation controller, tab bar controller etc. I am currently accomplishing this using Cocos2d director class replaceScene method. My application will need to have around 40 view controllers, each with a few UIButtons that could take them to any other view controller.
For instance View controller 1 may have buttons that take you to view controller 2
View Controller 2 may have buttons that link to 3,4,5,12
view controller 4 may need to link to view controller 17, 5 and 3
Every tutorial and bit of documentation I've read only discusses using Navigation Controllers, Tab bars or pushing views modally. None of these solutions fits my particular requirements.
Cocos2d has the "replaceScene" method which does exactly what I need, but mixing the many UIKit controls that I need makes developing this entire project in Cocos2d a nightmare.
I'm looking for something where I can have the user tap a button which will load a specified view controller/view transition to that view, and unload the previous view controller from memory. Any ideas?
Have a root view controller which has references of your view controllers. Also make a weak reference to the root view controller in each view controller, as in a delegate pattern. If one of the view controllers wants to make a view transition, send a message to the root view controller. Let the root view controller hide the current view and unhide the next view, using an animation if you want.
Basically you are implementing a view container much simpler than UINavigationController and UITabBarController. You could probably achieve the same thing using the tab bar controller and hide the tab bar view, but I would implement a custom one.

Resources