これには一般的なアプローチがあると確信していますが、検索用語を特定できません。ユーザーが場所の使用を許可した後にビューを更新するには
私は、テーブルビューと1つのセルに位置の使用をオンにするスイッチを含む設定ビューコントローラを持っています。ユーザーがそのスイッチを切り替えると、必要なアクションを実行するためにView Controllerメソッドが起動されます。
スイッチをオフにすると、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方法は、画面上とオフの場合にはスイッチによって発射されたことがある私は私のモデルに直接「オフ」のコンセプトを取っていますので、即時の効果。 「スイッチオン」の場合、私はまだそれを有効にするために私のモデルに行きますが、結果は即座に(要求がポップアップするOSによって)発生しないため、モデルが変更を登録する前にsetNeedsDisplayがディスプレイを設定しています。
理論的に私はallowLocationChangeメソッドでブロックすることができましたが、それは非常に多くのレベルでは悪い考えのように聞こえるだけです。
説明が分からないだけでコードやビジュアルフローを入れてください。 – Jaimish