跨多个视图使用CoreLocation的最佳方法

时间:2011-01-15 23:09:05

标签: iphone objective-c ios mapkit core-location

我的应用程序中有两个视图,一个是一般视图,其中CoreLocation在用户在视图中执行其他操作时计算用户位置。用户在触摸按钮时访问第二个视图,允许他们使用mapview和MapKit更准确地定位自己,我希望此视图中的mapview显示CoreLocation已在第一个视图中识别的位置并继续根据另一个视图中CoreLocation的更新显示此位置。

这是创建封装CoreLocation内容的单例并在视图中使用地图引用或使用通知的最佳方法吗?或者为我的场景使用其他一些更好的练习?

由于

5 个答案:

答案 0 :(得分:6)

我有几个在多个地方使用CoreLocation的应用。从我读过的内容来看,你肯定希望只有CLLocationManager的一个实例。它对我来说是一个很好的单身人士。

希望这有帮助!

答案 1 :(得分:4)

如果我是你,我会这样做:

  1. 决定始终加载哪个视图。 我假设您希望 CalculatingView 一直加载,并且将根据用户操作加载/卸载 MapView

  2. CalculatingView 中分配并初始化指向 CLLocationManager 的指针。这将提供位置属性并调用委托消息。由于 CalculatingView 已加载并保留,因此该指针也始终有效。

  3. CLLocationManager 的委托设置为计算视图,如果此视图已分配并初始化,也可称为自我 CLLocationManager 指针。

  4. 计算视图

  5. 中实施 CLLocationManager 的委托方法
  6. 如果您愿意,可以在计算视图中分配和初始化 MapView 。但只要您可以向 MapView 发送消息,就可以在其他地方使用它。通过检查它是否 nil respondsToSelector 确保它们有效。

  7. CLLocationManager 的委托 CalculatingView 收到消息时,会向 MapView 发送消息。

  8. 这就像转发消息一样,但 MapView 应该响应的消息不必与发送到 CalculatingView 的消息相同,就像委托方法调用一样的 CLLocationManager

  9. 通过检查 MapView 是否有效,这意味着如果它已加载显示,您可以决定向 MapView 发送消息

    < / LI>

    本质是决定哪个视图是否被加载,使用委托方法将消息发送(或中继)到其他指针(在这种情况下, MapView 指针)。

    单身是好的,但除非你打算从多个地方使用 CLLocationManager ,比如超过3~4个地方,我认为没有必要

    希望我没有混淆你。根据您发布的内容,这种方式似乎可以为您的目标提供简单的解决方案。如果我没有抓住你的真实意图,请告诉我。

答案 2 :(得分:1)

我不确定这是最好的方法,但我一直在设置我的主控制器(首先加载的控制器)作为位置管理器代表。当位置更新时,它会以新位置作为通知对象触发通知。然后,任何监听的控制器都可以使用该数据,但是他们需要它。

另外,Apple的LocateMe应用程序实例化了三次位置管理器。因此,通过他们的例子,拥有多个LocationManagers可能不是问题。

答案 3 :(得分:0)

根据我的阅读,最佳做法是将CLLocationManager添加到App Delegate,因为您可以从任意视图访问它。

将简短的示例代码放在您需要CLLocationManager的视图中

....imports....

@implementation YourViewController

- (void)viewDidLoad {
   self.myLocationManager = [[UIApplication sharedApplication] delegate].yourLocationManagerVarName;
}

@end

跳跃有帮助。

答案 4 :(得分:0)

也许你应该考虑一种面向MVC的方法。根据您的描述,您缺少用户的模型层表示。使用基本CLLocation属性定义一个简单的User类将是第一步。

@interface User {}
@property (nonatomic, retain) CLLocation *location;
@end

@implementation User
@synthesize location;
- (void)dealloc {
  self.location = nil;
  [super dealloc];
}
@end

用户的同一个实例将传递给您的视图控制器。它可以在app delegate中创建。

接下来为您的应用创建位置服务对象。它将启动CLLocationManager,并将位置提供给您的用户。您可能必须设置GPS准确度,忽略您不想要的帧,并在此处实现基本的LBS逻辑。

此时,您有一个功能完整的应用程序,没有任何UI。这是一种很好的设计,可以重复使用和测试。

现在将您的UI叠加在其上。为您的根控制器提供指向应用程序委托中的User实例的指针。您的视图控制器将此指针传递给它创建的模态/导航视图控制器。

该控制器开始在viewDidLoad中观察用户的位置变化并做出相应的反应。

- (void)viewDidLoad {
   [self observeValueForKeyPath:@"location" ofObject:self.user change:0 context:NULL];
}

您的视图控制器还会注册您的位置服务对象引发的通知,以向用户显示警报。

基于其他答案:

  • 在代码中创建多个CLLocationManager实例没有真正的代价。唯一的副作用是api是异步的,因此你必须等待在视图控制器中获得一个有效的位置。您可以尝试使用locationManager.location API从viewDidLoad上的位置管理器获取当前位置。
  • 不要分享您的应用代表的内容。这可以防止代码重用。如果您重复使用您的观点并且您的app delegate没有位置管理员怎么办?

如果您需要更多代码,请询问。