2012-06-06 113 views
1

我有开关,我想检测是否有任何开关改变位置,如果改变了,我需要开始我的行动。如何检测NSUserDefault中的更改?

交换机存储位置NSUserDefaults

- (IBAction)saveSwitch:(id)sender 
{  
    NSUserDefaults *defs1 = [NSUserDefaults standardUserDefaults]; 
    [defs1 setBool: blackSwitch.on forKey: @"blackKey"]; 

    NSUserDefaults *defs2 = [NSUserDefaults standardUserDefaults]; 
    [defs2 setBool: greenSwitch.on forKey: @"greenKey"]; 

    [[NSUserDefaults standardUserDefaults] synchronize]; 
} 

回答

5

,每当你在其他类调用synchronize

[[NSNotificationCenter defaultCenter] postNotificationName:@"MyAppSettingsChanged" object:self userInfo:nil]; 

后来听通知您可以张贴通知。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAppSettingsChanged:) name:@"MyAppSettingsChanged" object:nil]; 

-(void) onAppSettingsChanged:(NSNotification)notification 
{ 
    // settings changed 
} 

如果你愿意,你可以在调用postNotificationName包含像其设置已经改变了信息传递时的NSDictionary到用户信息。

+0

非常感谢! –

+0

现在我遇到了一个问题,因为我有8个开关,当我更改例如5个开关位置时,它发布了5个通知。有没有办法只发布一个通知? –

+1

SaveSwitch是否连接到小部件?除非您有某种保存按钮,否则每次都必须提高事件数量 - 或者在关闭对话框时保存并发布通知。 – tumtumtum

0

不能检测的变化NSUserDefaults的。相反,跟踪交换机本身何时发生变化,并处理该事件。例如:

[blackSwitch addTarget:self 
       action:@selector(blackSwitchChanged:) 
     forControlEvents:UIControlEventValueChanged]; 

手柄开关位置变化:

- (IBAction)blackSwitchChanged:(id)sender { 
    NSLog(@"Black switch changed"); 
    .. 
    // check if blackSwitch is on or off. 
} 
+0

是的,这工作..但我的意思是别的东西。我的开关在ModalView中,如果开关已更改,我想在另一个视图中开始操作。那可能吗? –

+0

如果您想在不同的视图中处理此问题,则必须设置委派或使用通知。如果您需要了解如何使用代表,请修改您的问题或发布新问题。 – melsam

3

如果您使用NSUserDefaults,最简单的方法是订阅NSUserDefaultsDidChangeNotification。它会在发生变化时自动发送。

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(appSettingsDidChange:) 
              name:NSUserDefaultsDidChangeNotification 
              object:nil]; 
2

追踪NSUserDefaults更改的最佳方式是使用KVO添加观察者。这样您就不需要执行任何自定义通知代码或手动跟踪更改。

在想要的类有关更改的通知只是把它注册为一个监听到指定的键:

[[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"blackKey" options:NSKeyValueObservingOptionNew context:nil];  
[[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"greenKey" options:NSKeyValueObservingOptionNew context:nil]; 

然后,只需对该通知的回复:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    if (object == defaults) { 
     // Here you can grab the values or just respond to it with an action. 
    } 
} 

现在,每当一个这些密钥更改会自动通知您。

这是一个超级干净的解决方案,并允许一些重用。例如,如果将NSKeyValueObservingOptionInitial键添加到上面的options参数(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew)中,那么它也会通知您的观察者方法具有初始值,即使对于初始状态,也允许您重新使用该方法。


斯威夫特版本

设置的默认值:

NSUserDefaults.standardUserDefaults().addObserver(self, forKeyPath: "blackKey", options: .New, context: nil) 
NSUserDefaults.standardUserDefaults().addObserver(self, forKeyPath: "greenKey", options: .New, context: nil) 

观察员:

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) { 
    if object is NSUserDefaults { 
     // Here you can grab the values or just respond to it with an action. 
    } 
}