我正在尝试使用NSRuleEditor来显示条件。如果我给它一个条件,它就会工作(创建一个静态标签),但当我给它多个条件时,规则编辑器的每一行都是空的(除了add/remove按钮之外,没有添加任何子视图)。为什么会这样呢?我的代码如下。
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
}发布于 2021-01-02 13:21:05
我自己解决了这个问题(在几个令人沮丧的小时之后)。
问题是我们从Objective-C协议方法-ruleEditor:child:forCriterion:withRowType返回Swift结构的实例。这些被编译器自动转换为__SwiftValue (一个Objective-C类)的实例。这看起来很好,直到我们在NSRuleEditor.h的顶部阅读到以下内容
树中的每个节点都由一个“条件”表示,它可以是任何对象。当用户从弹出菜单中进行选择时,规则编辑器视图将向其委托查询所选标准的子标准。对条件的唯一限制是,isEqual应将两个条件视为相等:如果它们表示相同的节点,则不能认为它们表示不同的节点。
所以我们的问题似乎是,我们返回的__SwiftValue没有对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比实际的文档页面更有帮助;帮您自己一个忙,通读一遍。
https://stackoverflow.com/questions/65536260
复制相似问题