gpt4 book ai didi

objective-c - NSOutlineView 中数组枚举对象的自定义部分

转载 作者:太空狗 更新时间:2023-10-30 03:45:36 25 4
gpt4 key购买 nike

我正在尝试为列出的对象创建一个带有自定义 header 组(父节点)的 NSOutlineVew。 (注意:我有基于单元格的 NSOutlineView)。例如,它看起来像 Xcode 的“Navigator”或 Numbers 侧边栏。我为每个类别的分离属性使用了默认组,但它看起来不像我想要的那样。我需要一个父节点(单元格),我可以对其进行视觉调整(添加控件元素和图像)。

我试图通过将对象数组传递给 NSDictionary 来实现这一点,为每个组提供特定的键。结果,通过 NSLog 一切都正确显示,但是将此变量作为程序 NSOulineView 的源的传输失败。

ProjectViewController.h

@interface ProjectViewController : NSViewController <NSOutlineViewDataSource, NSObject> {
IBOutlet NSOutlineView *outlineView;
FSEntity *content;
}

@property (readonly, assign) NSMutableArray *objects;

@end

ProjectViewController.m

@implementation ProjectViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Initialization code here.
// Setting default path to the local file or directory
NSString *home = NSHomeDirectory();
NSURL *url = [[NSURL alloc] initFileURLWithPath:home];
content = [[FSEntity alloc] initWithURL:url];

[self defineContentNSOutlineView];
NSLog(@"Array: %@",_objects);

// Basic сonfiguration an instance NSOutlineView
[self configurationNSOutlineView];
} return self;
}

@synthesize objects = _objects;

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
return (item == nil) ? [content.children objectAtIndex:index] : [((FSEntity *)item).children objectAtIndex:index];
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
return (item == nil) ? content.children.count > 0 : ((FSEntity *)item).children.count > 0;
}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
return (item == nil) ? content.children.count : ((FSEntity *)item).children.count;
}

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
if ([item isKindOfClass:[FSEntity class]]) {
return [((FSEntity *)item) title];
}

return nil;
}

- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item {
if ([cell isKindOfClass:[ImageAndTextCell class]]) {
ImageAndTextCell *textField = (ImageAndTextCell *)cell;
[textField setImage:[item icon]];
}
}

- (void)defineContentNSOutlineView {
NSMutableArray *objects = [NSMutableArray arrayWithObjects:[NSDictionary dictionaryWithObjectsAndKeys:@"FINDER", @"title", [NSArray arrayWithObjects:[NSDictionary dictionaryWithObject:content.children forKey:@"title"], nil], @"children",[NSNumber numberWithBool:YES], @"header", nil], nil];
_objects = objects;
}

- (void)configurationNSOutlineView {
[outlineView sizeLastColumnToFit];
[outlineView setFloatsGroupRows:NO];
[outlineView reloadData];
[outlineView expandItem:nil expandChildren:YES];
}

@end

为了更容易想象它的外观,我在方案上展示了它:

                 +--------------------------------------------+
| ▼ FINDER FILES ₪ ✱ |
| 03143553.file |
| ▶ Desktop |
| ▶ Documents |
| ▶ Downloads |
| ▶ Movies |
| ▶ Music |
| ▶ Pictures |
+--------------------------------------------+

以及我现在拥有的(不使用 NSTreeController 的 NSOulineView);

                 +--------------------------------------------+
| 03143553.file |
| ▶ Desktop |
| ▶ Documents |
| ▶ Downloads |
| ▶ Movies |
| ▶ Music |
| ▶ Pictures |
+--------------------------------------------+

我知道示例 Apple“SourceView”,但我不知道如何添加到创建的组、对象数组(文件和文件夹),NSTreeContoller 仅显示层次结构的第一个元素(不包含):

                 +--------------------------------------------+
| ▼ FINDER FILES |
| 03143553.file |
| Desktop |
| Documents |
| Downloads |
| Movies |
| Music |
| Pictures |
+--------------------------------------------+

SourceView示例修改方法:

- (void)addFinderSection {
[self addFolder:@"FINDER FILES"];

NSError *error = nil;
NSEnumerator *urls = [[[NSFileManager defaultManager] contentsOfDirectoryAtURL:self.url includingPropertiesForKeys:[NSArray arrayWithObjects: nil] options:(NSDirectoryEnumerationSkipsHiddenFiles) error:&error] objectEnumerator];
for (NSURL *url in urls) {
BOOL isDirectory;
if ([[NSFileManager defaultManager] fileExistsAtPath:[url path] isDirectory:&isDirectory]) {
if (isDirectory) {
[self addChild:[url path] withName:NO selectParent:YES];
} else {
[self addChild:[url path] withName:NO selectParent:YES];
}
}
}

[self selectParentFromSelection];
}

此方法仅显示第一个对象,如后一个方案所示。

