How to add annotation to the map view center on iPhone?

I have a MAP view in my application and I want to add a note for a note (red contact) in the map view center.
Now that the user scroll of the map, the scroll card must adjust to the center accordingly.
How to do it?
thanks

+6
source share
3 answers

If you want to use the actual annotation instead of the normal view located above the center of the map view, you can:

  • use an annotation class with a custom coordinate property (a predefined MKPointAnnotation class, for example). This avoids deleting and adding annotations when the center changes.
  • create annotation in viewDidLoad
  • save the link to it in the property, say, centerAnnation
  • update its coordinate (and name, etc.) in the map view regionDidChangeAnimated delegate (make sure the map delegation property is specified)

Example:

 @interface SomeViewController : UIViewController <MKMapViewDelegate> { MKPointAnnotation *centerAnnotation; } @property (nonatomic, retain) MKPointAnnotation *centerAnnotation; @end @implementation SomeViewController @synthesize centerAnnotation; - (void)viewDidLoad { [super viewDidLoad]; MKPointAnnotation *pa = [[MKPointAnnotation alloc] init]; pa.coordinate = mapView.centerCoordinate; pa.title = @"Map Center"; pa.subtitle = [NSString stringWithFormat:@"%f, %f", pa.coordinate.latitude, pa.coordinate.longitude]; [mapView addAnnotation:pa]; self.centerAnnotation = pa; [pa release]; } - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated { centerAnnotation.coordinate = mapView.centerCoordinate; centerAnnotation.subtitle = [NSString stringWithFormat:@"%f, %f", centerAnnotation.coordinate.latitude, centerAnnotation.coordinate.longitude]; } - (void)dealloc { [centerAnnotation release]; [super dealloc]; } @end 

Now this will move the annotation, but not smoothly. If you want the annotation to move more smoothly, you can add the UIPanGestureRecognizer and UIPinchGestureRecognizer to the map view, as well as update the annotation in the gesture handler:

  // (Also add UIGestureRecognizerDelegate to the interface.) // In viewDidLoad: UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)]; panGesture.delegate = self; [mapView addGestureRecognizer:panGesture]; [panGesture release]; UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)]; pinchGesture.delegate = self; [mapView addGestureRecognizer:pinchGesture]; [pinchGesture release]; - (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer { centerAnnotation.coordinate = mapView.centerCoordinate; centerAnnotation.subtitle = [NSString stringWithFormat:@"%f, %f", centerAnnotation.coordinate.latitude, centerAnnotation.coordinate.longitude]; } - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { //let the map view and our gesture recognizers work at the same time... return YES; } 
+10
source

Answer Anna is a smart approach to keeping map-centered annotations using annotations in a standard way of viewing a map. However, as one commenter noted, scrolling and shrinking, but much better, show a noticeable lag, and the recommended approach is to add an annotation view as a subview of the mapview view. Here is how it looks.

 @interface SHCenterPinMapViewController () <MKMapViewDelegate> @property (weak, nonatomic) IBOutlet MKMapView *mapView; @property (strong, nonatomic) MKPointAnnotation *centerAnnotaion; @property (strong, nonatomic) MKPinAnnotationView *centerAnnotationView; @end @implementation SHCenterPinMapViewController - (MKPointAnnotation *)centerAnnotaion { if (!_centerAnnotaion) { _centerAnnotaion = [[MKPointAnnotation alloc] init]; } return _centerAnnotaion; } - (MKPinAnnotationView *)centerAnnotationView { if (!_centerAnnotationView) { _centerAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:self.centerAnnotaion reuseIdentifier:@"centerAnnotationView"]; } return _centerAnnotationView; } - (void)viewDidLoad { [super viewDidLoad]; self.mapView.delegate = self; [self.mapView addSubview:self.centerAnnotationView]; } -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self moveMapAnnotationToCoordinate:self.mapView.centerCoordinate]; } // These are the constants need to offset distance between the lower left corner of // the annotaion view and the head of the pin #define PIN_WIDTH_OFFSET 7.75 #define PIN_HEIGHT_OFFSET 5 - (void)moveMapAnnotationToCoordinate:(CLLocationCoordinate2D) coordinate { CGPoint mapViewPoint = [self.mapView convertCoordinate:coordinate toPointToView:self.mapView]; // Offset the view from to account for distance from the lower left corner to the pin head CGFloat xoffset = CGRectGetMidX(self.centerAnnotationView.bounds) - PIN_WIDTH_OFFSET; CGFloat yoffset = -CGRectGetMidY(self.centerAnnotationView.bounds) + PIN_HEIGHT_OFFSET; self.centerAnnotationView.center = CGPointMake(mapViewPoint.x + xoffset, mapViewPoint.y + yoffset); } - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated { self.centerAnnotaion.coordinate = mapView.centerCoordinate; [self moveMapAnnotationToCoordinate:mapView.centerCoordinate]; } @end 

Actually, the only interesting thing is not that you need to compensate MKPinAnnotationView by a certain amount to take into account the distance between the lower left corner and the pin head. I don't like these asset-dependent constants in the code, so if anyone can find a better way to do this, I’m all ears.

I created a github project with a map controller that does this, as well as some other things related to using mapview so the user can select a location. Take a look here: https://github.com/scottrhoyt/CenterPinMapViewController

+4
source

Quick version

In class:

 var centerAnnotation = MKPointAnnotation() var centerAnnotationView = MKPinAnnotationView() 

In viewDidLoad:

 if #available(iOS 9.0, *) { centerAnnotationView.pinTintColor = customColor } else { // Fallback on earlier versions centerAnnotationView.pinColor = MKPinAnnotationColor.Red } self.view.addSubview(centerAnnotationView) 

In viewDidAppear:

 self.moveMapAnnotationToCoordinate(self.mapView.centerCoordinate) 

Then:

 func moveMapAnnotationToCoordinate(locate : CLLocationCoordinate2D ) { let mapViewPoint : CGPoint = self.mapView.convertCoordinate(locate, toPointToView: self.mapView) let pinWidth : CGFloat = 7.75 let pinHeight : CGFloat = 7 let xOffset : CGFloat = CGRectGetMidX(self.centerAnnotationView.bounds) - pinWidth let yOffset : CGFloat = CGRectGetMidY(self.centerAnnotationView.bounds) - pinHeight self.centerAnnotationView.center = CGPointMake(mapViewPoint.x - xOffset, mapViewPoint.y - yOffset) } 

To use the location change, add the CLLocationManagerDelegate delegate, and then:

 func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) { self.centerAnnotation.coordinate = self.mapView.centerCoordinate self.moveMapAnnotationToCoordinate(self.mapView.centerCoordinate) } 
0
source

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


All Articles