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

ツリー内の各ノードは、任意のオブジェクトである「基準」によって表されます。ユーザーがポップアップ メニューから選択すると、ルール エディター ビューは、選択した条件の子条件についてデリゲートにクエリを実行します。基準に関する唯一の制限は、2 つの基準が isEqual によって等しいと見なされる必要があるということです。それらが同じノードを表している場合、それらが異なるノードを表している場合は等しくなってはなりません。

__SwiftValueしたがって、私たちの問題は、返される s に の意味のある定義がないように思われますisEqual:。Swift 構造の代わりに Objective-C 互換のクラスを使用すると、すべてが期待どおりに機能します。

動作するコード:

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 に答える