我确信这是一种通用方法,但我无法弄清楚搜索条件。
我有一个设置视图控制器,它包含一个表视图,在一个单元格中有一个开关来打开位置使用。当用户切换该开关时,我触发视图控制器方法以采取必要的操作。
如果他们关闭开关,那么我告诉我的模型将该选项存储在我的NSUserDefaults中并更新视图以反映这一点(包括删除一些表格单元格)。这里没问题。
如果他们打开开关(第一次),我的方法会在用户允许在系统弹出窗口中使用位置之前触发并完成。因此视图没有更新。这在技术上是正确的,但是用户体验不佳,因为UI不会更新以反映他们的更改。
我正在处理模型中位置跟踪状态的更改,即位置委托,因此如果设置视图被取消并重新打开,则所有内容都应该是这样。
我的问题是如何异步告诉我的视图更新,假设它仍然显示。除非用户是超人,否则在物理上肯定它仍会在屏幕上显示,但逻辑上它不一定是。
更新:添加一些代码段以更好地说明。
以下是我的模型类的关键部分,它们都存储我自己的位置跟踪状态(useLocation变量)并充当位置管理器委托:
public class WorldModel : NSObject, CLLocationManagerDelegate {
var useLocation = false
override init() {
super.init()
let userDefaults = NSUserDefaults.standardUserDefaults()
useLocation = userDefaults.boolForKey("useLocation")
let locationStatus = CLLocationManager.authorizationStatus()
switch locationStatus {
case .NotDetermined:
useLocation = false
case .AuthorizedAlways, .AuthorizedWhenInUse:
break
case .Denied, .Restricted:
useLocation = false
userDefaults.setBool(false, forKey: "useLocation")
}
if useLocation {
setLocationTracking(true)
}
}
// ================================================================================
// Turn on or off location tracking for the model
// ================================================================================
public func setLocationAllowed(allowed: Bool) {
useLocation = allowed
setLocationTracking(allowed)
}
// ================================================================================
// Turn on or off location tracking with the OS
// ================================================================================
public func setLocationTracking(state: Bool) {
if state {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers
locationManager.requestWhenInUseAuthorization()
locationManager.pausesLocationUpdatesAutomatically = true
locationManager.startUpdatingLocation()
} else {
locationManager.stopUpdatingLocation()
}
}
// ================================================================================
// Capture location permission changes from the OS
// ================================================================================
public func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
let userDefaults = NSUserDefaults.standardUserDefaults()
switch status {
case .NotDetermined:
useLocation = false
case .AuthorizedAlways, .AuthorizedWhenInUse:
useLocation = true
userDefaults.setBool(true, forKey: "useLocation")
case .Denied, .Restricted:
useLocation = false
userDefaults.setBool(false, forKey: "useLocation")
}
}
}
这是视图控制器,它管理我想要更新的设置视图。 (仅相关部分。)
class SettingsViewController2: UIViewController, UITableViewDataSource, UITableViewDelegate {
var theWorldModel : WorldModel?
func allowLocationChange(sender: UISwitch) {
guard let ourWorld = theWorldModel else {
return
}
ourWorld.setLocationAllowed(sender.on)
self.view.setNeedsDisplay()
}
}
屏幕上的开关触发allowLocationChange方法,并且在关闭它的情况下立即生效,因为我将“关闭”概念直接用于我的模型。在“开启”的情况下,我仍然会转到我的模型来实现它,但结果不是立即的(由于操作系统弹出请求),因此setNeedsDisplay在模型注册更改之前设置显示
理论上我可以在allowLocationChange方法中阻塞,但这听起来像是一个很糟糕的想法。
答案 0 :(得分:1)
有一个CLLocationManager类,它是iOS中位置功能的根类。
CLLocationManager Class Reference
我建议您开发自己的类,它将负责为您的应用程序使用CLLocationManager实例。 它将隐藏CLLocationManager的实例,一个使用该实例的方法列表(如currentAuthorizationStatus(),authorize()...),更重要的是这个类将被指定为CLLocationManager实例的委托。
CLLocationManagerDelegate协议方法之一是 locationManager(_:didChangeAuthorizationStatus:)。在实施此方法时,您可以通过NSNoticationCenter发布通知。并且您的Settings viewController应该订阅此通知并做出相应的反应。
由您决定如何使您的类实例在您的应用程序中保持活力和独特性。我使用单身模式。