Map View - Disclosure Button to a View - ios

I started programming recently, and I have a question! I have created a mapview with the annotation and disclosure button.
How can I create multiple annotations with disclosure button that, after a tap, go to different descriptions based on the annotation choice?
This is my code:
#synthesize mapView;
-(void)viewDidLoad {
[super viewDidLoad];
[mapView setMapType:MKMapTypeHybrid];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
[mapView setDelegate:self];
MKCoordinateRegion bigBen = { {0.0, 0.0} , {0.0, 0.0} };
bigBen.center.latitude = 51.50063;
bigBen.center.longitude = -0.124629;
bigBen.span.longitudeDelta = 0.02f;
bigBen.span.latitudeDelta = 0.02f;
[mapView setRegion:bigBen animated:YES];
Annotation *ann1 = [[Annotation alloc] init];
ann1.title = #"Big Ben";
ann1.subtitle = #"Your subtitle";
ann1.coordinate = bigBen.center;
[mapView addAnnotation: ann1];
MKCoordinateRegion Bridge = { {0.0, 0.0} , {0.0, 0.0} };
Bridge.center.latitude = 51.500809;
Bridge.center.longitude = -0.120914;
Bridge.span.longitudeDelta = 0.02f;
Bridge.span.latitudeDelta = 0.02f;
[mapView setRegion:Bridge animated:YES];
Annotation *ann2 = [[Annotation alloc] init];
ann2.title = #"Westminster Bridge";
ann2.subtitle = #"Your subtitle";
ann2.coordinate = Bridge.center;
[mapView addAnnotation:ann2];
}
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
MKPinAnnotationView *MyPin=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"current"];
MyPin.pinColor = MKPinAnnotationColorPurple;
UIButton *advertButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[advertButton addTarget:self action:#selector(button:) forControlEvents:UIControlEventTouchUpInside];
MyPin.rightCalloutAccessoryView = advertButton;
MyPin.draggable = NO;
MyPin.highlighted = YES;
MyPin.animatesDrop=TRUE;
MyPin.canShowCallout = YES;
return MyPin;
}

The usual way to do it is to implement -mapView:annotationView:calloutAccessoryControlTapped: in your map view delegate. You can use the annotaionView parameter to decide which annotaion was tapped and what information you want to display.

Related

Map annotation swapping from displaying image to default pin randomly

