MKMapView 缩放到 viewDidLoad 上的用户位置?

发布于 2024-11-08 16:52:37 字数 538 浏览 1 评论 0原文

我试图在视图加载后将地图缩放到用户的当前位置,但收到错误“** * 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“无效区域””。请问有人可以帮忙吗?

干杯!

- (void)viewDidLoad
{
    [super viewDidLoad];

    MKCoordinateRegion mapRegion;   
    mapRegion.center.latitude = map.userLocation.coordinate.latitude;
    mapRegion.center.longitude = map.userLocation.coordinate.longitude;
    mapRegion.span.latitudeDelta = 0.2;
    mapRegion.span.longitudeDelta = 0.2;
    [map setRegion:mapRegion animated: YES];   
}

I'm trying to zoom a map into the user's current location once the view loads, but I'm getting the error "** * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid Region '" when the view loads. Please can someone help?

Cheers!

- (void)viewDidLoad
{
    [super viewDidLoad];

    MKCoordinateRegion mapRegion;   
    mapRegion.center.latitude = map.userLocation.coordinate.latitude;
    mapRegion.center.longitude = map.userLocation.coordinate.longitude;
    mapRegion.span.latitudeDelta = 0.2;
    mapRegion.span.longitudeDelta = 0.2;
    [map setRegion:mapRegion animated: YES];   
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

我的黑色迷你裙 2024-11-15 16:52:37

您是否设置了showsUserLocation = YES?如果设置为 NOMKMapView 将不会更新位置。所以请确保这一点。

MKMapView 对象很可能还没有用户位置。为了做到正确,您应该采用 MKMapViewDelegate 协议并实现 mapView:didUpdateUserLocation:

map.delegate = self;

...
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation 
{
    MKCoordinateRegion mapRegion;   
    mapRegion.center = mapView.userLocation.coordinate;
    mapRegion.span.latitudeDelta = 0.2;
    mapRegion.span.longitudeDelta = 0.2;

    [mapView setRegion:mapRegion animated: YES];
}

did you set showsUserLocation = YES? MKMapView won't update the location if it is set to NO. So make sure of that.

It is very likely that the MKMapView object doesn't have the user location yet. To do right, you should adopt MKMapViewDelegate protocol and implement mapView:didUpdateUserLocation:

map.delegate = self;

...
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation 
{
    MKCoordinateRegion mapRegion;   
    mapRegion.center = mapView.userLocation.coordinate;
    mapRegion.span.latitudeDelta = 0.2;
    mapRegion.span.longitudeDelta = 0.2;

    [mapView setRegion:mapRegion animated: YES];
}
纸短情长 2024-11-15 16:52:37

与迪帕克的答案一样,除了你可以更优雅地设置跨度:

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
    MKCoordinateRegion mapRegion;   
    mapRegion.center = map.userLocation.coordinate;
    mapRegion.span = MKCoordinateSpanMake(0.2, 0.2);
    [map setRegion:mapRegion animated: YES];
}

As with Deepak's answer, except you could set the span more elegantly:

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation {
    MKCoordinateRegion mapRegion;   
    mapRegion.center = map.userLocation.coordinate;
    mapRegion.span = MKCoordinateSpanMake(0.2, 0.2);
    [map setRegion:mapRegion animated: YES];
}
只是在用心讲痛 2024-11-15 16:52:37

如果用户可能想要滚动地图,您不想在 userDidUpdateLocation 中更新这些内容。如果您将该代码放入上述方法中,用户将无法滚动地图,因为该函数将被调用并将地图集中回当前位置。

You don't want to update this stuff inside userDidUpdateLocation if there is the possbility that the user will want to scroll the map. If you put that code in the mentioned method, the user will not be able to scroll the map because the function will be called and center the map back to the current location.

┊风居住的梦幻卍 2024-11-15 16:52:37

到目前为止,最简单的方法是在 didUpdateUserLocation 中使用 mapView.showAnnotations:

func mapView(mapView: MKMapView!, didUpdateUserLocation userLocation: MKUserLocation!) {
    mapView.showAnnotations([userLocation], animated: true)
}

仅此而已!

MKUserLocation 符合 MKAnnotation 协议。将 userLocation 作为数组传递,showAnnotations 方法将使 mapView 放大一个区域以及跨越 MKAnnotations 数组的填充,在本例中它只是 userLocation。对我有用。

如果您只想放大一次,请使用initialUserLocation 属性来检查是否已设置initial 属性。我根本不喜欢使用dispatch_once来做这类事情

By far the easiest way is to use mapView.showAnnotations in didUpdateUserLocation:

func mapView(mapView: MKMapView!, didUpdateUserLocation userLocation: MKUserLocation!) {
    mapView.showAnnotations([userLocation], animated: true)
}

That's all!

MKUserLocation conforms to the MKAnnotation protocol. Pass the userLocation as an array, the showAnnotations method will let the mapView zoom in on a region plus padding spanning the array of MKAnnotations,in this case it's just the userLocation. Works for me.

If you only want to zoom in once, use a initialUserLocation property to check whether the initial property was already set. I don't like using dispatch_once at all for that sort of thing

淡莣 2024-11-15 16:52:37

这是 @Deepak 在 Swift 3 for iOS 10 中的答案:

extension ViewController: MKMapViewDelegate
{
    func mapView( _ mapView: MKMapView, didUpdate userLocation: MKUserLocation )
    {
        let regionRadius = 400 // in meters
        let coordinateRegion = MKCoordinateRegionMakeWithDistance( userLocation.coordinate, regionRadius, regionRadius )
        self.mapView.setRegion( coordinateRegion, animated: true)
    }
}

