Domanda

I have this code that displays 4 points on a map with a custom image. I have begun to learn that perhaps the way I structured it is not optimal but it is what I have.

Please help me to learn how to make the titles I created show up on the map with the custom poi when someone taps it.

I have two classes that work with the view. The classes are MapAnnotation and LocationsViewController.

Here is the code for each.

MapAnnotation.h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>

@interface MapAnnotation : NSObject <MKAnnotation, MKMapViewDelegate> 
{
    CLLocationCoordinate2D _coordinate;
    NSString * title;

}

@property (nonatomic, copy) NSString *title;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate;

@end

MapAnnotation.m

#import "MapAnnotation.h"
#import "LocationsViewController.h"

@implementation MapAnnotation

@synthesize coordinate = _coordinate;
@synthesize title;

- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate
{
    self = [super init];

    if (self != nil)
    {
        _coordinate = coordinate;
    }

    return self;
}

@end

LocationsViewController.h

#import "TechBookAppDelegate.h"
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>

@interface LocationsViewController : UIViewController <MKMapViewDelegate, MKAnnotation>
{
    IBOutlet MKMapView *worldView;
    IBOutlet UIActivityIndicatorView *activityIndicator;

}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id < MKAnnotation >)annotation;
@end

LocationsViewController.m

#import "LocationsViewController.h"
#import "MapAnnotation.h"
@interface LocationsViewController ()
@end

@implementation LocationsViewController

@synthesize coordinate = _coordinate;
@synthesize title;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Initialization code
    }
    return self;
}

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

    static NSString *AnnotationViewID = @"annotationViewID";

    MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];

    if (annotationView == nil)
    {
        annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID];
    }

    annotationView.image = [UIImage imageNamed:@"app_icon_sm.png"];
    annotationView.annotation = annotation;

    return annotationView;
}



- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    worldView.showsUserLocation = NO;

    CLLocationCoordinate2D wisconsin = {.latitude =  45.620775, .longitude =  -89.47844};
    CLLocationCoordinate2D pennsyvainia = {.latitude =  39.912417, .longitude =  -77.663268};
    CLLocationCoordinate2D nevada = {.latitude =  36.054362, .longitude =  -115.020470};
    CLLocationCoordinate2D texas = {.latitude =  32.555038, .longitude =  -94.295592};
    MapAnnotation *pinWI = [[MapAnnotation alloc] initWithCoordinate: wisconsin] ;
    MapAnnotation *pinPA = [[MapAnnotation alloc] initWithCoordinate: pennsyvainia];
    MapAnnotation *pinNV = [[MapAnnotation alloc] initWithCoordinate: nevada];
    MapAnnotation *pinTX = [[MapAnnotation alloc] initWithCoordinate: texas];
    //UIImage *star = [UIImage imageNamed:@"locations_marker.png"];
                        //////////////////
    pinWI.title = @"Rhinelander, WI";///////
    pinPA.title = @"Chambersburg, PA";//////I dont understand why these do not output a
    pinNV.title = @"Henderson, NV";/////////title if the title property is a part of the
    pinTX.title = @"Marshall, TX";////////// MKAnnotation
                        //////////////////
    [worldView addAnnotation:pinTX];
    [worldView addAnnotation:pinNV];
    [worldView addAnnotation:pinWI];
    [worldView addAnnotation:pinPA];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

I suppose I need a function to create the titles? I really am hoping I do not have to create more classes to do this.

È stato utile?

Soluzione

Your main question is:

How to make the titles I created show up on the map with the custom poi when someone taps it.


In the viewForAnnotation delegate method, you need to set the canShowCallout property of the annotation view to YES (the default is NO):

if (annotationView == nil)
{
    annotationView = [[MKAnnotationView alloc] initWithAnnotation...
    annotationView.canShowCallout = YES;  // <-- add this line
}



Some additional comments unrelated to the question:

  1. In MapAnnotation.h, this class will only be implementing MKAnnotation, not MKMapViewDelegate so remove it from the protocol list to avoid potential compiler warnings and to make the code clearer and cleaner:

    @interface MapAnnotation : NSObject <MKAnnotation>
    
  2. In MapAnnotation.m, you don't need the #import "LocationsViewController.h". Remove it.

  3. In LocationsViewController.h, this class will not be implementing MKAnnotation so remove it from the protocol list to avoid potential compiler warnings and to make the code clearer and cleaner:

    @interface LocationsViewController : UIViewController <MKMapViewDelegate>
    
  4. Also in LocationsViewController.h, it's unnecessary to declare the delegate methods you'll be implementing. You can remove the viewForAnnotation declaration.

  5. In LocationsViewController.m, the @synthesizes for coordinate and title don't belong here. Remove them.

Altri suggerimenti

-(void)locatePlaceonMap:(NSDictionary*)dic
{
[map_bar setScrollEnabled:YES];
map_bar.delegate = self;
MKCoordinateRegion zoomIn = map_bar.region;

zoomIn.span.latitudeDelta  = 0.1f;
zoomIn.span.longitudeDelta  = 0.1f;

zoomIn.center.latitude = ApplicationDelegate.latitude;
zoomIn.center.longitude = ApplicationDelegate.longitude;

[map_bar setRegion:zoomIn animated:NO];

MKPointAnnotation *annotation = [[MKPointAnnotation alloc]init];
annotation.title = [dic valueForKey:@"vName"];
annotation.subtitle = [dic valueForKey:@"t_long_address"];

CLLocationCoordinate2D newlocation = [map_bar.userLocation coordinate];
newlocation.latitude=[[dic valueForKey:@"dLat"]doubleValue];
newlocation.longitude=[[dic valueForKey:@"dLong"]doubleValue];
annotation.coordinate = newlocation;
[map_bar addAnnotation:annotation];
}


#pragma mark MkMapViewDelegate Methods

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:   (id<MKAnnotation>)annotation
{
MKPinAnnotationView *pinView = nil;
static NSString *defaultPinID = @"ReusedPin";
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];

if ( pinView == nil )
    pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID];

if (annotation == mapView.userLocation) {

    return nil;

}else{
    pinView.image = [UIImage imageNamed:@"pin_trophy.png"];
    pinView.pinColor = MKPinAnnotationColorRed;
}
pinView.canShowCallout = YES;
pinView.animatesDrop = NO;

return pinView;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top