在ios中推出了树视图组件来表示层次结构数据。树可以通过点击每个节点中的(+)来展开,而可折叠的ny可以点击(-)节点。
我的类看起来像这样,
//树项目
@interface Node : NSObject
@property (nonatomic, strong) NSString *nodeCaption;
- (void)addNode:(Node *)node;
@end//树模型类
@interface Tree : NSObject
- (id)initWithParentNode:(Node *)node;//树视图类
@interface TreeView : UIView
- (id)initWithTree:(Tree *)tree andFrame:(CGRect)frame;
- (void)reloadData;
@end//使用方法
@implementation
Node *rootNode = [[Node alloc] init];
rootNode.caption = @"root";
NSArray *fruits1 = [NSArray arrayWithObjects:@"Apple", @"Peach", nil];
Node *fruit1Node = [[Node alloc] init];
fruit1Node.caption = @"set1";
for (NSString *fruit in fruits1) {
Node *aNode = [[Node alloc] init];
aNode.caption = fruit;
[fruit1Node addNode:aNode];
}
NSArray *fruits2 = [NSArray arrayWithObjects:@"Orange", @"Mango", nil];
Node *fruit2Node = [[Node alloc] init];
fruit2Node.caption = @"set2";
for (NSString *fruit in fruits2) {
Node *aNode = [[Node alloc] init];
aNode.caption = fruit;
[fruit2Node addNode:aNode];
}
[rootNode addNode:fruit1Node];
[rootNode addNode:fruit2Node];
Tree *tree = [[Tree alloc] initWithParentNode:rootNode];
TreeView *treeView = [[TreeView alloc] initWithTree:tree andFrame:self.frame];
[self.view addSubview:treeView];
[treeView reloadData];
@end这将输出类似于下面的内容
-Root
-set1
Apple
Peach
-set2
Orange
Mango在这种情况下,这是完全可以的。但问题出在我们用来为树创建输入的代码上,在这里,我们循环遍历我们持有的数据模型,并将其转换为树组件可以使用的模型。在我的例子中,我所有的树节点都是' category‘对象,我被迫将所有的category对象转换为Node对象来使用树。所以我想知道有没有一种方法可以使用树的用户打算使用的任何数据模型,而不是强制使用。
另外,我不想让用户对我的Abstract类进行子类化。因为,他们可能已经有了自己的父母。
发布于 2013-04-17 19:18:22
使用协议
如果我理解正确的话,您希望允许客户端使用自己的自定义对象作为"Node“对象。
如果这是正确的,那么您可以将"Node“作为协议而不是类,例如:
// If you want to add your objects to a tree, then you must implement this protocol...
@protocol NodeProtocol <NSObject>
@property (nonatomic, strong, readonly) NSMutableArray *children;
-(void)addNode:(id <NodeProtocol>)node; // Node items must support adding children nodes
-(NSString *)description; // Node items need to be able to print a textual description of themselves
@end
// Custom class implements the protocol
@interface CustomNode : NSObject <NodeProtocol>
...
@end使用封装的对象
或者,您可以将抽象对象封装在Node对象中,例如:
@interface Node : NSObject
@property (nonatomic, strong) NSObject *nodeItem;
-(void)addNode:(Node *)node;
@end使用类别
第三种方法是,您可以在NSObject上实现一个类别,并使用objc_setAssociatedObject将数据附加到对象。示例:
类别
#import "NSObject+NodeCategory.h"
#import <objc/runtime.h>
static char const *kNodeKey = "NodeKey";
@implementation NSObject (NodeCategory)
-(void)addNode:(NSObject *)node
{
NSMutableArray *children = [self children];
if (!children) children = [NSMutableArray new];
[children addObject:node];
[self setChildren:children];
}
-(void)setChildren:(NSMutableArray *)children
{
objc_setAssociatedObject(self, kNodeKey, children, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSMutableArray *)children
{
return objc_getAssociatedObject(self, kNodeKey);
}
@end示例用法
#import <Foundation/Foundation.h>
#import "NSObject+NodeCategory.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSObject *node = [NSObject new];
node.children = [NSMutableArray arrayWithArray:@[@"Kiwi Fruit", @"Apple", @"Bannana"]];
[node addNode:@"Dragon Fruit"];
NSLog(node.children.description);
}
return 0;
}https://stackoverflow.com/questions/16057853
复制相似问题