19

我的应用知道当前的用户位置(CoreLocation.framework)。一旦用户打开一个新的 MapView,他的 iPhone 就会再次开始搜索当前位置。是否可以跳过或更改 mkMapView 的第一个用户位置?

编辑:

是否可以覆盖 MKMapView 并使用其他 LocationManager?

4

4 回答 4

42

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

=在您UIViewController维护两个单独的属性:一个到 aMKMapView和一个到 a CLLocationManager

MKMapView= 使用您想要的和任何其他窗口镶边创建一个 XIB 文件。将插座连接到控制器属性。确保MKMapView不跟随用户位置。

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

= 在 vi​​ewController 的loadView方法中,加载带有 的 NIB MKMapView。为了给用户反馈,您可能需要放置一个UIActivityIndicatorView微调器并将其设置为startAnimating. 然后你开始:

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

=locationManager:didUpdateToLocation:fromLocation:检查事件是否在最后 N 秒后更新。然后告诉位置管理器停止更新,让微调器停止动画,并获取纬度/经度数据并将其与视图跨度和区域一起分配给地图视图,以便它缩放并居中到正确的位置。

= 现在是棘手的部分:蓝色大理石“颤抖者”是地图视图跟踪用户位置的一个特征。您将不得不暂时“伪造”它,直到真正的开始(或仅对当前位置使用单独的标记并自己保持其位置)。我个人会选择用户熟悉的蓝色大理石。

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

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

= 让 mapview 自己的 userLocation 更新添加到 viewDidLoad:

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

= 实施observeValueForKeyPathlocation当mapview 的属性有值时调用它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 注释中并显示它。打开/关闭 userLocation 跟踪,当您收到通知时,相同的 hide-the-annotation-show-the-real-marble 技巧将起作用。地图视图自己的位置管理器启动,当它有数据时,你可以让你的注释标记消失。

= 您可能希望实现 viewController 的viewWillDisappear方法并手动关闭userLocationmapview 上的跟踪,以便在下次打开视图时默认关闭。您还需要获取最后一个已知userLocation信息并将其保存以备下次使用。这样,您可以在viewWillAppear方法中进行所有定位标记杂耍,而不必担心 userLocation 干扰,直到您准备好它。

祝你好运。

于 2009-09-30T03:35:43.850 回答
27

在您的控制器中:

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

当地图出现时,它将以靠近帕洛阿尔托为中心

于 2009-09-24T07:49:40.463 回答
0

尝试showUserLocation在初始化时将该属性设置为 false,然后恢复region之前的地图视图(显然,您必须在之前的地图被破坏之前存储它)。

这是你想要的吗?

于 2009-09-25T01:36:14.090 回答
0

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

假设您有一个与遥控汽车的套接字连接,并且该汽车在有效载荷中发回包含地理位置信息的套接字数据。您可以将其解析出来,并实时更新地图上缩略图的位置。为此不需要“userLocation”属性,但如果您愿意,可以显示它。

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

于 2009-09-28T18:04:48.990 回答