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

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

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

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.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-11-2010, 05:11 AM   #1 (permalink)
Registered Member
 
Join Date: Jul 2010
Posts: 8
Jensen2k is on a distinguished road
Default Looping MKAnnotations from XML

Hey there!

I've been developing an application these last few days, but has come across a stop.

So, what i want to do is display annotations on a map, with location data from an XML. There are data there for 150 pins in norway.

What i have understanded, is that you need to build your own class for each MKAnnotations? I cant have hundreds of classes

I am fairly new to Obj-C, but is learning this quickly!
I came up with a loop to loop trough my values in the XML.

Code:
for (int i = 0; i < 140; i++) {
		Camera *aCamera = [appDelegate.cameras objectAtIndex:i];
		NSLog(@"Latitude%d: %d Longtitude: %d", i, aCamera.lat, aCamera.longt);
	}
Really hope someone can help me
Jensen2k is offline   Reply With Quote
Old 07-11-2010, 11:18 AM   #2 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 6,003
Duncan C has a spectacular aura about
Default

Quote:
Originally Posted by Jensen2k View Post
Hey there!

I've been developing an application these last few days, but has come across a stop.

So, what i want to do is display annotations on a map, with location data from an XML. There are data there for 150 pins in norway.

What i have understanded, is that you need to build your own class for each MKAnnotations? I cant have hundreds of classes

I am fairly new to Obj-C, but is learning this quickly!
Really hope someone can help me
No, you don't create a separate CLASS for each annotation. You create a separate annotation object for each annotation, and they are generally ALL of the same class. (If you had an app that displayed different types of annotations, like businesses, government buildings, museums, etc, you might want different types of data for each, in which case you might decide to have different types of annotation objects to store the data for each.)

Map annotations are simple data objects. They can be any object that supports the MKAnnotation protocol. The only requirement for an annotation is that it have a -coordinate property. It can also have optional title and subtitle properties.

Your annotation object can be as simple as this:

Code:
@interface MyAnnotation : NSObject <MKAnnotation> 
{
	CLLocationCoordinate2D	coordinate;
}
@property (nonatomic, assign)	CLLocationCoordinate2D	coordinate;
@property (nonatomic, copy)		NSString*				title;
@property (nonatomic, copy)		NSString*				subtitle;
@end
Code:
@implementation MyAnnotation

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

@end
Then you would just create one and add it to the map like this:

Code:
MyAnnotation* anAnnotation = [[[MyAnnotation alloc] init] autorelease];
anAnnotation.coordinate = theCoordinate;
[myMapView addAnnotation: anAnnotation];
__________________
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-11-2010, 01:22 PM   #3 (permalink)
Registered Member
 
Join Date: Jul 2010
Posts: 8
Jensen2k is on a distinguished road
Default

Thanks alot! Got it all worked out now :-)
Jensen2k is offline   Reply With Quote
Old 07-11-2010, 01:35 PM   #4 (permalink)
Registered Member
 
Join Date: Jul 2010
Posts: 8
Jensen2k is on a distinguished road
Default

Okay, now i stumbled upon a new problem, a bit more difficult.

