suggestions how to achieve DatePickerDialog equivalent using mvvmcross & monotouch - xamarin.ios

Currently have a Droid app implemented that in response to a button press pops up a DatePickerDialog.
As this must be a common use case does anyone have any suggestions how to achieve something similar with Touch?
Not sure if an AlertView can be used & if so how or what would be a suitable approach...
A pointer to an existing sample or project that does something similar would be appreciated.
TIA
Andreas

Assuming my UI designers agree (sometimes they like to do things differently)... I'd use a UIDatePicker - see
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIDatePicker_Class/Reference/UIDatePicker.html
http://jsasitorn.com/2010/06/iphone-uidatepicker-tutorial/ (Warning - ObjC!)
As a fairly experience MonoTouch and MvvmCross dev I would do this by:
create a custom UIView (maybe subclassing UIButton or UILabel) for my on-screen display
inside that custom UIView when edit is needed, I would use a UIDatePicker with code like that inside https://github.com/slodge/MvvmCross/blob/vnext/CrossUI/CrossUI.Touch/Dialog/Elements/DateTimeElement.cs
for MvvmCross data-binding I would expose a public DateTime Value {get;set;} property and a public event EventHandler ValueChanged event
to make that data-binding work I would then add some custom binding during my MvvmCross Setup - very similar to how it's now in this Droid question - Bind TimePicker & DatePicker - MVVMCross (Mono For Android)
use that custom UIView in my 'page' with two-way binding on Value
If I were in more of a hurry though, I might instead:
dump a button on the screen and bind it's Title to the ViewModel DateTime
use code-behind in my 'page' UIViewController to hook up the button TouchUpInside to some code to show a UIDatePicker
use code-behind to respond to UIDatePicker events in order to set properties back in the ViewModel

Related

Xamarin iOS : How to detect the tableview scroll

I want to detect the scroll of tableview in my class. I used decelerationEnded method of UITableViewDelegate but it got crashed.
Ideally you should be using a UITableViewSource assigned to your UITableView.Source property. You no longer require a delegate class, you can override all of the necessary methods within the source, which is the currently preferred method of achieving the result your after. You are most likely looking to override the method called 'Scrolled' within the UITableViewSource. However I would suggest making use of 'DecelerationEnded' as well if you're trying to do something depending on if your scroll view is at the 'bottom' or 'top' of the UITableViews content (That's just a little tip based off of some experience with this in a recent project.)

Custom Controls in Xamarin iOS with MVVMCross and no XIB

I am following a code only approach for my Xamarin iOS app and can see how you can easily create control such as UILabel and UITextField in ViewDidLoad of a Controller. That is also where I can apply MVVMCross Fluent Binding.
I have seen Stuart's n19 where he creates a custom Circle View and one that creates a Custom Label.
The custom circle overrides the Draw method and draws a circle (Owner Draw)
The custom labels changes the Forecolor of the existing Label (Subclassed)
I don't feel that either of those works for me. I want to create a UIView that is made up of other controls, a composite control. Imagine a control that looked something like this. That would be an ImageView, and 4 labels with one of them clickable.
At what point in the life of the UIView would I create something like that. Is there an equivalent of ViewDidLoad?
As Stuart said in his comment, N=32 - ViewModels and MvxView on the iPad - N+1 days of MvvmCross
is the MVVMCross tutorial you want.
For those that are happy with the idea of ViewModels being more than just a ViewModel per screen and understand Binding the bit around Custom Views starts at minute 20

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

How do I do two-way binding to a UITextView control using mvvmcross?

I have a simple view I created using XCode (it's a XIB). It consists of two UITextView controls and a UIButton. I've exposed the UITextView controls as Outlets and given them names. Everything looks good in my View.designer.cs file.
I'm creating my binding using this syntax:
this.AddBindings(
new Dictionary<object, string>()
{
{lastname, "{'Text':{'Path':'LastName','Mode':'TwoWay'}}"},
{uservin, "{'Text':{'Path':'CarVIN','Mode':'TwoWay'}}"}
});
When I move from the lastname UITextView to the uservin UITextView I expect the SETTER in my viewmodel to get called, but it doesn't. When I click the button and check the value of the two text properties on my ViewModel, they are both null.
Does anybody know what I've done wrong? I've got a quick demo due on Tuesday and have all other platforms working beautifully, but just can't seem to get past this issue.
Cheers,
/j
I think the problem will be that you are using UITextView instances... but mvvmcross vnext only ships with 2-way binding for UITextField elements.
To add the UITextView 2-way binding to an older mvvmcross version:
Add a custom target binding class - a bit like this one from v3: https://github.com/slodge/MvvmCross/blob/v3/Cirrious/Cirrious.MvvmCross.Binding.Touch/Target/MvxUITextViewTextTargetBinding.cs
Register it during Setup.cs with code like:
protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
base.FillTargetFactories(registry);
registry.RegisterFactory(new MvxSimplePropertyInfoTargetBindingFactory(typeof(MvxUITextViewTextTargetBinding), typeof(UITextView), "Text");
}
Alternatively (but maybe not before your immediate demos), you could consider updating to the v3 beta release.
Incidentally, using the 'swiss' binding syntax is generally now the normal way to do this:
this.AddBindings(
new Dictionary<object, string>()
{
{lastname, "Text LastName"},
{uservin, "Text CarVIN"}
});
... and TwoWay binding is the default for most non-Windows MvvmCross bindings.

How to use UITableViewDelegate.AccessoryButtonTapped (with Monotouch)

I'm creating an IPad application using C#, Mono develop and Monotouch.
I've been using Monotouch.Dialog to create functionality similar to the wifi-settings on an iPhone. I'm using StyledStringElement with an accessory and am now trying to differentiate between tapping the row and tapping the DetailDisclosureButton.
I've been found out that I should override the UITableViewDelegate.AccessoryButtonTapped on the UITableView. I've tried to created a derived class from UITableViewDelegate and hook this into the Monotouch.Dialog. But this is where I got stuck. I didn't manage to replace the existing UITableViewDelegate with my extended version.
So my questions are:
Is this the preferred way of handling this event (to be able to differentiate between a tap on the element and a tap on the DetailDisclosureButton) ?
If not, any pointer on how to accomplish this ?
I have been searching the web for a (similar) example but have not found any yet. Any examples that you know of that could get me started ?
Thanks,
boris
event EventHandler accessoryPushed;
public override void AccessoryButtonTapped (UITableView tableView, NSIndexPath indexPath)
{
if(!accessoryPushed)
{
accessoryPushed(this,EventArgs.Empty);
}
}
You will need to add this to the DailogViewController code that you are using (this will override the tapping action). Instead of a simple function, you may want an event to be triggered, so just handle the event in your main code. That is probably your best bet.
Once you change this line, you will have to implement new functions like AccessorySelected (just mimic the path the code follows when a row is selected except with accessory).
On the other hand, you could try a different navigation method, often disclosure buttons are annoying and you don't want to click on them except to get simple information about the button (like a help feature).
I haven't found any other examples, sorry!

Resources