展示当前位置和在Swift中更新MKMapView的位置

51

我正在学习如何使用新的Swift语言(仅限Swift,不包括Objective-C)。为了做到这一点,我想用一个地图(MKMapView)创建一个简单的视图。我想要找到并更新用户的位置(就像在苹果地图应用程序中一样)。

我尝试了这个,但什么也没发生:

import MapKit
import CoreLocation

class MapView : UIViewController, CLLocationManagerDelegate {

    @IBOutlet weak var map: MKMapView!
    var locationManager: CLLocationManager!

    override func viewDidLoad() {
        super.viewDidLoad()

        if (CLLocationManager.locationServicesEnabled())
        {
            locationManager = CLLocationManager()
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyBest
            locationManager.requestAlwaysAuthorization()
            locationManager.startUpdatingLocation()
        }
    }
}

你能帮助我吗?


只需访问此链接:https://dev59.com/1V8e5IYBdhLWcg3wssPG#49191349 - Mr.Javed Multani
11个回答

81

要获取位置管理器检索到的当前位置通知,您必须重写CLLocationManagerDelegate的一部分CLLocationManager.didUpdateLocations

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    if let location = locations.last{
        let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
        self.map.setRegion(region, animated: true)
    }
}

注意:如果您的目标是 iOS 8 或更高版本,则必须在 Info.plist 中包括 NSLocationAlwaysUsageDescriptionNSLocationWhenInUseUsageDescription 键才能让位置服务正常工作。


感谢您的回答,Zisoft。但是,为了使用该函数,我必须将所有新位置“保存”在某种列表中吗?那么,startUpdatingLocation()是否足以更新位置?注意:呃...对不起,请问我该如何做?:s非常感谢! - PMIW
一旦您调用了startUpdatingLocation,每次检测到位置变化时都会触发didUpdateLocations。您可以对位置进行任何需要的操作,例如将其存储在数组中以在地图视图上绘制路径。 - zisoft
好的,谢谢。 请问我该如何在我的 Info.plist 中包含 NSLocationAlwaysUsageDescription 键? - PMIW
该值应为字符串。当系统请求用户允许使用位置服务时,此文本将显示在屏幕上。在iOS 8中,这是强制性的。 - zisoft
如果您只需要在应用程序运行时跟踪用户位置,我建议使用NSLocationWhenInUseUsageDescription。这样人们更有可能点击“接受”。 - Toddarooski
显示剩余5条评论

39

100%有效,易于操作且经过测试

导入库:

import MapKit
import CoreLocation

设置代表:

CLLocationManagerDelegate,MKMapViewDelegate

取变量:

let locationManager = CLLocationManager()

在viewDidLoad()中编写以下代码:

self.locationManager.requestAlwaysAuthorization()

    // For use in foreground
    self.locationManager.requestWhenInUseAuthorization()

    if CLLocationManager.locationServicesEnabled() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.startUpdatingLocation()
    }

    mapView.delegate = self
    mapView.mapType = .standard
    mapView.isZoomEnabled = true
    mapView.isScrollEnabled = true

    if let coor = mapView.userLocation.location?.coordinate{
        mapView.setCenter(coor, animated: true)
    }

编写位置代理方法:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let locValue:CLLocationCoordinate2D = manager.location!.coordinate

    mapView.mapType = MKMapType.standard

    let span = MKCoordinateSpanMake(0.05, 0.05)
    let region = MKCoordinateRegion(center: locValue, span: span)
    mapView.setRegion(region, animated: true)

    let annotation = MKPointAnnotation()
    annotation.coordinate = locValue
    annotation.title = "Javed Multani"
    annotation.subtitle = "current location"
    mapView.addAnnotation(annotation)

    //centerMap(locValue)
}

不要忘记在 info.plist 中设置权限。

<key>NSLocationWhenInUseUsageDescription</key>
<string>This application requires location services to work</string>

<key>NSLocationAlwaysUsageDescription</key>
<string>This application requires location services to work</string>

看起来像这样:

enter image description here


21

