MKPinannotation Details Button - New Look

FirstViewController.h

#import <UIKit/UIKit.h> #import <MapKit/MapKit.h> @interface TransparentToolbar : UIToolbar{ } @end @interface AddressAnnotation : NSObject <MKAnnotation> { CLLocationCoordinate2D coordinate; NSString *title; NSString *subTitle; NSString *directions; NSString *website; } @property (nonatomic,retain) NSString *title; @property (nonatomic,retain) NSString *subtitle; @property (nonatomic,retain) NSString *directions; @property (nonatomic,retain) NSString *website; @end @interface FirstViewController : UIViewController { IBOutlet MKMapView *mapView; //stores go here! //declare store names as Company *cityState AddressAnnotation *chiliAuburnAlabama; AddressAnnotation *tuttifruttiHomewoodAlabama; NSString *website; } @property (nonatomic,retain) NSString *website; -(IBAction) updateLocation; -(IBAction) setMap:(id)sender; -(IBAction) showPin; @end FirstViewController.m #import "FirstViewController.h" #import "MoreInfo.h" @implementation AddressAnnotation @synthesize title; @synthesize subtitle; @synthesize coordinate; @synthesize directions; @synthesize website; - (NSString *)subtitle{ return subtitle; } -(NSString *) website{ return website; } -(NSString *) directions{ return directions; } - (NSString *)title{ return title; } -(id)initWithCoordinate:(CLLocationCoordinate2D) c{ coordinate=c; return self; } @end @implementation TransparentToolbar // Override draw rect to avoid // background coloring - (void)drawRect:(CGRect)rect { // do nothing in here } // Set properties to make background // translucent. - (void) applyTranslucentBackground { self.backgroundColor = [UIColor clearColor]; self.opaque = NO; self.translucent = YES; } // Override init. - (id) init { self = [super init]; [self applyTranslucentBackground]; return self; } // Override initWithFrame. - (id) initWithFrame:(CGRect) frame { self = [super initWithFrame:frame]; [self applyTranslucentBackground]; return self; } @end @implementation FirstViewController @synthesize website; // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)mapViewWillStartLocatingUser:(MKMapView *)mapView{ } - (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation{ [self showPin]; } - (void)viewDidLoad { mapView.showsUserLocation = YES; //[self showPin]; [super viewDidLoad]; } -(IBAction) updateLocation{ mapView.showsUserLocation = YES; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc. that aren't in use. } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. // eg self.myOutlet = nil; } -(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; } }} - (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id <MKAnnotation>)annotation { MKAnnotationView *pinView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"pinView"]; if (!pinView) { pinView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pinView"] autorelease]; pinView.image = [UIImage imageNamed:@"SPOON4.png"]; pinView.frame = CGRectMake(-30, 0, 37.5, 67.5); //pinView.animatesDrop = YES; pinView.canShowCallout = YES; UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; pinView.rightCalloutAccessoryView = rightButton; } else { pinView.annotation = annotation; } if (annotation == mapView.userLocation){ return nil; //default to blue dot } return pinView; } -(IBAction) showPin{ MKCoordinateRegion region; MKCoordinateSpan span; span.latitudeDelta=0.2; span.longitudeDelta=0.2; //MOST CODE WILL BE INSERTED HERE! //INSTRUCTIONS! //CCLocationCoordinate2D companyCity = mapView.userLocation.coordinate; //companyCity.latitude = latitude here; //companyCity.longitutde = longitude here; //CLLocation *companyCityLocation = [[CLLocation alloc] initWithLatitude:companyCity.latitude longitude:companyCity.longitude]; //if(companyCityState != nil) { //[mapView removeAnnotation:companyCityState]; //[companyCityState release]; //companyCityState = nil; //} //companyCityState = [[AddressAnnotation alloc] initWithCoordinate:companyCity]; //companyCityState.title = @"name of shop here"; //double distanceMetersCompanyCityState = [mapView.userLocation.location distanceFromLocation:companyCityLocation]; //double distanceMilesCompanyCityState = distanceMetersCompanyCityState/1609.334; //companyCityState.subtitle= [NSString stringWithFormat:@"%.2f miles away", distanceMilesCompanyCityState]; //[mapView addAnnotation:companyCityState]; //[companyCityState release]; //always declare location as companyCity //if more than one in one city then add a number ie companyCity2 //chili in mobile alabama CLLocationCoordinate2D chiliAuburn = mapView.userLocation.coordinate; chiliAuburn.latitude = 32.606434 ; chiliAuburn.longitude = (-85.484025); CLLocation *chiliAuburnLocation = [[CLLocation alloc] initWithLatitude:chiliAuburn.latitude longitude:chiliAuburn.longitude]; if(chiliAuburnAlabama != nil) { [mapView removeAnnotation:chiliAuburnAlabama]; [chiliAuburnAlabama release]; chiliAuburnAlabama = nil; } chiliAuburnAlabama = [[AddressAnnotation alloc] initWithCoordinate:chiliAuburn]; chiliAuburnAlabama.title = @"Chili Yogurt CafΓ©"; chiliAuburnAlabama.website = @"http://stackoverflow.com/questions/6195774/mkpinannotation-detail-disclosure-button-get-directions-call-number"; double distanceMetersChiliAuburnAlabama = [mapView.userLocation.location distanceFromLocation:chiliAuburnLocation]; double distanceMilesChiliAuburnAlabama = distanceMetersChiliAuburnAlabama/1609.334; chiliAuburnAlabama.subtitle= [NSString stringWithFormat:@"%.1f miles away", distanceMilesChiliAuburnAlabama]; [mapView addAnnotation:chiliAuburnAlabama]; [chiliAuburnAlabama release]; //tutti frutti homewood alabama CLLocationCoordinate2D tuttifruttiHomewood = mapView.userLocation.coordinate; tuttifruttiHomewood.latitude = 33.479775 ; tuttifruttiHomewood.longitude = -86.790977; CLLocation *tuttifruttiHomewoodLocation = [[CLLocation alloc]initWithLatitude:tuttifruttiHomewood.latitude longitude:tuttifruttiHomewood.longitude]; if(tuttifruttiHomewoodAlabama != nil) { [mapView removeAnnotation:tuttifruttiHomewoodAlabama]; [tuttifruttiHomewoodAlabama release]; tuttifruttiHomewoodAlabama = nil; } tuttifruttiHomewoodAlabama = [[AddressAnnotation alloc] initWithCoordinate:tuttifruttiHomewood]; double distanceMetersTuttifruttiHomewoodAlabama = [mapView.userLocation.location distanceFromLocation:tuttifruttiHomewoodLocation]; double distanceMilesTuttifruttiHomewoodAlabama = distanceMetersTuttifruttiHomewoodAlabama/1609.334; tuttifruttiHomewoodAlabama.title = @"Tutti Frutti"; tuttifruttiHomewoodAlabama.subtitle = [NSString stringWithFormat:@"%.1f miles away",distanceMilesTuttifruttiHomewoodAlabama]; [mapView addAnnotation:tuttifruttiHomewoodAlabama]; //ignore below CLLocationCoordinate2D user = mapView.userLocation.coordinate; region.span = span; region.center = user; [mapView setRegion:region animated:TRUE]; [mapView regionThatFits:region]; } - (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views { for(MKAnnotationView *annotationView in views) { if(annotationView.annotation == mv.userLocation) { MKCoordinateRegion region; MKCoordinateSpan span; span.latitudeDelta=0.1; span.longitudeDelta=0.1; CLLocationCoordinate2D location=mv.userLocation.coordinate; region.span=span; region.center=location; [mv setRegion:region animated:TRUE]; [mv regionThatFits:region]; } } } - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control{ MoreInfo *moreInfoView = [[MoreInfo alloc] initWithNibName:@"MoreInfo" bundle:nil]; moreInfoView.title = view.annotation.title ; //moreInfoView.getDirections = @""; moreInfoView.getWebsite = [NSURL URLWithString:view.annotation.website]; [self.navigationController pushViewController:moreInfoView animated:YES]; } - (void)dealloc { [super dealloc]; } @end 