When the map is tested through simulator I notice that some annotations display the default pin instead of the customized image. When I go back to the apps Home menu and enter the mapview again the same thing happens with different annotations.
This code present 4 annotations out of 20 that I have which all uses the same code.
-(void)viewDidLoad {
[super viewDidLoad];
_locationManager = [[CLLocationManager alloc] init];
[mapView setDelegate:self];
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
MKCoordinateRegion test1 = { {0.0, 0.0} , {0.0, 0.0} };
test1.center.latitude = 55.705609;
test1.center.longitude = 13.195707;
[mapView setRegion:test1 animated:YES];
testmap *ann2 = [[testmap alloc] init];
ann2.title = #"test1";
ann2.subtitle = #"Klicka här för mer info";
ann2.coordinate = test1.center;
ann2.name = #"test1";
[mapView addAnnotation:ann2];
MKCoordinateRegion test2 = { {0.0, 0.0} , {0.0, 0.0} }; //ändra ner
test2.center.latitude = 55.710113;
test2.center.longitude = 13.213500;
[mapView setRegion:test2 animated:YES];
testmap *ann3 = [[testmap alloc] init];
ann3.title = #"test2";
ann3.subtitle = #"Klicka här för mer info";
ann3.coordinate = test2.center;
ann3.name = #"test2";
[mapView addAnnotation:ann3];
MKCoordinateRegion test3 = { {0.0, 0.0} , {0.0, 0.0} };
test3.center.latitude = 55.708981;
test3.center.longitude = 13.197266;
[mapView setRegion:test3 animated:YES];
testmap *ann4 = [[testmap alloc] init];
ann4.title = #"test3";
ann4.subtitle = #"Klicka här för mer info";
ann4.coordinate = test3.center;
ann4.name = #"test3";
[mapView addAnnotation:ann4];
MKCoordinateRegion test4 = { {0.0, 0.0} , {0.0, 0.0} }; //ändra ner
test4.center.latitude = 55.705170;
test4.center.longitude = 13.191277;
[mapView setRegion:test4 animated:YES];
testmap *ann5 = [[testmap alloc] init];
ann5.title = #"test4";
ann5.subtitle = #"Klicka här för mer info";
ann5.coordinate = test4.center;
ann5.name = #"test4";
[mapView addAnnotation:ann5];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapview viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if(annotationView)
return nil;
else
{
MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:AnnotationIdentifier]; annotationView.canShowCallout = YES;
NSString* thisModelName = ((testmap*)annotation).name;
if ([thisModelName isEqualToString:#"test1"]) {
annotationView.image = [UIImage imageNamed:#"test1"];
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
annotationView.rightCalloutAccessoryView = rightButton;
annotationView.canShowCallout = YES;
annotationView.draggable = YES;
annotationView.highlighted = YES;
return annotationView;
}
else if ([thisModelName isEqualToString:#"test2"])
{
annotationView.image = [UIImage imageNamed:#"test2"];
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self action:#selector(myButton:) forControlEvents:UIControlEventTouchUpInside];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
annotationView.rightCalloutAccessoryView = rightButton;
annotationView.canShowCallout = YES;
annotationView.draggable = YES;
annotationView.highlighted = YES;
return annotationView;
}
else if ([thisModelName isEqualToString:#"test3"])
{
annotationView.image = [UIImage imageNamed:#"test3"];
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self action:#selector(myButton:) forControlEvents:UIControlEventTouchUpInside];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
annotationView.rightCalloutAccessoryView = rightButton;
annotationView.canShowCallout = YES;
annotationView.draggable = YES;
annotationView.highlighted = YES;
return annotationView;
}
else if ([thisModelName isEqualToString:#"test4"])
{
annotationView.image = [UIImage imageNamed:#"test4"];
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self action:#selector(myButton:) forControlEvents:UIControlEventTouchUpInside];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
annotationView.rightCalloutAccessoryView = rightButton;
annotationView.canShowCallout = YES;
annotationView.draggable = YES;
annotationView.highlighted = YES;
return annotationView;
}
}
return nil;
}
You're getting default pins "randomly" because of this code:
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if (annotationView)
return nil;
What this code says is if the dequeueReusableAnnotationViewWithIdentifier: returns a view (ie. if annotationView is not nil), return nil from the delegate method.
When you return nil from the viewForAnnotation delegate method, the map view does the following:
If the annotation is of type MKUserLocation, it will display the default blue dot.
If the annotation is not an MKUserLocation, it will display the default red pin.
What you probably meant was:
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if (annotationView)
return annotationView;
However, this will create a new problem because if the dequeue returns a view (a view that was previously used for a different annotation), the image of the dequeued view might not match the image that should be used for the current annotation.
So what will happen is annotation images will switch around "randomly" as you zoom and pan the map.
The proper approach in viewForAnnotation is to:
Get a reference to a view using dequeueReusableAnnotationViewWithIdentifier: and if that returns nil, create a new view. Set view properties that are common to all annotations only when creating a new view.
Using the view reference obtained in step 1, set view properties that are specific to the current annotation. If a dequeued view is being used, update its annotation property as well.
Example:
- (MKAnnotationView *)mapView:(MKMapView *)mapview viewForAnnotation:(id <MKAnnotation>)annotation
{
if (! [annotation isKindOfClass:[testmap class]])
{
//If annotation is NOT a "testmap" (eg. MKUserLocation),
//return nil so map view displays default view for it...
return nil;
}
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if (! annotationView) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];
//set view properties common to all annotations...
annotationView.canShowCallout = YES;
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
//Do not use addTarget with a custom method for callout accessories.
//Instead, use the calloutAccessoryControlTapped delegate method shown below.
annotationView.rightCalloutAccessoryView = rightButton;
annotationView.draggable = YES;
}
else {
//reusing a view, update its annotation to current...
annotationView.annotation = annotation;
}
//AFTER we have a view reference, set annotation-specific properties...
NSString* thisModelName = ((testmap*)annotation).name;
if ([thisModelName isEqualToString:#"test1"]) {
annotationView.image = [UIImage imageNamed:#"test1"];
}
else if ([thisModelName isEqualToString:#"test2"]) {
annotationView.image = [UIImage imageNamed:#"test2"];
}
else if ([thisModelName isEqualToString:#"test3"]) {
annotationView.image = [UIImage imageNamed:#"test3"];
}
else if ([thisModelName isEqualToString:#"test4"]) {
annotationView.image = [UIImage imageNamed:#"test4"];
}
/*
If image name will always be same as `name` property then
can use single line instead of if/else statements:
annotationView.image = [UIImage imageNamed:thisModelName];
*/
return annotationView;
}
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
if ([view.annotation isKindOfClass:[testmap class]]) {
testmap *tm = (testmap *)view.annotation;
NSLog(#"button for '%#' tapped", tm.name);
}
}

Only add pin when button is clicked

I have this code that I need altered slightly. The code I have below creates a pin on my current location (perfectly as I might add).
The only problem is that I need the code only to be run when I click a button, not every time I move.
Here is the code of the current location and the pin.
- (void)viewDidLoad {
[super viewDidLoad];
[self.mapView setDelegate:self];
[self.mapView setShowsUserLocation:YES];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
// zoom to region containing the user location
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 700, 700);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
// add the annotation
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = userLocation.coordinate;
point.title = #"Your Car";
//point.subtitle = #"";
[self.mapView addAnnotation:point];
}
I need this to run when I click a button such as:
-(IBAction)addPin
{
}
In the viewDidLoad: method,
Create a button like this:
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(showPinOnClick)
forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(100.0, 200.0, 150.0, 60.0);
[self.view addSubview:button];
// create the method defined as selector method for the UIButton in your viewcontroller
-(void) showPinOnClick{
//paste your code here to show the pin
CLLocationCoordinate2D location = self.mapview.userLocation.coordinate;
MKCoordinateRegion region;
MKCoordinateSpan span;
location.latitude = -32.008081;
location.longitude = 115.757671;
span.latitudeDelta = 0.03;
span.longitudeDelta = 0.03;
region.span = span;
region.center = location;
[_mapview setRegion:region animated:YES];
[_mapview regionThatFits:region];
//Create your annotation
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
// Set your annotation to point at your coordinate
point.coordinate = location;
point.title = #"Your Car";
//Drop pin on map
[_mapview addAnnotation:point];
[_mapview selectAnnotation:point animated:NO];
}

coloring and adding buttons to annotations in a mutable array in iOS

I am coding an application that uses a mapView in iOS.
I am trying to color the annotations in the mutable array to purple and to add a disclosure button to each pin .
The reason that I am using a mutable array is that I am going to retrieve many places from a DB to view each place on the map with a pin.
My code is :
- (void)viewDidLoad{
[super viewDidLoad];
// Do any additional setup after loading the view.
//code of map
[mapMKMapView setMapType:MKMapTypeStandard];
[mapMKMapView setZoomEnabled:YES];
[mapMKMapView setScrollEnabled:YES];
MKCoordinateRegion newRegion = { {0.0, 0.0},{0.0, 0.0}};
newRegion.center.latitude = 12.968427;
newRegion.center.longitude = 44.997704;
newRegion.span.latitudeDelta = 0.004731;
newRegion.span.longitudeDelta = 0.006952;
[self.mapMKMapView setRegion:newRegion animated:YES];
//multiple annotations
NSMutableArray *locations = [[NSMutableArray alloc] init ];
CLLocationCoordinate2D loc;
annotationClass *myAnn;
//1st annotation
myAnn = [[annotationClass alloc] init];
loc.latitude = 12.968427;
loc.longitude = 44.997704;
myAnn.coordinate = loc;
myAnn.title = #"Nakheel2";
myAnn.subtitle = #"This Al-Nakheel 2 stage";
[locations addObject:myAnn];
//2nd annotaion
myAnn = [[annotationClass alloc] init];
loc.latitude = 12.971532;
loc.longitude = 44.998015;
myAnn.coordinate = loc;
myAnn.title = #"Nakheel21";
myAnn.subtitle = #"This Al-Nakheel 2 stage Hi";
[locations addObject:myAnn];
[self.mapMKMapView addAnnotations:locations];
}
//******
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)locations
{
MKPinAnnotationView *MyPin=[[MKPinAnnotationView alloc] initWithAnnotation:locations reuseIdentifier:#"current"];
MyPin.pinColor = MKPinAnnotationColorPurple;
UIButton *adverButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[adverButton addTarget:self action:#selector(button:) forControlEvents:UIControlEventTouchUpInside];
MyPin.rightCalloutAccessoryView = adverButton;
MyPin.draggable = NO;
MyPin.highlighted = YES;
MyPin.animatesDrop = TRUE;
MyPin.canShowCallout = YES;
return MyPin;
}
The viewForAnnotation delegate method will be called by the map view automatically (you don't explicitly "run" it).
The most likely reason the map view is not calling it is that the map view's delegate is not set.
In the storyboard or xib, make sure the map view's delegate outlet is connected to the view controller (right-click or ctrl-click the map view and connect the delegate outlet to the view controller).
Or, you can add this line in the code in viewDidLoad before the setMapType:
//code of map
mapMKMapView.delegate = self; // <-- add this line
[mapMKMapView setMapType:MKMapTypeStandard];
An unrelated point:
Instead of using a custom action method for the button, I suggest using the map view's own calloutAccessoryControlTapped delegate method. In that method, you'll get direct access to the annotation object that was tapped (via view.annotation). Remove the addTarget and the button: method if you decide to use the delegate method.

Update annotation's subtitle

I'm struggling with setting the subtitle of an annotation in MapView, once it has been clicked.
.m:
MKCoordinateRegion England = { {0.0, 0.0} , {0.0, 0.0} };
England.center.latitude = 51.50063;
England.center.longitude = -0.124629;
England.span.longitudeDelta = 100.0f;
England.span.latitudeDelta = 100.0f;
[mapView setRegion:England animated:YES];
Annotation *ann1 = [[Annotation alloc] init];
ann1.title = #"England";
ann1.subtitle = #"subtitle";
ann1.coordinate = England.center;
[mapView addAnnotation:ann1];
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation: (id<MKAnnotation>)annotation {
MKPinAnnotationView *MyPin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"current"]; MyPin.pinColor = MKPinAnnotationColorPurple;
UIButton *advertButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[advertButton addTarget:self action:#selector(button:) forControlEvents:UIControlEventTouchUpInside];
MyPin.rightCalloutAccessoryView = advertButton;
MyPin.draggable = NO;
MyPin.highlighted = YES;
MyPin.animatesDrop = TRUE;
MyPin.canShowCallout = YES;
return MyPin;
}
- (void)mapView:(MKMapView *)mapView1 didSelectAnnotationView:(MKAnnotationView *)view
{
id<MKAnnotation> selectedAnn = [mapView.selectedAnnotations objectAtIndex:0];
country_title = selectedAnn.title;
selectedAnn.subtitle = #"NEW SUBTITLE";
}
How do I set the subtitle once the annotation has been clicked? I wan't to do it that way, because I get some rows from mysql when it's clicked.. but I don't know how to update the subtitle for the specific annotation?
Thanks in advance! :)
id<MKAnnotation> selectedAnn = view.annotation;
[mapview removeAnnotation:selectedAnn];
.. Add Annotation with new subtitle
[mapview addAnnotation:newselectedAnn];
[newselectedAnn setSelected:Yes animated:No];
Hope this helps

Open different websites through pinpoints in mapview

My idea is to have several (maybe as much as 100) pinpoints in a Google map.
I have created a button in the annotation message that appears when I click the pin. I want each pinpoint to be connected to a website. A different website for each pinpoint.
But at the moment I use this:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
{
[[UIApplication sharedApplication]
openURL:[NSURL URLWithString: #"http://www.google.co.uk"]];
The problem is that with this code, all the pinpoints open the same website.
Is there any way I can specify a web address for each pinpoint?
#import "ViewController.h"
#import "NewClass.h"
#implementation ViewController
#synthesize mapview;
NSString *myString;
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
//[[UIApplication sharedApplication]
//openURL:[NSURL URLWithString: #"http://www.arebikepark.se"]];
NewClass *ann = (NewClass *)view.annotation;
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:ann.website]];
}
-(IBAction)getLocation {
mapview.showsUserLocation = YES;
}
-(IBAction)setMap:(id)sender {
switch (((UISegmentedControl *) sender).selectedSegmentIndex) {
case 0:
mapview.mapType = MKMapTypeStandard;
break;
case 1:
mapview.mapType = MKMapTypeSatellite;
break;
case 2:
mapview.mapType = MKMapTypeHybrid;
break;
default:
break;
}
}
- (void)viewDidLoad {
[super viewDidLoad];
[mapview setMapType:MKMapTypeStandard];
[mapview setZoomEnabled:YES];
[mapview setScrollEnabled:YES];
MKCoordinateRegion region = { {0.0, 0.0 }, {0.0, 0.0 } };
region.center.latitude = 63.399785761795506;
region.center.longitude = 12.91691780090332;
region.span.longitudeDelta = 100.0f;
region.span.latitudeDelta = 100.0f;
[mapview setRegion:region animated:YES];
NewClass *ann = [[NewClass alloc] init];
ann.title = #"Åre";
ann.subtitle = #"www.arebikepark.se";
ann.coordinate = region.center;
ann.website = #"arebikepark.se";
[mapview addAnnotation:ann];
MKCoordinateRegion region1 = { {0.0, 0.0 }, {0.0, 0.0 } };
region1.center.latitude = 61.717050948488904;
region1.center.longitude = 16.153764724731445;
region1.span.longitudeDelta = 100.0f;
region1.span.latitudeDelta = 100.0f;
[mapview setRegion:region1 animated:YES];
NewClass *ann1 = [[NewClass alloc] init];
ann1.title = #"Järvsö";
ann1.subtitle = #"www.jarvsobergscykelpark.se";
ann1.coordinate = region1.center;
ann.website = #"www.jarvsobergscykelpark.se";
[mapview addAnnotation:ann1];
MKCoordinateRegion region2 = { {0.0, 0.0 }, {0.0, 0.0 } };
region2.center.latitude = 57.84191869696362;
region2.center.longitude = 12.02951431274414;
region2.span.longitudeDelta = 100.0f;
region2.span.latitudeDelta = 100.0f;
[mapview setRegion:region2 animated:YES];
NewClass *ann2 = [[NewClass alloc] init];
ann2.title = #"Ale";
ann2.subtitle = #"www.alebikepark.se";
ann2.coordinate = region2.center;
[mapview addAnnotation:ann2];
MKCoordinateRegion region3 = { {0.0, 0.0 }, {0.0, 0.0 } };
region3.center.latitude = 61.17768100166834;
region3.center.longitude = 13.261871337890625;
region3.span.longitudeDelta = 100.0f;
region3.span.latitudeDelta = 100.0f;
[mapview setRegion:region3 animated:YES];
NewClass *ann3 = [[NewClass alloc] init];
ann3.title = #"Kläppen";
ann3.subtitle = #"www.klappen.se/sv/Sommar/Bikepark";
ann3.coordinate = region3.center;
ann3.website = #"www.klappen.se/sv/Sommar/Bikepark";
[mapview addAnnotation:ann3];
MKCoordinateRegion region4 = { {0.0, 0.0 }, {0.0, 0.0 } };
region4.center.latitude = 65.82881853569008;
region4.center.longitude = 15.067813396453857;
region4.span.longitudeDelta = 100.0f;
region4.span.latitudeDelta = 100.0f;
[mapview setRegion:region4 animated:YES];
NewClass *ann4 = [[NewClass alloc] init];
ann4.title = #"Hemavan";
ann4.subtitle = #"www.bikepark.nu";
ann4.coordinate = region4.center;
ann4.website = #"www.bikepark.nu";
[mapview addAnnotation:ann4];
MKCoordinateRegion region5 = { {0.0, 0.0 }, {0.0, 0.0 } };
region5.center.latitude = 63.29058608431198;
region5.center.longitude = 18.7042236328125;
region5.span.longitudeDelta = 100.0f;
region5.span.latitudeDelta = 100.0f;
[mapview setRegion:region5 animated:YES];
NewClass *ann5 = [[NewClass alloc] init];
ann5.title = #"Örnsköldsvik";
ann5.subtitle = #"www.hkbikepark.se";
ann5.coordinate = region5.center;
ann5.website = #"www.hkbikepark.se";
[mapview addAnnotation:ann5];
}
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
MKPinAnnotationView *MyPin =(MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"MyPin"];
if (!MyPin) {
MyPin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"MyPin"];
MyPin.pinColor = MKPinAnnotationColorRed;
MyPin.canShowCallout = YES;
UIButton *details = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
MyPin.rightCalloutAccessoryView = details;
MyPin.canShowCallout = YES;
}
return MyPin;
}
#end
Add a property to your custom annotation class (the one that implements MKAnnotation) that stores the annotation's website. Set this property when you add the annotation to the map:
ann.website = #"http://www.google.co.uk";
[mapView addAnnotation:ann];
Then in the calloutAccessoryControlTapped delegate method, you can access this property:
MyAnnotationClass *ann = (MyAnnotationClass *)view.annotation;
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:ann.website]];
Based on the additional code you posted, the problem is that the website url strings don't have the http:// scheme prefix which the URLWithString method needs to convert the string to a URL. Because the url strings are invalid, the method returns nil which results in the openURL method doing nothing.
So, for example, the lines that set the website property should be:
ann.website = #"http://www.arebikepark.se";
ann1.website = #"http://www.jarvsobergscykelpark.se";
ann2.website = #"http://www.alebikepark.se"; //(line was missing completely)
ann3.website = #"http://www.klappen.se/sv/Sommar/Bikepark";
ann4.website = #"http://www.bikepark.nu";
ann5.website = #"http://www.hkbikepark.se";
Additionally, though the above urls are not a problem, if you intend to use urls with query strings that might contain special characters, you'll also need to escape the url string before passing it. One way is to use the stringByAddingPercentEscapesUsingEncoding method. See this answer by Dave DeLong for an example and some precautions/limitations/alternatives with that method.
Finally, unrelated to your main issue but, here are some additional comments on the code:
You don't need to create a region for each annotation just to set its coordinate. You can just do ann.coordinate = CLLocationCoordinate2DMake(63.399785761795506, 12.91691780090332);
If you are not using ARC, there are several memory leaks.
In viewForAnnotation, you should add an else part to the if statement: else MyPin.annotation = annotation; in case an annotation view is re-used for a different annotation. It probably won't happen with so few annotations but it's logically and technically required.
If you want the user location to appear as a blue dot instead of a red pin, you'll need to add this to the top of the viewForAnnotation method: if ([annotation isKindOfClass:[MKUserLocation class]]) return nil;

Resources