Почему мой 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
}

1 ответ

Я решил это сам (после нескольких разочаровывающих часов).

Проблема в том, что мы возвращаем экземпляры структуры Swift из метода протокола Objective-C. . Они автоматически преобразуются компилятором в экземпляры (класса Objective-C). Это выглядит хорошо, пока мы не читаем следующее в верхней части:

Каждый узел в дереве представлен «критерием», которым может быть любой объект. Когда пользователь делает выбор во всплывающих меню, представление редактора правил будет запрашивать у своего делегата дочерние критерии выбранного критерия. Единственное ограничение на критерии заключается в том, что два критерия должны считаться равными isEqual: если они представляют один и тот же узел, и не должны быть равными, если они представляют разные узлы.

Таким образом, наша проблема, по-видимому, заключается в том, что s мы возвращаемся, не имеют осмысленного определения . Все работает так, как ожидалось, если мы используем классы, совместимые с 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
}

Кстати, лиги более полезны, чем фактические страницы документации; сделайте себе одолжение и прочитайте его.

Другие вопросы по тегам