Here is @Deepak's answer in Swift 3 for iOS 10:

extension ViewController: MKMapViewDelegate
{
    func mapView( _ mapView: MKMapView, didUpdate userLocation: MKUserLocation )
    {
        let regionRadius = 400 // in meters
        let coordinateRegion = MKCoordinateRegionMakeWithDistance( userLocation.coordinate, regionRadius, regionRadius )
        self.mapView.setRegion( coordinateRegion, animated: true)
    }
}
你列表最软的妹 2024-11-15 16:52:37

当您使用didUpdateUserLocation方法时出现的问题,您将无法滚动或缩放到另一个位置。它将继续指向您的位置。
最好的方法(我尝试过)是您需要使用位置管理器。

viewDidLoad 中添加以下内容:

self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = kCLLocationAccuracyKilometer;;
// showing user location with the blue dot
[self.mapView setShowsUserLocation:YES];

self.mapView.delegate = self;

// getting user coordinates
CLLocation *location = [_locationManager location];
CLLocationCoordinate2D  coordinate = [location coordinate];


// showing them in the mapView
_mapView.region = MKCoordinateRegionMakeWithDistance(coordinate, 250, 250);

[self.locationManager startUpdatingLocation];

这样您就可以按照所需的缩放比例显示您的位置。
我希望这会有所帮助。

The problem that occurs when you use the didUpdateUserLocation method, you will not be able to scroll nor zoom to another location. It will keep pointing to your location.
The best way (that I've tried) is that you need to use the location manager.

In the viewDidLoad add the following :

self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = kCLLocationAccuracyKilometer;;
// showing user location with the blue dot
[self.mapView setShowsUserLocation:YES];

self.mapView.delegate = self;

// getting user coordinates
CLLocation *location = [_locationManager location];
CLLocationCoordinate2D  coordinate = [location coordinate];


// showing them in the mapView
_mapView.region = MKCoordinateRegionMakeWithDistance(coordinate, 250, 250);

[self.locationManager startUpdatingLocation];

this way you could display your location with the zoom that you want.
I hope this will help.

哭了丶谁疼 2024-11-15 16:52:37

查看MKMapView的setUserTrackingMode方法。跟踪用户在 MKMapView 上的位置的最简单方法可能是

[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];

这样,您也不需要成为 MKMapViewDelegate。可能的模式有:

MKUserTrackingModeNone = 0, // the user's location is not followed
MKUserTrackingModeFollow, // the map follows the user's location
MKUserTrackingModeFollowWithHeading, // the map follows the user's location and heading

Check out the method setUserTrackingMode of MKMapView. Probably the easiest way of tracking the user's location on a MKMapView is

[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];

That way you also don't need to be a MKMapViewDelegate. The possible modes are:

MKUserTrackingModeNone = 0, // the user's location is not followed
MKUserTrackingModeFollow, // the map follows the user's location
MKUserTrackingModeFollowWithHeading, // the map follows the user's location and heading
掩耳倾听 2024-11-15 16:52:37

......

MKCoordinateRegion region =mapView.region;

region.center.latitude = currentLocation.latitude ;
region.center.longitude = currentLocation.longitude;
region.span.longitudeDelta /= 1000.0;
region.span.latitudeDelta /= 1000.0;

[mapView setRegion:region animated:YES];
[mapView regionThatFits:region];

......

MKCoordinateRegion region =mapView.region;

region.center.latitude = currentLocation.latitude ;
region.center.longitude = currentLocation.longitude;
region.span.longitudeDelta /= 1000.0;
region.span.latitudeDelta /= 1000.0;

[mapView setRegion:region animated:YES];
[mapView regionThatFits:region];
简美 2024-11-15 16:52:37

斯威夫特3版本
使用此方法可以放大任意坐标。

extension MKMapView{
    func zoomIn(coordinate: CLLocationCoordinate2D, withLevel level:CLLocationDistance = 10000){
        let camera =
            MKMapCamera(lookingAtCenter: coordinate, fromEyeCoordinate: coordinate, eyeAltitude: level)
        self.setCamera(camera, animated: true)
    }
}

Swift 3 version
Use this method to zoom into any coordinate.

extension MKMapView{
    func zoomIn(coordinate: CLLocationCoordinate2D, withLevel level:CLLocationDistance = 10000){
        let camera =
            MKMapCamera(lookingAtCenter: coordinate, fromEyeCoordinate: coordinate, eyeAltitude: level)
        self.setCamera(camera, animated: true)
    }
}
罗罗贝儿 2024-11-15 16:52:37

按照 Deepak 的建议,实现 mapView:didUpdate: 委托方法。 Swift 5 的语法:

func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
  guard let newLocation = userLocation.location else { return }
  let region = MKCoordinateRegion(center: newLocation.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2))
  mapView.setRegion(region, animated: true)
}

As suggested by Deepak, implement the mapView:didUpdate: delegate method. Syntax for Swift 5:

func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
  guard let newLocation = userLocation.location else { return }
  let region = MKCoordinateRegion(center: newLocation.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2))
  mapView.setRegion(region, animated: true)
}
蒲公英的约定 2024-11-15 16:52:37

检查map.userLocation.cooperative的值,其他就OK了。

Check the value of map.userLocation.coordinate, the rest is OK.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文