对于Swift 3和XCode 8,我找到了以下答案:

  • 首先,您需要将隐私设置为info.plist。插入字符串 NSLocationWhenInUseUsageDescription 并附上您想要获取用户位置的原因的描述。例如,设置字符串 "用于应用程序中的地图"。

  • 其次,使用此代码示例:

    @IBOutlet weak var mapView: MKMapView!
    
    private var locationManager: CLLocationManager!
    private var currentLocation: CLLocation?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        mapView.delegate = self
    
        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
    
        // Check for Location Services
    
        if CLLocationManager.locationServicesEnabled() {
            locationManager.requestWhenInUseAuthorization()
            locationManager.startUpdatingLocation()
        }
    }
    
    // MARK - CLLocationManagerDelegate
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        defer { currentLocation = locations.last }
    
        if currentLocation == nil {
            // Zoom to user location
            if let userLocation = locations.last {
                let viewRegion = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 2000, 2000)
                mapView.setRegion(viewRegion, animated: false)
            }
        }
    }
    
  • 第三步,在storyboard中为地图视图设置用户位置标志。


7

MyLocation 是一个使用 Swift 编写的 iOS 演示应用程序。

您可以使用此演示应用程序来完成以下操作:

  1. 显示当前位置。

  2. 选择其他位置:在这种情况下停止跟踪位置。

  3. 在触摸时向 MKMapView(iOS) 添加标注。


3
请不要在多个问题上添加相同的答案。请回答最好的一个,并将其余标记为重复。参见 Is it acceptable to add a duplicate answer to several questions? - Bhargav Rao
谢谢,我会这样做。 - Ahmed Lotfy

5

有时在代码中设置 showsUserLocation 不起作用,原因可能很奇怪。

尝试以下组合方法:

在 viewDidLoad() 方法中:

  self.mapView.showsUserLocation = true

在Xcode中前往你的Storyboard,在右侧面板的属性检查器中勾选用户位置复选框,就像附图所示。运行你的应用程序,你应该能够看到用户位置

enter image description here


谢谢,复选框“用户位置”正是我正在寻找的——当前位置的蓝色点。 - Alex Metelkin

5

Swift 5.1

获取当前位置并在MKMapView上设置

导入库:

import MapKit
import CoreLocation

设置代理:

CLLocationManagerDelegate , MKMapViewDelegate

声明变量:

let locationManager = CLLocationManager()

在viewDidLoad()方法中编写以下代码:

self.locationManager.requestAlwaysAuthorization()
self.locationManager.requestWhenInUseAuthorization()

if CLLocationManager.locationServicesEnabled() {
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.startUpdatingLocation()
}
mapView.delegate = self
mapView.mapType = .standard
mapView.isZoomEnabled = true
mapView.isScrollEnabled = true

if let coor = mapView.userLocation.location?.coordinate{
    mapView.setCenter(coor, animated: true)
}

编写位置委托方法:
func locationManager(_ manager: CLLocationManager, didUpdateLocations 
    locations: [CLLocation]) {
    let locValue:CLLocationCoordinate2D = manager.location!.coordinate

    mapView.mapType = MKMapType.standard

    let span = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
    let region = MKCoordinateRegion(center: locValue, span: span)
    mapView.setRegion(region, animated: true)

    let annotation = MKPointAnnotation()
    annotation.coordinate = locValue
    annotation.title = "You are Here"
    mapView.addAnnotation(annotation)
}

在 info.plist 中设置权限 *

<key>NSLocationWhenInUseUsageDescription</key>
<string>This application requires location services to work</string>

<key>NSLocationAlwaysUsageDescription</key>
<string>This application requires location services to work</string>

3

对于Swift 2,您应该将其更改为以下内容:

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let location = locations.last

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

    self.map.setRegion(region, animated: true)
}

2

1

你需要重写CLLocationManager.didUpdateLocations

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

    let userLocation:CLLocation = locations[0] as CLLocation
    locationManager.stopUpdatingLocation()

    let location = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)

    let span = MKCoordinateSpanMake(0.5, 0.5)

    let region = MKCoordinateRegion (center:  location,span: span)

    mapView.setRegion(region, animated: true)
}

您还需要将NSLocationWhenInUseUsageDescriptionNSLocationAlwaysUsageDescription添加到您的plist设置中,将Result作为值。


1
mapView.showsUserLocation = true

创建UIButton并添加此操作。
@IBAction func showCurrentLocation(_ sender: Any) {
        let coordinate = mapView.userLocation.coordinate
        let center = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
        self.mapView.setRegion(region, animated: true)
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接