2015-05-17 40 views
6

如何在地图上保持销位于中心位置,同时我(通过Pan Gesture)移动另一个视图,以便引脚保持在覆盖图上方一个实际的MapKit覆盖)。如何保持销和地图上方移动覆盖在MKMapView上方

请参阅第一个和最后一个状态的附件截图。

我已经获得了覆盖层和屏幕顶部之间的空间的CGRect作为用户平移的上/下。然而,当用户向上移动时,我如何使用它来移动地图和别针,同时放大地图。当用户向下平移时,再次缩小地图,迄今为止已经避开了我。

我试过不同的方法,试图调整可见矩形以调整地图视图的框架。答案可能在于一些MKMapRect /地区弄虚作假..

Initial state

Final state with overlay panned upward

(由Freepik CC手形图标3.0)

+0

你试过'setCenterCoordinate'的方法呢? –

+0

当您平移覆盖图时,地图应该是放大还是缩小? – keithbhunter

+0

@keithbhunter是的,向内平移,向上平移,向下平移。 – Aodh

回答

4
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() 
    } 

} 

要设置的意见,把地图视图和您的视图控制器中的UIView。使用自动布局将地图视图的左侧,顶部和右侧固定到超级视图。然后将地图视图的底部固定到UIView的顶部。接下来,将UIView的左侧,底部和右侧固定到超级视图。最后,将UIView上的高度约束设置为您希望初始化为的任何值。此高度值将随用户拖动视图而更改。这使得UIView可以随我们的需要增长,并同时安抚自动布局。

将地图视图UIViewUIView的高度限制添加到您的视图控制器中,如上面的代码中所示。 regionDistance属性是在这里做变焦魔术的。它是一个指数方程(我随机组成),根据地图视图的高度计算出较大或较小的区域。 reloadMap()使用它来更新地图的缩放。将它们联系在一起的就是UIView上的UIPanGestureRecognizer,它控制着UIView的高度,导致地图上的缩放操作。

陷阱:这会强制地图更新区域的速度比装载区域的速度更快,使其看起来非常跳跃。这可能有解决方法。获得创意。

我在示例中使用的坐标是Apple的总部。

Apple's HQ

5

事实上,keithbhunter的代码是缓慢的,因为除了更新区域的速度比它可以加载它,地图也正在改变高度会导致额外的开销!

我更新了代码,使其运行平稳。

有了这段代码,我所做的就是保持地图视图具有相同的大小,但是我会移动中心点以补偿滑动视图的高度。

对于这段代码的工作,你必须修改keithbhunter的设置,使得mapView的底部约束完全固定到超级视图的底部(而不是滑动视图(这样mapView始终与超级视图的大小相同)对于剩下的设置是一样的。

enter image description here

此外,也可以自定义缩放量与可变maxMetersDistance

我在这里,总是在艾菲尔铁塔

中心

enter image description here enter 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; 
    } 

} 
+0

感谢Juan&Keith! Juan的解决方案中有一些跳跃,我必须弄清楚,但这与我所寻找的非常接近:) – Aodh

相关问题