【问题标题】:Swift MapView Stuck Around User's Current LocationSwift MapView 停留在用户当前位置
【发布时间】:2016-12-17 05:02:19
【问题描述】:

目前,我的代码在用户的当前位置放置了一个图钉。当我尝试移动地图时出现了一个小问题,因为视图将向后移动并以当前位置图钉为中心。我希望用户能够导航地图并四处移动,如果用户切换视图控制器(转到另一个选项卡)并返回,地图将以用户位置图钉为中心。我一直在尝试修改此代码以执行此操作,但我没有任何运气从哪里开始。

import UIKit
import MapKit
import CoreLocation
let newPin = MKPointAnnotation()

class MapVC: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {



@IBOutlet weak var map: MKMapView!

 let locationManager =  CLLocationManager()

override func viewDidLoad() {
    super.viewDidLoad()

    // User's location

    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    if #available(iOS 8.0, *) {
    locationManager.requestAlwaysAuthorization()
    } else {
    // Fallback on earlier versions
    }
    locationManager.startUpdatingLocation()


    // add gesture recognizer
    let longPress = UILongPressGestureRecognizer(target: self, action: #selector(MapVC.mapLongPress(_:))) // colon needs to pass through info
    longPress.minimumPressDuration = 1.5 // in seconds
    //add gesture recognition
    map.addGestureRecognizer(longPress)
}

// func called when gesture recognizer detects a long press

func mapLongPress(_ recognizer: UIGestureRecognizer) {

    print("A long press has been detected.")

    let touchedAt = recognizer.location(in: self.map) // adds the location on the view it was pressed
    let touchedAtCoordinate : CLLocationCoordinate2D = map.convert(touchedAt, toCoordinateFrom: self.map) // will get coordinates

    let newPin = MKPointAnnotation()
    newPin.coordinate = touchedAtCoordinate
    map.addAnnotation(newPin)


}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {


    map.removeAnnotation(newPin)

    let location = locations.last! as CLLocation

    let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
    let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))

    //set region on the map
    map.setRegion(region, animated: true)

    newPin.coordinate = location.coordinate
    map.addAnnotation(newPin)





}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}

【问题讨论】:

    标签: swift mkmapview


    【解决方案1】:

    你的代码有几个问题:

    您在全局范围内声明变量newPin,在mapLongPress(...) 中声明一个新变量let newPin = ...,因此不使用全局newPin

    didUpdateLocations() 中,您首先删除(全局)newPin 注释(为什么??)并在函数末尾再次设置它。因为全局 newPin 从未设置为任何有用的值,所以永远不会得到想要的结果。

    此外,在didUpdateLocations() 中,您将地图的区域和中心点设置为当前位置。这在每次位置更新时都会完成,在尝试平移地图时会产生奇怪的结果。

    要在视图出现时设置中心和区域,请尝试以下操作:

    class MapVC: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
        @IBOutlet weak var map: MKMapView!
        let locationManager =  CLLocationManager()
    
        // class variable for the current location
        var lastLocation: CLLocation?
    
        override func viewDidLoad() {
            // ...
        }
    
        override func viewDidAppear(_ animated: Bool) {
            if self.lastLocation != nil {
                // set center and region to current location
                let center = CLLocationCoordinate2D(latitude: self.lastLocation.coordinate.latitude, longitude: self.lastLocation.coordinate.longitude)
                let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
    
                //set region on the map
                map.setRegion(region, animated: true)
            }
        }
    
        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            self.lastLocation = locations.last
        }
    
    }
    

    【讨论】:

    • 啊,我看到 mapLongPress 中的局部变量 newPin 是多余的。至于 didUpdateLocations(),我不知道 if 会不断更新。如何在打开视图控制器时更新它,以便用户能够平移地图?
    • 您可以将上次检索到的位置保存在类变量中,并在ViewDidAppear中设置区域和中心点
    • 这听起来可能很幼稚,但请多多包涵。如何设置类变量,以便可以在函数 didUpdateLocations() 之外保存位置(或区域/中心点)?我只知道如何使用全局变量来做到这一点。
    • 好的,我想我对正在发生的事情有了更好的理解。首先,我了解 didUpdateLocations() 的作用(我不希望它每次都更新)并且 viewDidAppear 是有道理的(因为我只对一开始就显示它感兴趣)。但是,您能解释一下代码“self.lastLocation = locations.last!as CLLocation”的作用吗?其次,我是否可以通过在变量前面加上“self”来访问函数外部的变量?
    • didUpdateLocations 在检测到新位置时被调用。使用self.lastLocation = locations.last 将变量lastLocation 设置为当前位置。这个变量可以在你的类MapVC的每个函数中访问。但这远远超出了问题范围,这是快速的基础知识。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2015-10-01
    相关资源
    最近更新 更多