MoreInfo.h

 #import <UIKit/UIKit.h> @interface MoreInfo : UIViewController { IBOutlet UITableView *tableView; NSMutableArray *moreInfo; NSURL *getDirections; NSURL *getWebsite; } -(void)goToWebsite; @property (nonatomic,retain) NSURL *getDirections; @property (nonatomic,retain) NSURL *getWebsite; @end 

MoreInfo.m

 #import "MoreInfo.h" #import "FirstViewController.h" @implementation MoreInfo @synthesize getDirections; @synthesize getWebsite; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)dealloc { [super dealloc]; } - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc that aren't in use. } #pragma mark - View lifecycle - (void)viewDidLoad { moreInfo = [[NSMutableArray alloc] init]; [moreInfo addObject:@"Phone Number"]; [moreInfo addObject:@"Address"]; [moreInfo addObject:@"Go to Website"]; [moreInfo addObject:@"Get Directions"]; [super viewDidLoad]; } /*- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath{ }*/ - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{ if (indexPath.row == 2) { [self goToWebsite]; } } -(void) goToWebsite{ [[UIApplication sharedApplication]openURL:getWebsite]; NSLog(@"website is %@", [getWebsite absoluteString]); } - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [moreInfo count]; } - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{ if (section == 0) { return @"More Information"; }else return nil; } - (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease]; } // Set up the cell... if(indexPath.section == 0){ cell.textLabel.text = [moreInfo objectAtIndex:indexPath.row]; cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; } return cell; } - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{ if(section == 0){ return @"Touch the Address to Get Directions"; }else return nil; } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. // eg self.myOutlet = nil; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } @end 
