iOS MKMapView 以用户位置为中心,然后在 Swift 3.0 中允许无限滚动
iOS MKMapView Center on User Location and then allow unlimited Scrolling in Swift 3.0
我认为 Swift 3.0 中还没有人问过这个问题 - 三个目标:
在 viewDidLoad
地图中心到用户位置可以设置的特定缩放级别(例如 let span: MKCoordinateSpan = MKCoordinateSpanMake(40.0, 40.0)
)
一旦地图加载并以用户位置为中心,用户就可以将地图移动并滚动到任何其他位置,而地图不会自动回到原始用户位置
只允许用户放大到一定程度,但允许用户完全缩小以查看整个全球地图(对缩小级别没有限制)
到目前为止,这是我的代码:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[0]
let span: MKCoordinateSpan = MKCoordinateSpanMake(40.0, 40.0)
let userLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
let region: MKCoordinateRegion = MKCoordinateRegionMake(userLocation, span)
mapView.setRegion(region, animated: true)
self.mapView.showsUserLocation = true
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
}
1。应该可以使用您现在拥有的代码。
2。添加检查后续位置更新
在didUpdateLocations
方法中,添加一个Bool
来检查区域是否已经以用户为中心。
var regionHasBeenCentered = false
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[0]
if !regionHasBeenCentered {
let span: MKCoordinateSpan = MKCoordinateSpanMake(40.0, 40.0)
let userLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
let region: MKCoordinateRegion = MKCoordinateRegionMake(userLocation, span)
mapView.setRegion(region, animated: true)
regionHasBeenCentered = true
}
self.mapView.showsUserLocation = true
}
现在地图在第一次更新后将不再以用户为中心,直到您将 regionHasBeenCentered
改回 false
。这将允许用户自由滚动和缩放。
3。实施 MKMapViewDelegate
检测地图区域变化的方法
在您的视图控制器上实施 MKMapViewDelegate
,以便您可以检查区域更改。
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
...并将视图控制器设置为 delegate
:
override func viewDidLoad() {
// other things…
mapView.delegate = self
}
然后实现以下方法,该方法将在区域更改之前立即调用。这里可以查看span的尺寸是否太小,设置为合适的最小值。
func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
if mapView.region.span.latitudeDelta <= 40 && mapView.region.span.longitudeDelta <= 40 {
let minimumSpan = MKCoordinateSpan(latitudeDelta: 40, longitudeDelta: 40)
let minimumRegion= MKCoordinateRegion(center: mapView.centerCoordinate, span: minimumSpan)
mapView.setRegion(minimumRegion, animated: false)
}
}
重要说明: 从 MKCoordinateSpan
documentation 开始,longitudeDelta
将随着您从赤道移动 toward/away 而改变。
longitudeDelta
The amount of east-to-west distance (measured in degrees) to display for the map region. The number of kilometers spanned by a longitude range varies based on the current latitude. For example, one degree of longitude spans a distance of approximately 111 kilometers (69 miles) at the equator but shrinks to 0 kilometers at the poles.
此外,MKCoordinateSpan
的尺寸以度为单位,40 度有点大,因此您可能需要更改这些值,否则用户根本无法放大太多。
我认为 Swift 3.0 中还没有人问过这个问题 - 三个目标:
在
viewDidLoad
地图中心到用户位置可以设置的特定缩放级别(例如let span: MKCoordinateSpan = MKCoordinateSpanMake(40.0, 40.0)
)一旦地图加载并以用户位置为中心,用户就可以将地图移动并滚动到任何其他位置,而地图不会自动回到原始用户位置
只允许用户放大到一定程度,但允许用户完全缩小以查看整个全球地图(对缩小级别没有限制)
到目前为止,这是我的代码:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[0]
let span: MKCoordinateSpan = MKCoordinateSpanMake(40.0, 40.0)
let userLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
let region: MKCoordinateRegion = MKCoordinateRegionMake(userLocation, span)
mapView.setRegion(region, animated: true)
self.mapView.showsUserLocation = true
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
}
1。应该可以使用您现在拥有的代码。
2。添加检查后续位置更新
在didUpdateLocations
方法中,添加一个Bool
来检查区域是否已经以用户为中心。
var regionHasBeenCentered = false
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[0]
if !regionHasBeenCentered {
let span: MKCoordinateSpan = MKCoordinateSpanMake(40.0, 40.0)
let userLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
let region: MKCoordinateRegion = MKCoordinateRegionMake(userLocation, span)
mapView.setRegion(region, animated: true)
regionHasBeenCentered = true
}
self.mapView.showsUserLocation = true
}
现在地图在第一次更新后将不再以用户为中心,直到您将 regionHasBeenCentered
改回 false
。这将允许用户自由滚动和缩放。
3。实施 MKMapViewDelegate
检测地图区域变化的方法
在您的视图控制器上实施 MKMapViewDelegate
,以便您可以检查区域更改。
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
...并将视图控制器设置为 delegate
:
override func viewDidLoad() {
// other things…
mapView.delegate = self
}
然后实现以下方法,该方法将在区域更改之前立即调用。这里可以查看span的尺寸是否太小,设置为合适的最小值。
func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) {
if mapView.region.span.latitudeDelta <= 40 && mapView.region.span.longitudeDelta <= 40 {
let minimumSpan = MKCoordinateSpan(latitudeDelta: 40, longitudeDelta: 40)
let minimumRegion= MKCoordinateRegion(center: mapView.centerCoordinate, span: minimumSpan)
mapView.setRegion(minimumRegion, animated: false)
}
}
重要说明: 从 MKCoordinateSpan
documentation 开始,longitudeDelta
将随着您从赤道移动 toward/away 而改变。
longitudeDelta
The amount of east-to-west distance (measured in degrees) to display for the map region. The number of kilometers spanned by a longitude range varies based on the current latitude. For example, one degree of longitude spans a distance of approximately 111 kilometers (69 miles) at the equator but shrinks to 0 kilometers at the poles.
此外,MKCoordinateSpan
的尺寸以度为单位,40 度有点大,因此您可能需要更改这些值,否则用户根本无法放大太多。