选择多个项目时禁用 NSButton - Cocoa 绑定

Disable NSButton when multiple items selected - Cocoa Bindings

我想在连接到 NSArrayControllerNSTableView 中选择多个项目时禁用 NSButton。我知道我可以在未选择任何内容时轻松禁用按钮(绑定到 @count),但我不确定如何反转它以便 @count 必须 == 1 才能启用。

我正在使用 Swift,但我对最佳方法比特定语言的实现更感兴趣(除非 Swift 和 Objective C 之间的差异很大本例)。

如果选择包括多行,我如何使用 Cocoa 绑定来禁用 NSButton

  • 我们假设包含 table 视图的 class 称为 tableViewController
  • tableViewController.

    中声明一个属性selectionIndexes

    Objective-C:

    @property NSIndexSet *selectionIndexes;
    

    Swift:

    dynamic var selectionIndexes = NSIndexSet()
    
  • 将 table 视图的 Selection Indexes 绑定到那个 属性。

  • tableViewController中添加这两个方法

    Objective-C:

    + (NSSet *)keyPathsForValuesAffectingEnableButton
    {
      return [NSSet setWithObject:@"selectionIndexes"];
    }
    
    - (BOOL)enableButton
    {
      return self.selectionIndexes.count < 2;
    }
    

    Swift:

    override class func keyPathsForValuesAffectingEnableButton(key : String) -> Set<String> {
         return Set<String>(["selectionIndexes"])
    }
    
    func enableButton() -> Bool
    {
      return selectionIndexes.count < 2
    }
    

    keyPathsForValuesAffecting<key>是一种轻松实现键值观察器的方法。

  • 现在将按钮的 Enabled 属性 绑定到 tableViewControllerenableButton

如果您使用的是阵列控制器,请将 table 视图的 Selection Indexes 绑定到阵列控制器的 selectionIndexes 并将阵列控制器的 Selection Indexes 绑定到 [= tableViewController 的 15=]。

假设您现有的绑定将按钮的 enabled 绑定绑定到数组控制器的 selectionIndexes 属性,您可以实现您想要的're after with a value transformer:

只要阵列控制器的 selectionIndexes 属性 发生变化,按钮的状态就会更新。此更新的一部分将涉及调用您的值转换器,其中传入值将是更新后的 selectionIndexes。您的转换器逻辑必须 将此对象转换 为布尔值(启用或未启用),这将依次确定按钮的状态:

@objc(SelectionIndexesCountIsOneOrZeroTransformer)
public class SelectionIndexesCountIsOneOrZeroTransformer): NSValueTransformer {

    override public class func allowsReverseTransformation() -> Bool {
        return false
    }

    override public class func transformedValueClass() -> AnyClass {
        return NSNumber.self
    }

    override public func transformedValue(value: AnyObject?) -> AnyObject? {
        var retval = false

        if let indexSet = value as? NSIndexSet {
            retval = (indexSet.count < 2)
        }

        return retval
    }
}