Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Mockup & CodeGen, iPhone & iPad
($9.99)

Make your own iPhone apps
and run them live!
(free)

Manu
($0.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 07-29-2010, 03:56 PM   #1 (permalink)
Registered Member
 
Ovidius's Avatar
 
Join Date: Jun 2010
Posts: 77
Angry MKAnnotation

Hi,

I am having a SERIOUSLY hard time trying to get MKAnnotation working . I Googled this so much today, spent a DECENT number of hours with no luck . Can someone post some code as to how this thing is supposed to be declared or how these protocols are supposed to be set up? Please give me some kind of step-by-step help. I have my MKMapView ready to go, I just can't create this MKAnnotation object for the life of me.

I want the simplest case: Add an MKPinAnnotationView at the user's current location.

Last edited by Ovidius; 07-29-2010 at 04:16 PM.
Ovidius is offline   Reply With Quote
Old 07-29-2010, 06:30 PM   #2 (permalink)
Registered Member
 
Ovidius's Avatar
 
Join Date: Jun 2010
Posts: 77
Default

Bump.
Ovidius is offline   Reply With Quote
Old 07-29-2010, 06:49 PM   #3 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 4,814
Default

Quote:
Originally Posted by Ovidius View Post
Hi,

I am having a SERIOUSLY hard time trying to get MKAnnotation working . I Googled this so much today, spent a DECENT number of hours with no luck . Can someone post some code as to how this thing is supposed to be declared or how these protocols are supposed to be set up? Please give me some kind of step-by-step help. I have my MKMapView ready to go, I just can't create this MKAnnotation object for the life of me.

I want the simplest case: Add an MKPinAnnotationView at the user's current location.

An annotation object is ANY object that implements the MKAnnotation protocol. The MKAnnotation protocol is painfully simple: It's just an object that has a property coordinate, and optionally properties title and subtitle.

You declare that an object supports a protocol by putting the protocol name in angle brackets at the end of the @interface declaration. If an object supports more than one protocol, you just list the protocols inside angle brackets, separated by commas. The relevant line in the MyAnnotation object is:

Code:
@interface MyAnnotation : NSObject <MKAnnotation>
Here is the header file for a sample annotation object:


Code:
#import <Foundation/Foundation.h>

@interface MyAnnotation : NSObject <MKAnnotation> 

{
	CLLocationCoordinate2D	coordinate;
	NSString*				title;
	NSString*				subtitle;
}

@property (nonatomic, assign)	CLLocationCoordinate2D	coordinate;
@property (nonatomic, copy)		NSString*				title;
@property (nonatomic, copy)		NSString*				subtitle;

@end
And here is the body:


#import "MyAnnotation.h"


Code:
#import "MyAnnotation.h"

@implementation MyAnnotation

@synthesize title;
@synthesize subtitle;
@synthesize coordinate;

- (void)dealloc 
{
	self.title = nil;
	self.subtitle = nil;
}
@end
__________________
Regards,

Duncan C
WareTo

Check out our apps in the Apple App store


Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.

See this tutorial on using UIView animations and layer animations:

See this thread on generating random, non-repeating text

Check out a very cool Macintosh Kaleidoscopes app called ScopeWorks that we released to the Mac App store.
Duncan C is offline   Reply With Quote
Old 07-29-2010, 06:52 PM   #4 (permalink)
Registered Member
 
Ovidius's Avatar
 
Join Date: Jun 2010
Posts: 77
Default

Hi Duncan,

Thanks for the quick response.

I have a question: How do you set the coordinate? It seems to me like it is read-only.
Ovidius is offline   Reply With Quote
Old 07-29-2010, 07:16 PM   #5 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 4,814
Default

Quote:
Originally Posted by Ovidius View Post
Hi Duncan,

Thanks for the quick response.

I have a question: How do you set the coordinate? It seems to me like it is read-only.

coordinate is a read/write property, so you just change it.

You could say:

Code:
anAnnotation = [[MyAnnotation alloc] init];
anAnnotation.coordinate = CLLocationCoordinate2DMake(0,0);
(Obviously, you would not use a coordinate of 0,0, but you get the idea.)
__________________
Regards,

Duncan C
WareTo

Check out our apps in the Apple App store


Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.

See this tutorial on using UIView animations and layer animations:

See this thread on generating random, non-repeating text

Check out a very cool Macintosh Kaleidoscopes app called ScopeWorks that we released to the Mac App store.
Duncan C is offline   Reply With Quote
Old 07-29-2010, 07:17 PM   #6 (permalink)
Registered Member
 
Ovidius's Avatar
 
Join Date: Jun 2010
Posts: 77
Default

I'm sorry about my previous post, I was looking at the Apple Reference for this protocol and it stated the coordinate as readonly, which gave me problems when assigning its @property and then synthesizing its setters and getters. However:

Basically, I have my class set up as you mention. I tried the following:

Code:
MapAnnotation *startAnnotation = [[MapAnnotation alloc] initWithCoordinate:userLocation.coordinate];
			MKPinAnnotationView *startAnnotationPin = [[MKPinAnnotationView alloc] initWithAnnotation:startAnnotation reuseIdentifier:@"StartPin"];
			startAnnotationPin.pinColor = MKPinAnnotationColorGreen;
			[mapView addAnnotation:startAnnotationPin];
I get this error: warning: class 'MKPinAnnotationView' does not implement the 'MKAnnotation' protocol
Ovidius is offline   Reply With Quote
Old 07-29-2010, 07:40 PM   #7 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 4,814
Default

Quote:
Originally Posted by Ovidius View Post
I'm sorry about my previous post, I was looking at the Apple Reference for this protocol and it stated the coordinate as readonly, which gave me problems when assigning its @property and then synthesizing its setters and getters. However:

Basically, I have my class set up as you mention. I tried the following:

Code:
MapAnnotation *startAnnotation = [[MapAnnotation alloc] initWithCoordinate:userLocation.coordinate];
			MKPinAnnotationView *startAnnotationPin = [[MKPinAnnotationView alloc] initWithAnnotation:startAnnotation reuseIdentifier:@"StartPin"];
			startAnnotationPin.pinColor = MKPinAnnotationColorGreen;
			[mapView addAnnotation:startAnnotationPin];
I get this error: warning: class 'MKPinAnnotationView' does not implement the 'MKAnnotation' protocol


You've got the sequence wrong. You create an annotation object and add it to the map. Then, later, the system asks for an annotation view to display that annotation on the map. The code you posted should look like this:

Code:
MapAnnotation *startAnnotation = [[MapAnnotation alloc] 
  initWithCoordinate:userLocation.coordinate];
[mapView addAnnotation: startAnnotation];
Then, you need to add a mapView:viewForAnnotation: method to your map view delegate. That method gets called when the system needs an annotation view to display the annotation you just created.

Something like this:

Code:
- (MKAnnotationView *)mapView:(MKMapView *)mapView
			viewForAnnotation:(id <MKAnnotation>)annotation 
{
  MapAnnotation* theAnnotation = (MapAnnotation*) annotation;
  if(annotation != mapView.userLocation) 
  {
  if ([annotation isKindOfClass: [MapAnnotation class]])
    {
      MKPinAnnotationView *startAnnotationPin = [[MKPinAnnotationView alloc] initWithAnnotation:startAnnotation reuseIdentifier:@"StartPin"];
      startAnnotationPin.pinColor = MKPinAnnotationColorGreen;
      return startAnnotationPin.pinColor;
    }
  }
  else
    return nil;
}

Disclaimer: I banged out the code I'm posting without even checking to make sure it compiles, much less runs without errors. My code rarely compiles the first time, so there are likely syntax errors in the code above.
__________________
Regards,

Duncan C
WareTo

Check out our apps in the Apple App store


Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.

See this tutorial on using UIView animations and layer animations:

See this thread on generating random, non-repeating text

Check out a very cool Macintosh Kaleidoscopes app called ScopeWorks that we released to the Mac App store.
Duncan C is offline   Reply With Quote
Old 07-29-2010, 08:11 PM   #8 (permalink)
Registered Member
 
Ovidius's Avatar
 
Join Date: Jun 2010
Posts: 77
Default

Quote:
Originally Posted by Duncan C View Post
You've got the sequence wrong. You create an annotation object and add it to the map. Then, later, the system asks for an annotation view to display that annotation on the map. The code you posted should look like this:

Code:
MapAnnotation *startAnnotation = [[MapAnnotation alloc] 
  initWithCoordinate:userLocation.coordinate];
[mapView addAnnotation: startAnnotation];
Then, you need to add a mapView:viewForAnnotation: method to your map view delegate. That method gets called when the system needs an annotation view to display the annotation you just created.

Something like this:

Code:
- (MKAnnotationView *)mapView:(MKMapView *)mapView
			viewForAnnotation:(id <MKAnnotation>)annotation 
{
  MapAnnotation* theAnnotation = (MapAnnotation*) annotation;
  if(annotation != mapView.userLocation) 
  {
  if ([annotation isKindOfClass: [MapAnnotation class]])
    {
      MKPinAnnotationView *startAnnotationPin = [[MKPinAnnotationView alloc] initWithAnnotation:startAnnotation reuseIdentifier:@"StartPin"];
      startAnnotationPin.pinColor = MKPinAnnotationColorGreen;
      return startAnnotationPin.pinColor;
    }
  }
  else
    return nil;
}

Disclaimer: I banged out the code I'm posting without even checking to make sure it compiles, much less runs without errors. My code rarely compiles the first time, so there are likely syntax errors in the code above.
No worries, but I do get some errors which I don't know how to deal with:

Code:
- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id <MKAnnotation>)anAnnotation 
{
	if ([anAnnotation isKindOfClass:MapAnnotation]) <- expected expression before 'MapAnnotation'



	{
		MapAnnotation *theAnnotation = [[MapAnnotation alloc] init];
		theAnnotation = (MapAnnotation *)anAnnotation; <- 'theAnnotation' undeclared (first use in this function)



		if (theAnnotation.identifier == @"StartAnnotation")
		{
			MKPinAnnotationView *startAnnotationPin = [[MKPinAnnotationView alloc] initWithAnnotation:anAnnotation reuseIdentifier:@"StartPin"];
			startAnnotationPin.pinColor = MKPinAnnotationColorGreen;
			return startAnnotationPin;
		}
		return nil;
	}
} <-- control reaches end of non-void function
Ovidius is offline   Reply With Quote
Old 07-29-2010, 08:35 PM   #9 (permalink)
Registered Member
 
