我一直试图解决这个问题几个小时,我似乎无法找到解决方案。我正在尝试在地图视图上创建一个按钮,在按下时放大用户位置。以下是与按钮有关的函数的代码:
func zoomInOnLocation() {
let userLocation = MKUserLocation()
let locationManager = CLLocationManager()
locationManager.requestWhenInUseAuthorization()
let currentLocation: CLLocation? = userLocation.location
let latitude = currentLocation?.coordinate.latitude
let longitude = currentLocation?.coordinate.longitude
let span: MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
let location: CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude!, longitude!)
let region: MKCoordinateRegion = MKCoordinateRegionMake(location, span)
mapView.setRegion(region, animated: true)
}
当我单击模拟器中的按钮时,我收到一条错误,指出致命错误:
在解包可选值时意外发现nil
第五行mapDelegate.mapView!...
以红色突出显示。另外,我在 Info.plist 中添加了正确的标记。非常感谢任何帮助。
答案 0 :(得分:0)
所以你可能不想像现在这样与mapView委托进行交互。
如何将委托添加到包含mapView的视图的类中,如下所示:
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
并在viewDidLoad()中设置委托:
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
mapView.delegate = self
}
当然,您希望设置locationManager
和userLocation
:
let locationManager = CLLocationManager()
var userLocation = CLLocation()
请注意,userLocation
是一个变量,因为很可能您希望在某个时候更新它。
您可能希望使用locationManager
:
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
您可以根据应用的需求进行更改,并考虑所需的准确度会对电池寿命产生影响。另外,您是否在userLocation上启动和停止更新?因为我没有在你的代码中看到它,除非你是在这个函数之外做的。
一个好的做法是尽量减少特定功能对一项任务的影响。您可能希望在其他地方进行所有这些设置,然后只放大功能内部。 :)
最后,为了放大,您可以更改MKCoordinateSpanMake
的值,并记住较大的跨度值会放大地图,因此可以查看较小的区域。
let userLocationCoordinates = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
let span = MKCoordinateSpanMake(0.3, 0.3)
let region = MKCoordinateRegion(center: userLocationCoordinates, span: span)
mapView.setRegion(region, animated: true)
希望能帮到你一点,让我知道它是怎么回事!
答案 1 :(得分:0)
检查一下:
if #available(iOS 9.0, *) {
locationManager.requestLocation()
} else {
// Fallback
}
let latitude:CLLocationDegrees = //insert latitutde
let longitude:CLLocationDegrees = //insert longitude
let latDelta:CLLocationDegrees = 0.05
let lonDelta:CLLocationDegrees = 0.05
let span = MKCoordinateSpanMake(latDelta, lonDelta)
let location = CLLocationCoordinate2DMake(latitude, longitude)
let region = MKCoordinateRegionMake(location, span)
mapView.setRegion(region, animated: false)
更多信息:Making the map zoom to user location and annotation (swift 2)
答案 2 :(得分:0)
也许这会有所帮助。我创建了这个函数来放大由位置数组定义的区域,范围从当前用户位置到构成折线的一组点周围的区域。该函数根据我的系统常量中设置的regionPaddingFactor常量在点周围提供缓冲区。
func setRectView(_ locations: [MKAnnotation], mapView: MKMapView) // Size the area for display and reset the view
{
var maxLat = -90.0
var minLat = 90.0
var maxLon = -180.0
var minLon = 180.0
if locations.count >= 1 {
for waypoint in locations {
maxLat = max(maxLat, waypoint.coordinate.latitude)
minLat = min(minLat, waypoint.coordinate.latitude)
maxLon = max(maxLon, waypoint.coordinate.longitude)
minLon = min(minLon, waypoint.coordinate.longitude)
}
let loc = CLLocationCoordinate2DMake((maxLat-fabs(maxLat - minLat)/2), (maxLon-fabs(maxLon - minLon)/2))
let span = MKCoordinateSpanMake(0.001 + (1.0 + Setting.shared.regionPaddingFactor) * fabs(maxLat - minLat), 0.001 + (1.0 + Setting.shared.regionPaddingFactor) * fabs(maxLon-minLon))
// The 0.001 values above ensure that you do not get a 0.0 valued span if all of the points have the same latitude, longitude, or both, or if there is only one point
// The regionPaddingFactor is a constant to allow some space around the points passed in
let reg = MKCoordinateRegionMake(loc, span)
mapView.setRegion(reg, animated: true)
mapView.animatedZoom(zoomRegion: reg, duration: 0.8)
}
}
在通话代码中,我提供了3个设置,当用户按下按钮时旋转:
需要最后一个选项,因为每当收到新的当前位置时我都会调用该函数来根据当前位置重新定位视图,如果用户正在尝试重新定位地图,则会重复重新定位视图。
如果您不希望发送不同位置数组的灵活性,可以使用mapView.annotations或仅将当前位置作为数组进行定位。