还有一个问题,正如我之前所说,如何将节点 **“FINDER FILES”** 按钮添加到单元格的右侧。

你能帮我解决这个问题吗?我知道,也许并不难,但我刚开始学习 Objective-C,我不知道该怎么做。谢谢。

最佳答案

根据您提供的起始代码,我能够使用基于单元格的 NSOutlineViews 来实现一些工作。您发布的代码似乎不完整,因此很难知道您想从缺少的 FSEntity 类中得到什么。我只是使用基础类:NSArray 用于节点列表(即根节点和子节点),NSDictionaries 用于每个节点本身(根节点和子节点),以及 NSURL 作为文件系统引用。我试图尽可能接近您的原始代码。最后,它看起来像这样:

ProjectViewController.h

@interface ProjectViewController : NSViewController <NSOutlineViewDataSource, NSObject>
{
IBOutlet NSOutlineView *outlineView;
NSURL *content;
}

@end

ProjectViewController.m

#import "ProjectViewController.h"

@interface ProjectViewController () {
NSMutableArray* _objects;
}
@property (nonatomic, retain, readwrite) NSMutableArray* objects;
@end

@implementation ProjectViewController

@synthesize objects = _objects;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Initialization code here.
// Setting default path to the local file or directory
NSString *home = NSHomeDirectory();
content = [[NSURL alloc] initFileURLWithPath:home];

[self defineContentNSOutlineView];
NSLog(@"Array: %@",_objects);

// Basic сonfiguration an instance NSOutlineView
[self configurationNSOutlineView];
}
return self;
}

// nodes have 3 keys: title, url, icon
- (NSArray*)p_childrenForNode: (NSMutableDictionary*)node {
if (nil == node)
return self.objects;

NSArray* retVal = nil;
if (nil == (retVal = [node valueForKey: @"children"]))
{
NSMutableArray* children = [NSMutableArray array];
for (NSURL* urlInDir in [[NSFileManager defaultManager] contentsOfDirectoryAtURL: [node objectForKey: @"url"]
includingPropertiesForKeys: [NSArray arrayWithObjects: NSURLNameKey, NSURLEffectiveIconKey, nil]
options: 0
error: NULL])
{
id name = [urlInDir getResourceValue: &name forKey: NSURLNameKey error: NULL] ? name : @"<Couldn't get name>";
id icon = [urlInDir getResourceValue: &icon forKey: NSURLEffectiveIconKey error: NULL] ? icon : nil;

NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithObjectsAndKeys: urlInDir, @"url", name, @"title", nil];

if (icon)
[dict setObject: icon forKey: @"icon"];

[children addObject: dict];
}

retVal = children;

if (children)
[node setValue: children forKey: @"children"];
}
return retVal;
}

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
NSMutableDictionary* itemDict = (NSMutableDictionary*)item;
NSArray* children = [self p_childrenForNode: itemDict];
return children.count > index ? [[[children objectAtIndex: index] retain] autorelease] : nil;
}

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
NSMutableDictionary* itemDict = (NSMutableDictionary*)item;
NSArray* children = [self p_childrenForNode: itemDict];
return children.count > 0;
}

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
NSMutableDictionary* itemDict = (NSMutableDictionary*)item;
NSArray* children = [self p_childrenForNode: itemDict];
NSInteger retVal = children.count;
return retVal;
}

- (id)outlineView:(NSOutlineView *)pOutlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {

NSImage* icon = [item objectForKey: @"icon"];
NSString* title = [item objectForKey: @"title"];
id value = nil;

if (icon) {
[icon setSize: NSMakeSize(pOutlineView.rowHeight - 2, pOutlineView.rowHeight - 2)];
NSTextAttachment* attachment = [[[NSTextAttachment alloc] init] autorelease];
[(NSCell *)[attachment attachmentCell] setImage: icon];
NSMutableAttributedString *aString = [[[NSAttributedString attributedStringWithAttachment:attachment] mutableCopy] autorelease];
[[aString mutableString] appendFormat: @" %@", title];
value = aString;
} else {
value = title;
}

return value;
}

- (void)defineContentNSOutlineView {
// Make root object
NSMutableDictionary* rootObj = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"FINDER", @"title",
content, @"url",
nil];

id icon = [content getResourceValue: &icon forKey: NSURLEffectiveIconKey error: NULL] ? icon : nil;
if (icon)
[rootObj setObject: icon forKey: @"icon"];

// Set it
self.objects = [NSMutableArray arrayWithObject: rootObj];
}

- (void)configurationNSOutlineView {
[outlineView sizeLastColumnToFit];
[outlineView setFloatsGroupRows:NO];
[outlineView reloadData];
[outlineView expandItem:nil expandChildren:YES];
}

@end

我将整个工作示例项目发布到 GitHub .

关于objective-c - NSOutlineView 中数组枚举对象的自定义部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12145310/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com