How to keep pin and map centered over moving overlay in MKMapView

How can I hold the pin centered on the map while I move (through Pan Gesture) another view vertically above the map so that the contact remains above the overlay (and not the actual overlay of MapKit).

See attached screenshots for the first and last states.

I have a CGRect of space between the overlay and the top of the screen when the user pans up / down. However, how I use this to move the map and bring it out while scaling to the map when the user turns up ... and zoom in again when the user turns down still eludes me.

I tried different approaches, trying to adjust the visible rectangle to adjust the map display frame. The answer may lie in some MKMapRect / Region tricks.

Initial state

Final state with overlay panned upward

( Freepik CC BY 3.0 hand icon)

+6
source share
2 answers

Actually, the keithbhunter code is slow because, in addition to updating the region faster than it can load it, the map also changes height, which causes additional overhead!

I updated the code to work smoothly.

With this code, I make the map look the same size, but instead I move the center point to compensate for the height of the sliding view.

In order for this code to work, you need to change the keithbhunter setting so that the lower mapView constraint is fully tied to the bottom of the supervisor (and not the slideView (so that the mapView is always the same size as the superview). The rest is the same.

enter image description here

You can also adjust the scale size using the variable maxMetersDistance

Here I am, always focusing on the Eiffel Tower

enter image description hereenter image description here

 import UIKit import MapKit class ViewController: UIViewController { @IBOutlet weak var mapView: MKMapView! @IBOutlet weak var slidingView: UIView! @IBOutlet weak var slidingViewHeight: NSLayoutConstraint! var maxMetersDistance:CGFloat = 10000.0; // customize this to set how far the map zooms out of the interest area override func viewDidLoad() { super.viewDidLoad() let pan = UIPanGestureRecognizer(target: self, action: "viewDidPan:") self.slidingView.addGestureRecognizer(pan) firstTimeCenter() } func firstTimeCenter(){ var coordinate = CLLocationCoordinate2D(latitude: 48.8582, longitude: 2.2945) let region = MKCoordinateRegionMakeWithDistance(coordinate, Double(maxMetersDistance), Double(maxMetersDistance)) self.mapView.setRegion(region, animated: true) } func reloadMap() { let height = CGFloat(self.slidingViewHeight.constant) var regionDistance = (maxMetersDistance / self.view.frame.height) * height regionDistance = maxMetersDistance - regionDistance var coordinate = CLLocationCoordinate2D(latitude: 48.8582, longitude: 2.2945) var mapRect = mapView.visibleMapRect; var metersPerMapPoint = MKMetersPerMapPointAtLatitude(coordinate.latitude); var metersPerPixel = CGFloat(metersPerMapPoint) * CGFloat(mapRect.size.width) / CGFloat(mapView.bounds.size.width); var totalMeters = Double(metersPerPixel) * Double(height/2) coordinate = self.translateCoord(coordinate, MetersLat: -totalMeters, MetersLong: 0.0) let region = MKCoordinateRegionMakeWithDistance(coordinate, Double(regionDistance), Double(regionDistance)) self.mapView.setRegion(region, animated: false) } func viewDidPan(panGesture: UIPanGestureRecognizer) { let location = panGesture.locationInView(self.view) self.slidingViewHeight.constant = self.view.frame.size.height - location.y self.reloadMap() } func translateCoord(coord:CLLocationCoordinate2D, MetersLat:Double, MetersLong:Double)->CLLocationCoordinate2D{ var tempCoord = CLLocationCoordinate2D() var tempRegion = MKCoordinateRegionMakeWithDistance(coord, MetersLat, MetersLong); var tempSpan = tempRegion.span; tempCoord.latitude = coord.latitude + tempSpan.latitudeDelta; tempCoord.longitude = coord.longitude + tempSpan.longitudeDelta; return tempCoord; } } 
+5
source
 class ViewController: UIViewController { @IBOutlet weak var mapView: MKMapView! @IBOutlet weak var slidingView: UIView! @IBOutlet weak var slidingViewHeight: NSLayoutConstraint! override func viewDidLoad() { super.viewDidLoad() self.reloadMap() let pan = UIPanGestureRecognizer(target: self, action: "viewDidPan:") self.slidingView.addGestureRecognizer(pan) } func reloadMap() { let coordinate = CLLocationCoordinate2D(latitude: 37.332363, longitude: -122.030805) let height = Double(self.mapView.frame.size.height) let regionDistance = 0.3 * height * height // random multiplier and exponential equation for scaling let region = MKCoordinateRegionMakeWithDistance(coordinate, regionDistance, regionDistance) self.mapView.setRegion(region, animated: false) } func viewDidPan(panGesture: UIPanGestureRecognizer) { let location = panGesture.locationInView(self.view) self.slidingViewHeight.constant = self.view.frame.size.height - location.y self.reloadMap() } } 

To customize the views, place the map and UIView in your view controller. Use autorun to snap the map to the left, top, and right sides of the screen. Then attach the bottom of the map to the top of the UIView . Then connect the left, bottom, and right sides of the UIView with the add-in. Finally, set the height limit on the UIView to what you want to initialize. This height value will be changed when the user drags the view. This allows UIView to grow as we like, and at the same time remove autostart.

Add @IBOutlet to the view controller for the map view, limiting the length of the UIView and UIView , as in the code above. The regionDistance property is what does the magic of scaling here. This is an exponential equation (which I did randomly) that will calculate the area for a larger or smaller size depending on the height of the map display. reloadMap() uses this to update map scaling. Binding all of this is the UIPanGestureRecognizer on the UIView , which controls the height of the UIView , causing the map to scale.

Pitfall: This forces the map to update the region faster than loading the region, which makes it very nervous. There are probably ways around this. Create an ad.

The coordinate that I used in the example is Apple headquarters.

Apple's HQ

+4
source

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


All Articles