【问题标题】:MKMapView zoom to users location on viewDidLoad?MKMapView 缩放到 viewDidLoad 上的用户位置?
【发布时间】:2011-08-29 04:04:15
【问题描述】:

我正在尝试在视图加载后将地图缩放到用户的当前位置,但我收到错误“** * Terminating app due to unaught exception 'NSInvalidArgumentException', reason: 'Invalid Region '" 当视图加载时。请问有人可以帮忙吗?

干杯!

- (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];   
}

【问题讨论】:

  • 我认为已经有足够多的人试图表明,如果您的问题已经有标签,则无需在标题中添加[COCOA-TOUCH]。

标签: iphone objective-c cocoa-touch


【解决方案1】:

你设置showsUserLocation = YES了吗?如果设置为NO,MKMapView 将不会更新位置。所以请确保这一点。

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];
}

【讨论】:

  • 行“map.delegate = self;”有一个错误说'未知类型的名称'地图''。如果我将此注释掉,用户的位置会显示(它总是有),但视图不会放大
  • 嗯...我的意思是适当地设置MKMapView 的代表。 map 不是 MKMapView 的实例吗?您在哪里尝试这样做?
  • 耶!将委托线放到 viewDidLoad 中,它可以工作 :) 谢谢!
【解决方案2】:

与 Deepak 的回答一样,除了您可以更优雅地设置跨度:

- (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];
}

【讨论】:

  • 将方法的内容包装在static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{<code to center map on user here>}); 中会不会更优雅?这样做的目的是确保地图只以用户的坐标为中心(在 viewDidLoad 上),并且如果用户在使用应用程序时移动,则不会一次又一次地重置。
  • 不是这种情况。您提供的代码只会在每次应用程序启动时运行一次。
【解决方案3】:

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

【讨论】:

  • 您可以通过使用以下代码包装您的代码来防止这种情况发生:static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{<code to center map on user here>});
  • 这是超级有用的仅供参考@BFar。
【解决方案4】:

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

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

就是这样!

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

如果您只想放大一次,请使用 initialUserLocation 属性检查初始属性是否已设置。我根本不喜欢在这种事情上使用 dispatch_once

【讨论】:

  • 我认为这是最简单的方法之一。
【解决方案5】:

这是@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)
    }
}

【讨论】:

    【解决方案6】:

    当您使用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];
    

    通过这种方式,您可以使用所需的缩放比例显示您的位置。 我希望这会有所帮助。

    【讨论】:

      【解决方案7】:

      查看 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
      

      【讨论】:

        【解决方案8】:

        ……

        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];
        

        【讨论】:

          【解决方案9】:

          Swift 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)
              }
          }
          

          【讨论】:

            【解决方案10】:

            按照 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)
            }
            

            【讨论】:

              【解决方案11】:

              检查map.userLocation.coordinate的值,其余都OK。

              【讨论】:

                猜你喜欢
                • 2011-08-11
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-11-23
                • 2011-01-29
                • 2014-04-30
                相关资源
                最近更新 更多