2016-01-10 43 views
0

在将Cocoa应用程序从Objective-C转换为Swift时,我在数据源的itemIsExpandable方法中遇到项属性(类型ID)问题。NSOutlineView和isItemExpandable不能在Swift中工作

在Objective-C I测试item==nil和,并返回该项目的儿童人数如果不是:[[item children] count]由于雨燕这个属性是AnyObject型的,我不能测试为零。

我也不能测试为零没有得到解包错误。我不一定能够回报真正的价值,因为在某些情况下,该物品没有孩子。为了增加混淆,在数据源方法numberOfChildrenOfItem中,项目的类型是可选的AnyObject?有任何想法吗?

回答

0

你的问题的一个可能的解决方案是通过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的零检查相当于以及防范链中其他地方的问题(例如,如果item事实证明不是TreeNode)。通常,应尽可能避免强制展开(!)。

+0

我花了一段时间,但可选的链接示例是我的数据模型最好的工作。我认为Swift和Obj-C之间的区别是语法,但是最近几天让我意识到Swift非常强大,需要采用不同的思维方式才能将它用于Cocoa应用程序。太奇妙了。只有一个 ”!”有必要让它工作。谢谢!你们都很棒。 – Charlie

0

有问题的数据源方法的签名如下:

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] 
} 
0

item不是可选的,因为它永远不会是nil。 A nil项目将代表根项目,但这不可见。这是实际可见的顶级项目的“虚拟”父级。由于它从来没有显示过,并且它的孩子总是显示出来,所以大纲视图并不关心它是否“可展开”,并且永远不会问你的代表。