首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >过滤NSOutlineView/NSTreeController

过滤NSOutlineView/NSTreeController
EN

Stack Overflow用户
提问于 2009-07-25 10:23:21
回答 3查看 1.7K关注 0票数 3

如何使用搜索框过滤NSOutlineView/NSTreeController?我知道这与绑定和谓词有关。但没有具体说明如何实现。谁能给我介绍一下过滤NSOutlineView/NSTreeController的步骤?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-07-25 15:22:10

我觉得你做不到。NSArrayController允许你给它一个过滤谓词,而NSTreeController不允许。我建议你使用file a bug

票数 2
EN

Stack Overflow用户

发布于 2018-05-17 22:28:00

从macOS 10.11开始,NSTableView (以及子类NSOutlineView)有了新的hideRows & unhideRows方法,可以简化过滤出行的任务。NSTreeController (它不是NSArrayController的子类,因此不继承它的filter谓词)中的项仍然没有自动过滤出来,但它至少做了很多繁重的工作,允许您将整个模型保留在控制器中,同时只显示其中的一个子集。

票数 0
EN

Stack Overflow用户

发布于 2021-02-23 05:56:32

我在这个问题上绞尽脑汁,但它实际上是非常简单的动态过滤一个NSTreeController,你只需要调整你的实际节点对象。

在我的例子中,我放弃了在控制器上实现实际的过滤器,而只是向我的树节点传递了一个谓词。当谓词在叶节点上不匹配时,我只需将其从子数组中删除。

代码语言:javascript
复制
class PredicateOutlineNode: NSObject {

    typealias Element = PredicateOutlineNode

    @objc dynamic var children: [Element] = [] {
        didSet {
            propagatePredicatesAndRefilterChildren()
        }
    }

    @objc private(set) dynamic var filteredChildren: [Element] = [] {
        didSet {
            count = filteredChildren.count
            isLeaf = filteredChildren.isEmpty
        }
    }

    @objc private(set) dynamic var count: Int = 0
    @objc private(set) dynamic var isLeaf: Bool = true

    var predicate: NSPredicate? {
        didSet {
            propagatePredicatesAndRefilterChildren()
        }
    }

    private func propagatePredicatesAndRefilterChildren() {
        // Propagate the predicate down the child nodes in case either
        // the predicate or the children array changed.
        children.forEach { $0.predicate = predicate }

        // Determine the matching leaf nodes.
        let newChildren: [Element]

        if let predicate = predicate {
            newChildren = children.compactMap { child -> Element? in
                if child.isLeaf, !predicate.evaluate(with: child) {
                    return nil
                }
                return child
            }
        } else {
            newChildren = children
        }

        // Only actually update the children if the count varies.
        if newChildren.count != filteredChildren.count {
            filteredChildren = newChildren
        }
    }
}

现在,您可以将NSTreeController类名设置为PredicateOutlineNode,并将其关键路径设置为filteredChildrencountisLeaf。当然,你可以用不同的方式命名你的对象访问器。现在,当我想要过滤树时,我在根节点上设置了一个NSPredicate,它向下传递它。

也适用于KVO,不需要额外的代码,NSOutlineView将自动更新。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1181813

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档