【发布时间】:2016-04-30 04:34:34
【问题描述】:
我确信有一个通用的方法,但我无法弄清楚搜索词。
我有一个设置视图控制器,其中包括一个表格视图和一个单元格中的一个开关来打开位置使用。当用户切换该开关时,我会触发视图控制器方法以采取必要的操作。
如果他们关闭开关,那么我会告诉我的模型将该选择存储在我的 NSUserDefaults 中并更新视图以反映这一点(包括删除一些表格单元格)。这里没有问题。
如果他们打开开关(第一次),我的方法会在用户允许在系统弹出窗口中使用位置之前触发并完成。因此视图没有被更新。这在技术上是正确的,但用户体验很差,因为 UI 没有更新以反映他们的变化。
我正在处理模型中位置跟踪状态的变化,即位置委托,所以如果设置视图被关闭并重新打开,一切都是正常的。
我的问题是我如何异步告诉我的视图更新,假设它仍然显示。除非用户是超人,否则它在物理上似乎仍然会出现在屏幕上,尽管从逻辑上来说它不需要。
更新:添加一些代码 sn-ps 以更好地说明。
这是我的模型类的关键部分,它们既存储我自己的位置跟踪状态(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 方法,但这在很多层面上听起来都是个坏主意。
【问题讨论】:
-
只有描述还不够理解放一些代码和视觉流程@zkarj
标签: ios asynchronous model-view-controller location