+6
source share
1 answer

If I understand correctly, you want to add a disclosure button that will allow you to submit a new view with information about the current output annotation. To get the disclosure button, you just need to implement this code:

 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation { MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"pinView"]; if (!pinView) { pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"pinView"] autorelease]; pinView.pinColor = MKPinAnnotationColorRed; pinView.animatesDrop = YES; pinView.canShowCallout = YES; UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; pinView.rightCalloutAccessoryView = rightButton; } else { pinView.annotation = annotation; } return pinView; } 

Now, when you click on the contact on mapView, the disclosure button will be displayed on the presented view. Then you will need to use the following method to tell the application what to do when the expand button is clicked.

 - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control 

In this method, you can present a popover or modal window, or click a view or what you would like to do with information about the current location. You also do not need to create a new tip for each of them. The easiest way would be to synthesize the values ​​in this kind of controller such as phoneNumber and website , and the like. Then in the last method where you present the view, pass the values ​​as needed. For instance,

 NewView *vc = [[NewView alloc] initWithNibName:@"NewView" bundle:nil]; vc.phoneNumber = // the phone number of this location; vc.website = // the website; 

etc. before submitting a presentation. Hope this helps

EDIT: To get rid of this error, for everything you synthesize, you must declare in the header. So you will have

 @interface FirstViewController : UIViewController { IBOutlet MKMapView *mapView; //stores go here! //declare store names as Company *cityState AddressAnnotation *chiliAuburnAlabama; AddressAnnotation *tuttifruttiHomewoodAlabama; NSString *website; // the rest of your synthesized attributes you want in the view controller; } -(IBAction) updateLocation; -(IBAction) setMap:(id)sender; -(IBAction) showPin; @property (nonatomic, retain) NSString *website; // This is the property that will get rid of your error and you should do it to any other attributes you want to pass into the controller; @end 

You will also need this in the annotation header if you use it. He reports that part of the code should expect some string to be sent to it, and she will know how to handle its storage.

As for calling the GoToMap method, you must configure the delegate for your MoreInfo class when you create it. Therefore, in your MoreInfo header, you will have, among other things,

 @interface MoreInfo .... { id delegate; // everything else; } @property (nonatomic, assign) id delegate; // your methods and other properties; @end 

Then, when you create it in your view controller, you will have

 MoreInfo *moreInfoView = [[MoreInfo alloc] initWithNibName:@"MoreInfo" bundle:nil]; moreInfoView.title = view.annotation.title ; moreInfoView.delegate = self; // this assigns the current view controller as its delegate; //moreInfoView.getDirections = [NSURL URLWithString:[NSString stringWithFormat: @"http://maps.google.com/maps?q=%@@%1.6f,%1.6f&z=10", view.annotation.coordinate.latitude, view.annotation.coordinate.longitude]]; moreInfoView.getWebsite = view.annotation.website; [self.navigationController pushViewController:moreInfoView animated:YES]; 

Finally, when you want to call GoToWebsite from your MoreInfo, you can call

 [self.delegate GoToWebsite]; 

This, of course, assumes that the method is in your first view controller (which I could swear it, but can't find it all of a sudden).

But basically how you do it

+27
source

Source: https://habr.com/ru/post/889502/


All Articles