2015-05-17 39 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

相關問題