微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么我的 NSRuleEditor 不显示标准?

如何解决为什么我的 NSRuleEditor 不显示标准?

我正在尝试使用 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
}

解决方法

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

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

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

所以我们的问题似乎是我们返回的 __SwiftValueisEqual: 没有有意义的定义。如果我们使用兼容 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 比实际的文档页面更有帮助;帮自己一个忙,通读一遍。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。