Ovidius's Avatar
 
Join Date: Jun 2010
Posts: 77
Default

Quote:
Originally Posted by Ovidius View Post
No worries, but I do get some errors which I don't know how to deal with:

Code:
- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id <MKAnnotation>)anAnnotation 
{
	if ([anAnnotation isKindOfClass:MapAnnotation]) <- expected expression before 'MapAnnotation'



	{
		MapAnnotation *theAnnotation = [[MapAnnotation alloc] init];
		theAnnotation = (MapAnnotation *)anAnnotation; <- 'theAnnotation' undeclared (first use in this function)



		if (theAnnotation.identifier == @"StartAnnotation")
		{
			MKPinAnnotationView *startAnnotationPin = [[MKPinAnnotationView alloc] initWithAnnotation:anAnnotation reuseIdentifier:@"StartPin"];
			startAnnotationPin.pinColor = MKPinAnnotationColorGreen;
			return startAnnotationPin;
		}
		return nil;
	}
} <-- control reaches end of non-void function
OK I got it now, for those who may want the same answer:

Code:
- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id <MKAnnotation>)anAnnotation 
{
	if ([anAnnotation isKindOfClass:[MapAnnotation class]])
	{
		MapAnnotation *theAnnotation = (MapAnnotation *)anAnnotation;
		if (theAnnotation.identifier == @"StartAnnotation")
		{
			MKPinAnnotationView *startAnnotationPin = [[MKPinAnnotationView alloc] initWithAnnotation:anAnnotation reuseIdentifier:@"StartPin"];
			startAnnotationPin.pinColor = MKPinAnnotationColorGreen;
			return startAnnotationPin;
		}
	}
	return nil;
}
I guess I should note I included an NSString named identifier in the class of MapAnnotation...