I am trying to add an action when clicking on the annotation callout. (If that is what it's called). You know, that blue arrow.

Okay, so here are some code:

Here are the annotations added
Code:
	for (int i = 0; i < 140; i++) {
		Camera *aCamera = [appDelegate.cameras objectAtIndex:i];
		NSLog(@"Road%d: %@", i, aCamera.lat);
		
		cameraMapViewController* anAnnotation = [[[cameraMapViewController alloc] init] autorelease];
		CLLocationDegrees latitude;
		CLLocationDegrees longtitude;
		latitude = [aCamera.lat doubleValue];
		longtitude = [aCamera.longt doubleValue];

		coordinate.latitude = latitude;
		coordinate.longitude = longtitude;
		anAnnotation.title = aCamera.road;
		anAnnotation.subtitle = aCamera.region;
		anAnnotation.coordinate = coordinate;
		
		[cameraMap addAnnotation: anAnnotation];
	}
And here are the custom pin-view made:
Code:

- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
{

	MKPinAnnotationView* customPinView = [[[MKPinAnnotationView alloc]
										   initWithAnnotation:annotation reuseIdentifier:nil] autorelease];
	customPinView.pinColor = MKPinAnnotationColorRed;;
	customPinView.animatesDrop = NO;
	customPinView.canShowCallout = YES;
	
            // add a detail disclosure button to the callout which will open a new view controller page
            //
            // note: you can assign a specific call out accessory view, or as MKMapViewDelegate you can implement:
            //  - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control;
            //
            UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
            [rightButton addTarget:self
                            action:@selector(showDetails:)
                  forControlEvents:UIControlEventTouchUpInside];
            customPinView.rightCalloutAccessoryView = rightButton;
			
            return customPinView;
}
*** you see, the button triggers the showDetails-function, which you can see here:
Code:
- (void)showDetails:(id)sender
{
		
	appDelegate = (VeikameraAppDelegate *)[[UIApplication sharedApplication] delegate];

    // the detail view does not want a toolbar so hide it
    camController = [[showCameraViewController alloc] initWithNibName:@"showCameraViewController" bundle:[NSBundle mainBundle]];
	
	Camera *aCamera = [appDelegate.cameras objectAtIndex:sender];
	
	camController.aCamera = aCamera;
	
	[self.navigationController pushViewController:camController animated:YES];
	[camController release];
	
	//NSLog(@"showDetails, id:%d", sender);
}

So, the problem is that the ID its returning to showDetails(the sender) is of no use for me. I need a integer between 1 and 149(numer of annotations there are). Is it in some way possible to stick each annotation with it's own id? :-)
Jensen2k is offline   Reply With Quote
Old 07-11-2010, 01:57 PM   #5 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 6,003
Duncan C has a spectacular aura about
Default

Quote:
Originally Posted by Jensen2k View Post
Okay, now i stumbled upon a new problem, a bit more difficult.

I am trying to add an action when clicking on the annotation callout. (If that is what it's called). You know, that blue arrow.

Okay, so here are some code:

Here are the annotations added
Code:
	for (int i = 0; i < 140; i++) {
		Camera *aCamera = [appDelegate.cameras objectAtIndex:i];
		NSLog(@"Road%d: %@", i, aCamera.lat);
		
		cameraMapViewController* anAnnotation = [[[cameraMapViewController alloc] init] autorelease];
		CLLocationDegrees latitude;
		CLLocationDegrees longtitude;
		latitude = [aCamera.lat doubleValue];
		longtitude = [aCamera.longt doubleValue];

		coordinate.latitude = latitude;
		coordinate.longitude = longtitude;
		anAnnotation.title = aCamera.road;
		anAnnotation.subtitle = aCamera.region;
		anAnnotation.coordinate = coordinate;
		
		[cameraMap addAnnotation: anAnnotation];
	}
And here are the custom pin-view made:
Code:

- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
{

	MKPinAnnotationView* customPinView = [[[MKPinAnnotationView alloc]
										   initWithAnnotation:annotation reuseIdentifier:nil] autorelease];
	customPinView.pinColor = MKPinAnnotationColorRed;;
	customPinView.animatesDrop = NO;
	customPinView.canShowCallout = YES;
	
            // add a detail disclosure button to the callout which will open a new view controller page
            //
            // note: you can assign a specific call out accessory view, or as MKMapViewDelegate you can implement:
            //  - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control;
            //
            UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
            [rightButton addTarget:self
                            action:@selector(showDetails:)
                  forControlEvents:UIControlEventTouchUpInside];
            customPinView.rightCalloutAccessoryView = rightButton;
			
            return customPinView;
}
*** you see, the button triggers the showDetails-function, which you can see here:
Code:
- (void)showDetails:(id)sender
{
		
	appDelegate = (VeikameraAppDelegate *)[[UIApplication sharedApplication] delegate];

    // the detail view does not want a toolbar so hide it
    camController = [[showCameraViewController alloc] initWithNibName:@"showCameraViewController" bundle:[NSBundle mainBundle]];
	
	Camera *aCamera = [appDelegate.cameras objectAtIndex:sender];
	
	camController.aCamera = aCamera;
	
	[self.navigationController pushViewController:camController animated:YES];
	[camController release];
	
	//NSLog(@"showDetails, id:%d", sender);
}

So, the problem is that the ID its returning to showDetails(the sender) is of no use for me. I need a integer between 1 and 149(numer of annotations there are). Is it in some way possible to stick each annotation with it's own id? :-)

There are a couple of solutions. You can add a numeric tag to the rightButton object that you add to the rightCalloutAccessoryView (UIButtons have a tag property.) Then, in your action, you can get the sender's tag property to retrieve the index.

The problem with that approach is that if you, or the user, does anything to change the numbering of your annotations, like deleting one of them, the indexes are not valid any more.

A better option would be to use the map view delegate calloutAccessoryControlTapped method. That method gives you a pointer to the annotation view which, in turn, gives you a pointer to the annotation object itself.

By the way, I see what looks like a big problem with the code you posted. You create your annotations with the following line of code:

Code:
  cameraMapViewController* anAnnotation = [[[cameraMapViewController alloc] init] autorelease];
The name of the class you are using, "cameraMapViewController", suggests that you are creating a view controller object as an annotation. That would be very bad. View controllers are big complex objects, intended to manage a whole screen-full of views, respond to user interface rotations, handle low memory warnings, etc.

If your annotation objects are simple data container objects, and not view controllers, then the class name is a bad choice. You should call it something like cameraMapAnnotation.
__________________
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
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: 326
15 members and 311 guests
akphyo, alexP, cgokey, EXOPTENDAELAX, flamingliquid, guusleijsten, mariano_donati, ohmniac, Paul Slocum, PavelSea, SLIC, Sloshmonster, Sonuye857, v1n2e7t
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,653
Threads: 94,115
Posts: 402,888
Top Poster: BrianSlick (7,990)
Welcome to our newest member, ohmniac
Powered by vBadvanced CMPS v3.1.0

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