本来这一节,我是要写一个CoreData的例子的,实际上那一篇我已经完成了超过一半。能够使用CoreData增加一个根记录,并且能在OutlineView 里面显示。以下两个原因使得我决定增加这么一篇: 首先我想在OutLineView里面增加场景菜单,不同级别的分类菜单的内容应该是不同的。第二就是OutLineView的显示问题,OutLine有相当强的显示能力的,如果在那一篇文章里面加入这些内容,就显得过于跑题,如果不加这些内容,就会让人觉得看不懂。对我自己而言,反正是要学习这部分内容的,
我大致看了下,这部分内容并不少,完全够的上一章,所以就这么临时变卦了。
这一章实际上是一个Mac提供的例子,我想自己重新做一遍,并记录以下我的想法。DragNDropOutlineView,你可以去下载来看,也可以就在这里跟随我做,随你(我们后面要用到例子的内容,所以下载一个吧)。
首先建立工程:MyDragOutLineView。
程序自动产生了 DovAppDelegate,这个类其实就是例子里面的AppController,但我不想把数据源这类东西放在这里。
如果我们要编一个较大的程序,各自的功能应该各自管理,写在AppController 里面不是好习惯。可能会方便点点。
我们继续建立我们的数据源类,就象(1)里做过的。拖一个OutlineView到窗口,其他的暂时都不要,按例子一样的格式设置OutLineView的各个列。 注意要把CheckBox Cell 拖入2,3列,不是CheckBox。我揣摩,带Cell的,是源于一个基类的类,它有能力作为表格的一个单元,而控件并没有这样的性质。换言之,表格无法识别和管理它。
表格的第一项,做了一个自定义类的,使得它有能力支持图片,这个我们稍后再说。
在我们的数据源里增加一个 NSTreeNode类的对象,去查一下它吧。
NSTreeNode *_rootTreeNode;
NSTreeNode类简单地建立和管理一个对象树。每个树的节点描述一个模型对象。如果某个节点的父节点为nil,就表示它是这个树的根。记住它,将来你一定会在某种场合遇到它的。我们其实第一个例子里面就可以用它,当然,我当时并不知道这个类。树是非常常见的一个数据类型。
然后将OutLineView 对象拉入数据源类里面,并建立一个属性。在此之前,应该先拖进来一个Object对象,并将它的类设置为我们的数据源类。如果数据源游离在程序之外,是无法拉入IBOutlet对象的。这不难理解。另外要设置OutLineView的Datasource和Delegate都是我们的数据源类(拉线)。
NSTreeNode 对象的初始化数据来源于一个称为 initinfo.dict 的数据文件,xml格式。我不知道这个文件是从哪里来的,有那些具体要求,目前我们就跳过这个,直接从例子那边拷贝过来,同时也拷贝例子里面的那些图片文件。后面,我们将要用到他们。
将 SimpleNodeData.h和SimpleNodeData.m两个文件添加到我们的工程里面。这个类是树节点的相应对象,保存 initinfo.dict 里面的内容。这个也没太多好说的。只是不符合ARC的内容要处理一下。
然后,将数据源相关的方法拷贝到我们的数据源里面。这时候如果执行一下程序,你会发现OutLineView有了些东西,当没有内容。这是因为内容没有送达我们OutlineView相应的列造成的。仔细查看objectValueForTableColumn的代码,你会发现,程序是根据 列的identifier来分配内容的,而我们还没有设置,对应例子程序设置相应的 identifier。再次运行程序,你会看到我们期望的结果已经大致出来了。
下面是我们几个文件中的源代码:
//
// DovDataSource.h
// MyDragOutLineView
//
// Created by wuzhiqiang on 12-12-11.
// Copyright (c) 2012年 wuzhiqiang. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface DovDataSource :NSObject{
NSTreeNode *_rootTreeNode;
__weakNSOutlineView *_outlineView;
}
@property (weak) IBOutlet NSOutlineView *outlineView;
@end
//
// DovDataSource.m
// MyDragOutLineView
//
// Created by wuzhiqiang on 12-12-11.
// Copyright (c) 2012年 wuzhiqiang. All rights reserved.
//
#import "DovDataSource.h"
#import "SimpleNodeData.h"
// It is best to #define strings to avoid making typing errors
#define LOCAL_REORDER_PASTEBOARD_TYPE @"MyCustomOutlineViewPboardType"
#define COLUMNID_IS_EXPANDABLE @"IsExpandableColumn"
#define COLUMNID_NAME @"NameColumn"
#define COLUMNID_NODE_KIND @"NodeKindColumn"
#define COLUMID_IS_SELECTABLE @"IsSelectableColumn"
#define NAME_KEY @"Name"
#define CHILDREN_KEY @"Children"
@interface DovDataSource(AppPrivate)
- (void)addNewDataToSelection:(SimpleNodeData *)newChildData;
- (NSImage *)randomIconImage;
- (NSTreeNode *)treeNodeFromDictionary:(NSDictionary *)dictionary;
- (BOOL)_dragIsLocalReorder:(id <NSDraggingInfo>)info;
@end
@implementation DovDataSo