代码之家  ›  专栏  ›  技术社区  ›  jantimon

如何用给定的用户位置初始化mkmapview?

  •  19
  • jantimon  · 技术社区  · 16 年前

    我的应用知道当前的用户位置(corelocation.framework)。 一旦用户打开一个新的地图视图,他的iPhone就开始再次搜索当前位置。 是否可以跳过该操作或更改mkmapview的第一个用户位置?

    编辑:

    是否可以覆盖mkmapview并使用其他locationmanager?

    4 回复  |  直到 15 年前
        1
  •  42
  •   Ramin    16 年前

    是的,可以有一个单独的位置管理器对象,并将其值赋给MapView(顺便说一句,我使用下面的“=”作为列表前缀,以防止SO代码格式化程序借用)。

    =在你的 UIViewController 保持两个独立的属性:一对一 MKMapView 一对一 CLLocationManager .

    =使用创建XIB文件 MKMMAVIEW 还有你想要的任何其他的窗饰。将插座连接到控制器属性。确保 MKMMAVIEW 不遵循用户位置。

    =让uiviewController实现 CLLocationManagerDelegate 协议——尤其是 locationManager:didUpdateToLocation:fromLocation: 每当有新的位置值可用时将调用的方法。我们将设置控制器作为位置管理器的代理。

    =在视图控制器中 loadView 方法,用 Mkmap视图 在里面。要向用户提供反馈,您可能需要 UIActivityIndicatorView 旋转并设置为 startAnimating . 然后从以下内容开始:

    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
    self.locationManager.distanceFilter = 10; // or whatever
    [self.locationManager startUpdatingLocation];
    

    =在 位置管理器:DidUpdateToLocation:FromLocation: 检查事件是否在最近n秒后更新。然后告诉位置管理器停止更新,微调器停止动画,并获取lat/long数据并将其与视图范围和区域一起分配给地图视图,以便将其缩放和居中到正确的位置。

    =现在有一个棘手的部分:蓝色大理石“throbber”是mapview跟踪用户位置的一个特性。你必须暂时“假动作”,直到真正的动作开始(或者用一个单独的标记来标记当前的位置并自己保持它的位置)。我个人会选择用户熟悉的蓝色大理石。

    =要使其在启动时显示正确,您需要创建一个自定义mkannotationView,只在位置管理器返回的位置添加蓝色大理石图形。这意味着要用显示位置的地图视图的快照,然后将蓝色的大理石图片跳出来,并将其用作自定义注释视图的图像。

    =如果希望它主动跟踪地图,可以启用地图视图的用户位置跟踪,当它获取实际数据时,可以隐藏以前设置的标记,并让地图视图进行更新。另一个选项是允许现有的位置管理器每秒左右继续接收更新,并自己更新蓝色大理石注释的位置。

    =要让mapview自己的用户位置执行更新,请添加到viewdidload:

    [self.map.userLocation addObserver:self 
    forKeyPath:@"location" 
    options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld) 
    context:NULL];
    self.map.showsUserLocation = YES; // starts updating user location
    

    =实现 observeValueForKeyPath . 当 location 映射视图的属性 userlocation 有价值:

    -(void)observeValueForKeyPath:(NSString *)keyPath 
          ofObject:(id)object 
            change:(NSDictionary *)change 
           context:(void *)context 
    {
         if ([self.map isUserLocationVisible]) {
             [self.locationManager stopUpdatingLocation];
             self.ownBlueMarble.hidden = YES;
         }
         // The current location is in self.map.userLocation.coordinate
    }
    

    =为了避免显示当前位置时的预热延迟,请保留对包含地图和位置管理器的ViewController的引用,这样它就不会消失(这有点占用内存,但如果释放它,则必须再次等待,直到MapView加载瓷砖并准备就绪)。

    =在 viewWillLoad 您可以将最后一个已知位置填充到自定义BlueMarble注释中并显示它。打开/关闭用户位置跟踪,当您收到通知时,相同的隐藏注释显示真正的大理石技巧将起作用。地图视图自己的位置管理器启动,当它有数据时,可以使注释标记消失。

    =您可能希望实现视图控制器的 viewWillDisappear 方法和手动关闭 userLocation 跟踪地图视图,以便下次显示该视图时默认关闭。你还想知道最后一个 用户定位 把它留到下一个开始。这样,您就可以在 viewWillAppear 方法,并且在准备好之前不必担心用户位置干扰。

    祝你好运。

        2
  •  27
  •   zakovyrya    16 年前

    在控制器中:

    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
        CLLocationCoordinate2D coord = {latitude: 37.423617, longitude: -122.220154};
        MKCoordinateSpan span = {latitudeDelta: 1, longitudeDelta: 1};
        MKCoordinateRegion region = {coord, span};
        [mapView setRegion:region];
    }
    

    当地图出现时,它将集中在帕洛阿尔托附近。

        3
  •  0
  •   Nick Bedford    16 年前

    尝试设置 showUserLocation 初始化时属性设置为false,然后还原 region 以前的地图视图(很明显,在销毁以前的地图之前必须存储此视图)。

    这就是你想要的吗?

        4
  •  0
  •   slf    16 年前

    您不需要使用另一个位置管理器,您可以向地图添加您想要的任何点,并通过您想要的任何其他逻辑更新它们。

    假设你有一个与遥控车的插座连接,那辆车将包含有效载荷中地理位置信息的插座数据发送回来。您可以解析出来,并实时更新地图上缩略图的位置。不需要“userlocation”属性,但如果需要,可以显示它。

    用户的位置是只读的,您是否可以使用它。这并不意味着你需要另一个位置经理来做你可能需要做的任何事情。听起来你的应用程序不需要这个功能,但我可能误解了你的问题。