0

我正在尝试获得一个NSRuleEditor显示标准。如果我给它一个单一的标准,它会起作用(创建一个静态标签),但是当我给它一个以上的时候,规则编辑器的每一行都是空白的(除了添加/删除按钮之外没有添加子视图)。为什么会这样?我的代码如下。

struct RuleItem {

    var text: String

    var children: [RuleItem] = []

}

var ruleItems = [
    RuleItem(text: "hello"),
    RuleItem(text: "world", children: [
        RuleItem(text: "child 1"),
        RuleItem(text: "child 2")
    ])
]

// In class conforming to NSRuleEditorDelegate:

func ruleEditor(_ editor: NSRuleEditor, numberOfChildrenForCriterion criterion: Any?, with rowType: NSRuleEditor.RowType) -> Int {
    if let item = criterion as AnyObject as? RuleItem {
        return item.children.count
    } else {
        return ruleItems.count
    }
}

func ruleEditor(_ editor: NSRuleEditor, child index: Int, forCriterion criterion: Any?, with rowType: NSRuleEditor.RowType) -> Any {
    if let item = criterion as AnyObject as? RuleItem {
        return item.children[index]
    } else {
        return ruleItems[index]
    }
}

func ruleEditor(_ editor: NSRuleEditor, displayValueForCriterion criterion: Any, inRow row: Int) -> Any {
    (criterion as AnyObject as! RuleItem).text as NSString
}
4

1 回答 1

0

我自己解决了这个问题(经过几个令人沮丧的小时)。

问题是我们正在从 Objective-C 协议方法返回 Swift 结构的实例-ruleEditor:child:forCriterion:withRowType__SwiftValue这些由编译器自动转换为(Objective-C 类)的实例。这似乎很好,直到我们在顶部阅读以下内容NSRuleEditor.h

树中的每个节点都由一个“标准”表示,该标准可以是任何对象。当用户从弹出菜单中进行选择时,规则编辑器视图将向其委托查询所选标准的子标准。对标准的唯一限制是两个标准应该被 isEqual 视为相等:如果它们代表相同的节点,并且如果它们代表不同的节点则不能相等。

所以我们的问题似乎是__SwiftValue我们返回的 s 没有有意义的定义isEqual:。如果我们使用与 Objective-C 兼容的类而不是 Swift 结构,一切都会按预期工作。

有效的代码:

class RuleItem: NSObject {
    
    init(text: String, children: [RuleItem] = []) {
        self.text = text
        self.children = children
    }
    
    var text: String
    
    var children: [RuleItem] = []
    
}

var ruleItems = [
    RuleItem(text: "hello"),
    RuleItem(text: "world", children: [
        RuleItem(text: "child 1"),
        RuleItem(text: "child 2")
    ])
]

// In class conforming to NSRuleEditorDelegate:

func ruleEditor(_ editor: NSRuleEditor, numberOfChildrenForCriterion criterion: Any?, with rowType: NSRuleEditor.RowType) -> Int {
    if criterion == nil {
        return ruleItems.count
    }
    return (criterion as! RuleItem).children.count
}

func ruleEditor(_ editor: NSRuleEditor, child index: Int, forCriterion criterion: Any?, with rowType: NSRuleEditor.RowType) -> Any {
    if criterion == nil {
        return ruleItems[index]
    }
    return (criterion as! RuleItem).children[index]
}

func ruleEditor(_ editor: NSRuleEditor, displayValueForCriterion criterion: Any, inRow row: Int) -> Any {
    (criterion as! RuleItem).text
}

顺便说一句,NSRuleEditor.h联赛比实际的文档页面更有帮助吗?帮自己一个忙,通读一遍。

于 2021-01-02T05:21:05.047 回答