以编程方式更改cocoa绑定值

时间:2013-04-12 18:30:39

标签: objective-c cocoa cocoa-bindings

我的首选项中有一个NSButton,可以与将应用程序添加到LoginItems进行交互。如果添加登录项失败,我想取消选中该框,以便用户不会误将其添加到登录项中。但是,执行此操作后,当我再次单击该复选框时,不会触发绑定。

enter image description here

- (void)addLoginItem:(BOOL)status
{
    NSURL *url = [[[NSBundle mainBundle] bundleURL] URLByAppendingPathComponent:
                  @"Contents/Library/LoginItems/HelperApp.app"];

    // Registering helper app
    if (LSRegisterURL((__bridge CFURLRef)url, true) != noErr) {
        NSLog(@"LSRegisterURL failed!");
    }

    if (!SMLoginItemSetEnabled((__bridge CFStringRef)[[NSBundle mainBundle] bundleIdentifier], (status) ? true : false)) {
        NSLog(@"SMLoginItemSetEnabled failed!");
        [self willChangeValueForKey:@"startAtLogin"];
        [self.startAtLogin setValue:[NSNumber numberWithBool:[self automaticStartup]] forKey:@"state"];
        [self didChangeValueForKey:@"startAtLogin"];
    }
}

- (void)setAutomaticStartup:(BOOL)state
{
    NSLog(@"Set automatic startup: %d", state);
    if ([self respondsToSelector:@selector(addLoginItem:)]) {
        [self addLoginItem:state];
    }
}

- (BOOL)automaticStartup
{

    BOOL isEnabled  = NO;

    // the easy and sane method (SMJobCopyDictionary) can pose problems when sandboxed. -_-
    CFArrayRef cfJobDicts = SMCopyAllJobDictionaries(kSMDomainUserLaunchd);
    NSArray* jobDicts = CFBridgingRelease(cfJobDicts);

    if (jobDicts && [jobDicts count] > 0) {
        for (NSDictionary* job in jobDicts) {
            if ([[[NSBundle mainBundle] bundleIdentifier] isEqualToString:[job objectForKey:@"Label"]]) {
                isEnabled = [[job objectForKey:@"OnDemand"] boolValue];
                break;
            }
        }
    }
    NSLog(@"Is Enabled: %d", isEnabled);
//    if (isEnabled != _enabled) {
    [self willChangeValueForKey:@"startupEnabled"];
        startupEnabled = isEnabled;
    [self didChangeValueForKey:@"startupEnabled"];
//    }

    return isEnabled;
}

我有绑定到self.automaticStartup的复选框的数据绑定。如果我删除了行[self.startAtLogin setValue:[NSNumber numberWithBool:[self automaticStartup]] forKey:@"state"];,那么绑定工作正常,但如果添加项目失败,则不会取消选中。

如何以编程方式更改此绑定值,以便不会忽略所有其他绑定事件?

1 个答案:

答案 0 :(得分:0)

根据您的解释,您的约束值为automaticStartup,但您要为willChangeValueForKey:发送startAtLogin。为了使绑定正常工作,您需要在某个时刻警告绑定变量的更改。但是,由于你当时正处于setAutomaticStartup:之中,所以在这里做这件事并不安全。

在这种情况下,我不会使用绑定来执行更改本身,我会考虑旧式IBAction机制,然后在您确认时通过IBOutlet手动设置复选框值状态。