Duncan, thanks so much for your help, it went a long way. I never did map annotations until now, and the way they are implemented in the framework is extremely weird IMHO, but anyways, thank you. Without your guidance I don't know how else I could have understood the MKAnnotation class.

Last edited by Ovidius; 07-29-2010 at 08:39 PM.
Ovidius is offline   Reply With Quote
Old 07-29-2010, 08:47 PM   #10 (permalink)
Registered Member
 
Ovidius's Avatar
 
Join Date: Jun 2010
Posts: 77
Default

modded again to avoid mem leakz:

Code:
- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id <MKAnnotation>)anAnnotation 
{
	MKPinAnnotationView *pin = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier: @"StartPin"];
	if (pin == nil)
	{
		if ([anAnnotation isKindOfClass:[MapAnnotation class]])
		{
			MapAnnotation *theAnnotation = (MapAnnotation *)anAnnotation;
			if (theAnnotation.identifier == @"StartAnnotation")
			{
				MKPinAnnotationView *startAnnotationPin = [[MKPinAnnotationView alloc] initWithAnnotation:anAnnotation reuseIdentifier:@"StartPin"];
				startAnnotationPin.pinColor = MKPinAnnotationColorGreen;
				return startAnnotationPin;
			}
		}
	}
	return nil;
}
Ovidius is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 277
17 members and 260 guests
2WeeksToGo, ADY, dacapo, Dani77, Fritzer, ghost, HDshot, headkaze, iDifferent, mer10, mystic.purple, Rudy, smethorst, stoneage, superg, tathaastu, Zool
Most users ever online was 1,187, 10-11-2011 at 08:09 AM.
» Stats
Members: 158,878
Threads: 89,224
Posts: 380,732
Top Poster: BrianSlick (7,129)
Welcome to our newest member, olga2000
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 11:42 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0