Once again thanks to a hint from Geoff, I've pieced a little more of MapKit together. This has been tested with RC2 of MonoTouch. The trick? It ONLY WORKS ON THE DEVICE - the simulator will 'crash' with the Stack Trace shown at the bottom of this post (I'm sure this will be fixed in a future release).
This code in
FinishedLaunching
Once again, use the 'new' AddAnnotationObject method.
mapView.Delegate = new MapViewDelegate(this);with this
MyAnnotation a = new MyAnnotation(
new CLLocationCoordinate2D(-33.867139,151.207114)
, "Home"
, "is where the heart is"
);
Console.WriteLine(" ### This breaks in the simulator BUT it works on device!!!");
mapView.AddAnnotationObject(a);
MKAnnotation
subclassIn MonoTouch
MKAnnotation
is an abstract class, but in ObjectiveC it's a @protocol. This kinda explains why everything in the class is read-only - @protocols are akin to interface
s in C#, but they cannot be "modelled" as interfaces in MonoTouch because @protocols members can be optional! The simplest way to get an annotation is therefore this implementation (although I think you could also create your own subclass of NSObject
and Export()
the MKAnnotation
members manually).public class MyAnnotation : MKAnnotationand this
{
private CLLocationCoordinate2D _coordinate;
private string _title, _subtitle;
public override CLLocationCoordinate2D Coordinate {
get { return _coordinate; }
}
public override string Title {
get { return _title; }
}
public override string Subtitle {
get { return _subtitle; }
}
/// <summary>
/// Need this constructor to set the fields, since the public
/// interface of this class is all READ-ONLY
/// <summary>
public MyAnnotation (CLLocationCoordinate2D coord,
string t, string s) : base()
{
_coordinate=coord;
_title=t;
_subtitle=s;
}
}
MKMapViewDelegate
implementationpublic class MapViewDelegate : MKMapViewDelegate
{
private AppDelegate _appd;
public MapViewDelegate (AppDelegate appd):base()
{
_appd = appd;
}
///
/// When user moves the map, update lat,long text in label
///
public override void RegionChanged
(MKMapView mapView, bool animated)
{
Console.WriteLine("Region did change");
_appd.labelCurrent.Text = "Map Center "
+ mapView.CenterCoordinate.Latitude + ", "
+ mapView.CenterCoordinate.Longitude;
}
///
/// Seems to work in the Simulator now
///
public override MKAnnotationView GetViewForAnnotation
(MKMapView mapView, NSObject annotation)
{
var anv = mapView.DequeueReusableAnnotation("thislocation");
if (anv == null)
{
Console.WriteLine("creating new MKAnnotationView");
anv = new MKPinAnnotationView(annotation, "thislocation");
}
else
{
anv.Annotation = annotation;
}
anv.AnimatesDrop = true;
anv.PinColor = MKPinAnnotationColor.Green;
anv.CanShowCallout = true;
return anv;
}
}
This Stack Trace (below) is what you'll see in MonoDevelop when using the Simulator - upload to the device to get it working (or if you are using the trial version, you may have to wait for an update to MonoTouch). UPDATE:fixed in MonoTouch 1.1
at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication.UIApplicationMain (int,string[],intptr,intptr) <0x00004>
at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication.UIApplicationMain (int,string[],intptr,intptr)
at MonoTouch.UIKit.UIApplication.Main (string[],string,string)
at MonoTouch.UIKit.UIApplication.Main (string[])
at MapKit01.Application.Main (string[])
at (wrapper runtime-invoke).runtime_invoke_void_object (object,intptr,intptr,intptr)
Native stacktrace:
0 MapKit01 0x00092d1a mono_handle_native_sigsegv + 266
1 MapKit01 0x00006f3a mono_sigsegv_signal_handler + 298
2 libSystem.B.dylib 0x90b25b9b _sigtramp + 43
3 ??? 0xffffffff 0x0 + 4294967295
Debug info from gdb:
warning: Trying to remove a section from the ordered section list that did not exist at 0x2d4000.
Can you pls post the entire sln?
ReplyDeleteI'm happy to report that, having tried the above code with MonoTouch 1.1 (just released on the MonoTouch website), it works :)
ReplyDeleteI am getting errors that these properties do not exist:
ReplyDelete//anv.AnimatesDrop = true
//anv.PinColor = MKPinAnnotationColor.Green;
its a nice article... i just tried some funstuff with mapkit and it works fine. I have a small issue, i want to get Bounding Region of the map in LatLongs.I think with MKMapView Class's Region property i can get it but i don't know how to make correct region using Center Point and Span.
ReplyDeleteI got 2 error while compiling the source.
ReplyDeleteIt said:
MapKit01.AppDelegate.MyAnnotation.coordinate' is marked as an override but no suitable property found to override
MapKit01.AppDelegate.MapViewDelegate.GetViewForAnnotation(MonoTouch.MapKit.MKMapView, MonoTouch.MapKit.MKAnnotation)': cannot override because `MonoTouch.MapKit.MKMapViewDelegate.GetViewForAnnotation(MonoTouch.MapKit.MKMapView, MonoTouch.Foundation.NSObject)' is not a method
I'm using MonoTouch 1.1 and the latest MonoDevelop 2.2.1
Post has been updated with a MonoDevelop solution that works with MonoTouch 1.1 - MapKit03.zip.
ReplyDeletehihi....i've downloaded the MapKit03.zip to learn about the mapkit...but When I compiled it, it told me that there was an error :
ReplyDelete`MapKit01.AppDelegate.MyAnnotation' does not implement inherited abstract member `MonoTouch.MapKit.MKAnnotation.Coordinate.set' (CS0534) (MapKit03)
Should I do any modifications ?
Yes - the example is over one year old! Your MKAnnotation subclass should include both get and set for the Coordinate property.
ReplyDeleteprivate CLLocationCoordinate2D coordinate;
public override CLLocationCoordinate2D Coordinate
{
get { return coordinate; }
set { coordinate = value; } // required for iOS 3.2/4.0
}
how to set multiple coordinates in a single view?
ReplyDeleteThis drawing on maps with monotouch also contains examples of adding multiple pins to a map. Also there is a whole chapter on Mapping in my book
ReplyDeleteThank you very much,
ReplyDeletebut my requirement is to show multiple addresses (contacts) in a single view without any lines between addresses.
When I try and use your "MyAnnotation" class I get this error:
ReplyDelete.MyAnnotation' does not implement inherited abstract member `MonoTouch.MapKit.MKAnnotation.Coordinate.set' (CS0534)
Jack, unfortunately the base class has changed since this blogpost - you must now implement the 'set' as well. See the comment above from 22-Oct-2010, your MyAnnotation class needs this:
ReplyDeleteprivate CLLocationCoordinate2D coordinate;
public override CLLocationCoordinate2D Coordinate
{
get { return coordinate; }
set { coordinate = value; } // required for iOS 3.2/4.0
}