【问题标题】:NSOutlineView and isItemExpandable not working in SwiftNSOutlineView 和 isItemExpandable 在 Swift 中不起作用
【发布时间】:2016-01-10 18:14:57
【问题描述】:

在将Cocoa 应用程序从Objective-C 转换为Swift 时,我遇到了数据源itemIsExpandable 方法中的项目属性(类型id)的问题。

在 Objective-C 中,我测试 item==nil,如果不是,则返回该项目的子项数量:[[item children] count] 由于在 Swift 中此属性的类型为 AnyObject,因此我无法测试零。

如果没有展开错误,我也无法测试为零。我不一定能返回一个真值,因为在某些情况下该项目没有子项。更令人困惑的是,在数据源方法numberOfChildrenOfItem 中,项目的类型是可选的AnyObject?有任何想法吗?

【问题讨论】:

    标签: objective-c xcode swift cocoa


    【解决方案1】:

    您的问题的一个潜在解决方案是通过 Swift 的可选链接,如下所示:

    func outlineView(outlineView: NSOutlineView, isItemExpandable item: AnyObject) -> Bool {
        if let _ = (item as? TreeNode)?.children {
            return true
        }
    
        return false
    }
    
    func outlineView(outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int {
    
        if let children = (item as? TreeNode)?.children {
            return children.count
        }
    
        return content.count
    }
    
    func outlineView(outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject {
    
        if let child = (item as? TreeNode)?.children?[index] {
            return child
        } else if index >= 0 && index != NSNotFound {
            return content[index]
        }
    
        return self
    }
    

    这样做的好处是,您既可以执行与 Objective-C nil 检查相同的操作,也可以防止链中其他地方出现问题(例如,如果 item 被证明是其他问题比TreeNode)。通常,应尽可能避免强制展开 (!)。

    【讨论】:

    • 我花了一些时间,但可选链接示例是我的数据模型使用得最好的示例。我只是认为 Swift 和 Obj-C 之间的区别在于语法,但最近几天让我意识到 Swift 非常强大,并且需要不同的思维方式才能将其用于 Cocoa 应用程序。太奇妙了。只有一个 ”!”有必要让它工作。谢谢!你们也太棒了。
    【解决方案2】:

    相关数据源方法的签名如下:

    func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: AnyObject) -> Bool
    

    item 只是您通过-outlineView(_:child:ofItem:) 传递给数据源的对象之一,因此找出它是什么类型的对象并使用对象的属性来计算您应该返回什么。在下面的代码中,我的数据源很简单——一切都是Document

    class Document: NSObject {
        dynamic var title: String?
        dynamic var documents = NSMutableArray() // children
        dynamic var isPage: NSNumber! // isExpandable
        dynamic weak var parent: Document?
    }
    

    这是数据源:

    // MARK:- NSOutlineViewDataSource
    
    // <contents> is the array holding the top-level tree objects
    
    func outlineView(outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int {
        return item == nil ? contents.count : (item as! Document).documents.count
    }
    
    func outlineView(outlineView: NSOutlineView, isItemExpandable item: AnyObject) -> Bool {
        return (item as! Document).isPage.boolValue == false
    }
    
    func outlineView(outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject {
        // The object returned here is always a Document
        return item == nil ? contents[index] : (item as! Document).documents[index]
    }
    

    【讨论】:

      【解决方案3】:

      item 不是可选的,因为它永远不会是nilnil 项目将代表根项目,但这是不可见的。它是实际可见的顶级项目的“虚拟”父级。由于它从不显示,并且它的子项总是显示,所以大纲视图不关心它是否“可扩展”,并且永远不会询问您的代表。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-05
        • 2014-07-27
        相关资源
        最近更新 更多