Custom Controls in Xamarin iOS with MVVMCross and no XIB - xamarin.ios

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

Related

Adding paintcode stylekit images to storyboard not showing preview

I'm following the instructions for adding stylekit images to storyboards by adding an object, setting it's class to stylekit and then right click dragging to the UIImage from the stylekit object - however I'm not seeing the images show up in UIImageView preview in the storyboard. The image is there when I run the code however.
Is there a different series of steps I need to take? I'm using ios9 xcode 7.
Interface Builder doesn’t allow previewing this kind of connections. To see the image in IB, you will need to subclass the view, mark it as #IBDesignable and override drawRect method, where you call the StyleKit drawing method.

suggestions how to achieve DatePickerDialog equivalent using mvvmcross & monotouch

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

Adding images to mkmapview Monotouch

I had found this post on the site for adding UIImage to the MKMapView but this is in the objective-c. can any body help how can we use it on the monotouch by c# ?
https://stackoverflow.com/a/6554418
I recommand you to view this screencast from Xamarin about "Developing iOS Map Applications with C#".
It doesn't cover the custom MKOverlayView drawing part because it's exactly as creating a custom view and overriding it's drawing routine.
But it does explain you how and why you have to endup here..
Basically, you have to
create a custom MKImageOverlay object (subclassing MKOverlay)
create a custom MKImageOverlayView object (subclassing MKOverlayView) that will handle the actual image drawing methods (like any view drawing overriding using CoreGraphics)
add your custom MKImageOverlay to the map with MKMapView.addOverlay() method
provide a MKMapViewDelegate to the map that will handle your custom MKImageOverlay by overriding GetViewForOverlay and returning your custom MKImageOverlayView
You could look at this SO post here too : MonoTouch Mapkit image overlay
Cheers

show popovers on uilabel touch in iphone

I have a number of UILabels on a single view of a iphone application ios 4.3. How to handle touch events for all these labels at one time? I wanted to show pop overs on touch of that label. I know popovers are not available on iphone and will be making my custom ones.
what i did was using UITapGestureRecognizer and adding an action #selector(labelTap:) and then doing [label addGestureRecognizer:TapGestureRecognizerObject. But when i use the same UITapGestureRecognizer for all my UIlabels only the last added label shows the tap action.
i have set userInteractionEnable to YES.
Can any one point me to the right direction?
You need to create separate UITapRecognizer for tracking different UILabel, when a UIGestureRecognizer is added to multiple views, it will only track event from last it added to. To better understand why you need different instances of UITapRecognizer, think of it as a UIView that only handles touches event but doesn't do any drawing.

Monotouch - programming for Swipe Gesture

I am developing a control for an IPAD application (My first time doing Apple development). Its a simple control that mimics a grid - consists of a collection of UIViews (each of which represents a cell) all added to a parent UIView (in a grid like fashion).
One of the requirements is to implement a swipe gesture - the users swipe across the grid to activate/inactivate the cell - this corresponds to a 1/0 in the database.
I create a UISwipeGesture and added it to each of my UIView which represents a cell. That appears to be an incorrect approach as it fires the event for the UIView in which the swipe originated but not across all the UIViews.
My understanding would be that i need to implement the SwipeGesture across the parent UIView which contains all these children UIView. However if i do that how will i know which child UIView has been swiped over? Or any other approach which would make sense?
I know this thread is fairly old, but I created a Swipe extension method that might have helped.
View.Swipe(UISwipeGestureRecognizerDirection.Right).Event += Swipe_Event;
void Swipe_Event(ViewExtensions.SwipeClass sender, UISwipeGestureRecognizer recognizer)
{
View view = sender.View; // do something with view that was swiped.
}
This may not answer your question, but I can speak to the approach I've taken here with a similar use case:
1) I would abandon UIScrollView and use UITableView. You'll notice that UITableView inherits from UIScrollView and has all the performance benefits of virtualization and cell / view re-use. Which you'll find terribly useful as you work towards optimizing your app for performance on device.
2) Utilize the UITableViewCell's ContentView to create custom "Grid" cells. Or better yet, utilize MonoTouch.Dialog if you're not required to create Grid rows ad-hoc.
3) Use this awesome class (props to #praeclarum) to setup gestures in MonoTouch. You essentially provide a UIGestureRecognizer as a generic argument. You can then utilize the LocationInView method to grab the point in the UITableView where the gesture occurred
public void HandleSwipe(UISwipeGestureRecognizer recognizer)
{
if(recognizer.State == UIGestureRecognizerState.Ended) {
var point = recognizer.LocationInView(myTableView);
var indexPath = myTableView.IndexPathForRowAtPoint(point);
// do associated calculations here
}
}
I think you're correct that the gesture recognizer has to be attached to the parent view. In the action method associated with the gesture recognizer I think you can use the Monotouch equivalent of CGRectContainsPoint() to determine whether the swipe occurred in a particular subview. I imagine you would have to iterate through the subviews until you found the one in which the swipe occurred. I'm not aware of a method that would immediately identify the swiped subview.

Resources