xcode - 以编程方式更改状态时 NSButton 绑定(bind)失败

标签 xcode cocoa cocoa-bindings nsbutton

我有一个核心数据Mac应用程序,具有不同的实体和属性...... 这些属性之一绑定(bind)到 NSButton 复选框...

这是我的问题: 如果我用鼠标单击按钮,我可以看到其状态发生变化(例如从未选中更改为选中),并且绑定(bind)属性的状态将保存到数据核心,因为如果我关闭并重新打开应用程序,按钮仍然处于选中状态...

但是...

如果我以编程方式更改此按钮的状态,我仍然可以看到其状态发生变化(相同的示例,从未选中更改为选中),但绑定(bind)属性的状态不会保存到数据核心,如果我关闭重新打开应用程序,按钮又回到未选中状态!

有什么想法吗?

编辑

好吧,我会尽力解释(抱歉我的英语不好)......

我必须对这个名为 Adherents 的实体的某些值进行一些操作和验证(例如,如果 date1> date2 则选中 checkbox1,如果选中 checkbox2,则无论日期比较如何,都会选中 checkbox1)...

我首先指出了一个解决方案,我在“NSManagedObject 子类文件 Adherents.m”中使用该实体的值执行这些操作

- (void)awakeFromFetch{

 [super awakeFromFetch];


    // Controle de la cotisation
    aujourdhui = [NSDate date];
    finCotisation = [NSDate dateWithString:[dateCotisation description]];
    controle = [aujourdhui compare:finCotisation];
   if(controle == NSOrderedAscending)
   {
       self.cotisation = [NSNumber numberWithBool:1];
   }
    else if(controle == NSOrderedDescending)
    {
       if ([self.membreHonneur boolValue] == 0)
       {
            self.cotisation = [NSNumber numberWithBool:0];
        }
      else if ([self.membreHonneur boolValue] == 1)
       {
            self.cotisation = [NSNumber numberWithBool:1];
       }
    }
}

就像这样,该操作仅在应用程序启动时发生,这很好,但还不够…… 为了“在途中”(在用户通过 NSDatePicker 输入或更改日期之后)执行此操作,我找到的最佳解决方案是检查用户何时编辑日期选择器...... 看来我只能在 AppDelegate.m 文件中执行此操作(尝试在 Adherents.h 中声明“IBOutlet NSDatePicker *champDate;”,但是随后,我无法使用 Interface Builder 中的复选框连接 socket ...),并且我似乎也无法从那里访问和操作实体值(“self.cotising”在 AppDelegate.m 中使用时会带来未知属性,并且我找不到如何在 AppDelegate.h 中正确声明它)。

所以,我的解决方案是在 AppDelegate 中执行这些操作,比较 NSDatePicker 的值并作用于 NSButton 复选框状态......

- (void)awakeFromNib {

    [champDate setTarget:self];
    [champDate setAction:@selector(checkDate:)];

}

-(void)checkDate:(id)object {
   finCotisation = [NSDate dateWithNaturalLanguageString:[champDate stringValue]];
   aujourdhui = [NSDate date];
   NSComparisonResult controle = [aujourdhui compare:finCotisation];
    if(controle == NSOrderedAscending){
        [bouttonCotisation setState:TRUE];
    }
    else if(controle == NSOrderedDescending){
        [bouttonCotisation setState:FALSE];
   }
}

但是,当这样做时,绑定(bind)会失败......所以,我必须同时执行这两件事:监视 NSDatePicker 并以编程方式更改 AppDelegate.m 中的复选框状态,并且还使用 Adherents.m 中的 AwakeFromFetch 检查和更改实体值,我当一切都绑定(bind)时,我认为这是一个伟大的废话^^

最佳答案

我不确定我是否理解您问题的具体情况,但收集了这么多:

  • 从外部看您的数据模型对象具有以下属性
    • 两个日期值
    • bool 值
    • 第二个 bool 值,应根据其他三个值具有不同的值
  • 您仅更新 awakeFromFetch 方法中的依赖值,因此在运行时更改数据时它不会更新,因此您需要在 AppDelegate 中手动更改复选框。

我发现这种方法有两个问题:

  1. 使用绑定(bind)时,您应该只更改模型数据来更新 UI,而不是直接调用 UI 元素的 setter。
  2. 如果您有一个完全依赖于其他属性的属性,请不要单独保存它(缓存原因除外,但这会使它变得更加复杂)。只需即时计算即可。

我假设你的模型类如下所示:

@interface
@property (strong) NSDate *date1;
@property (strong) NSDate *date2;
@property (assign BOOL someBool;
@end

现在我们以同样的方式声明将依赖属性添加到头文件中:

// readonly because it cannot be changed directly, only the values it depends on can be changed
@property (assign, readonly) BOOL dependentBool;

但是对于这个属性,我们自己在 @implementation 中实现了 getter:

-(BOOL)dependentBool
{
    if (NSOrderedAscending = [self.date1 compare:self.date2])
        return YES;

    if (self.someBool)
        return YES;

    return NO;
}

这样,每当有人检查 dependentBool 属性时,它都会返回正确的结果。您现在可以将复选框绑定(bind)到 dependentBool。 但是,如果您更改任何值,则依赖于复选框的值将不会更新,因为它不知道值已更改。为了解决这个问题,我们将以下方法添加到模型类实现中:

+(NSSet *)keyPathsForValuesAffectingDependentBool
{
    return [NSSet setWithArray:@[@"date1", @"date2", @"someBool"]];
}

这告诉任何观察 dependentBool 属性(当绑定(bind)到此属性时复选框将执行此操作)的人,它依赖于这些键路径,因此也应该观察这些键路径。

这样,您只需更改 date1 的值,绑定(bind)到 dependentBool 的任何 View 都会相应更改。

注意:要使其正常工作,您必须通过属性的 setter 更改属性的值([myModelObject setDate1:date]myModelObject.date1 = dateself.date1 = date) 不直接更改实例变量 (_date1 = date)。

我希望您可以根据您的需要调整此示例。

关于xcode - 以编程方式更改状态时 NSButton 绑定(bind)失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13994149/

相关文章:

c++ - 使用 Mac C++ 连接 sqlite3 时构建错误

swift - 本地化 FirebaseUI 身份验证

ios - 如何使用 AVFoundation 获取 iOS 中播放的视频的当前帧?

core-data - cocoa 绑定(bind) : Binding to the "many" end of a to-many relationship

ios - 如何让 UNNotificationSound 使用我项目中蓝色文件夹中的 .caf 文件

swift - 在 Swift 3 和 Xcode 中使用堆栈 View 按钮打开 Storyboard View

cocoa - 在 SDEF 中声明各种 <accessor style> 标签有什么作用?

macos - 支持图层的 NSView 旋转和倾斜同级

macos - 使用绑定(bind)和结构时自定义 nspopupbutton 标题

objective-c - 如何从 NSCollectionViewItem 的 View 中获取 representedObject?