2012-08-27 3 views
6

リストされたオブジェクトのカスタムヘッダーグループ(親ノード)を使用してNSOutlineVewを作成しようとしています。 (注:私はセルベースのNSOutlineViewを持っています)。例えば、Xcode "Navigator"やNumbersのサイドバーのように見えます。カテゴリごとに分離プロパティのデフォルトグループを使用しましたが、それは私が望むものではないようです。親ノード(セル)が必要です。視覚的に調整できます(コントロールの要素と画像を追加します)。NSOutlineViewの配列の列挙されたオブジェクトのカスタムセクション

オブジェクトの配列を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        | 
       +--------------------------------------------+ 

と私が今持っているもの(NSOulineView NSTreeControllerを使わないで);

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

(階層の最初の要素を私は例Appleの「SourceView」について知っているが、私は、作成したグループにオブジェクト(ファイルとフォルダ)の配列を追加する方法がわからない、NSTreeContoller表示SourceView例の

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

修飾方法:)を含むことなく、後者の方式でそれを示すように

- (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]; 
} 

この方法は、最初のオブジェクトが表示されます。

もう1つの質問は、前にも述べましたが、ノードの右側に「FINDER FILES」**ボタンを追加する方法です。

これを手伝ってもらえますか?私は知っている、おそらくそれほど難しいわけではないが、私はObjective-Cを学び始めたばかりで、これをどうやって行うのか分からない。ありがとう。

+0

私はこれが完全に役に立つとは思えませんが、NSViewベースのNSOutlineView(NSCellベース)と比較してこれをはるかに簡単に実行できることがわかります。その理由は、ビューベースのNSOutlineViewsでは、任意の数のサブビューを追加して、すべての標準機能を保持できるからです。セルベースのアプローチでは、1つのセルに拘束され、複数のコントロールの動作を組み合わせるには、カスタムNSCellサブクラスとたくさんのカスタム描画とイベント処理コードを記述する必要があります。ビューベースのNSOutlineViewは無料でそれを提供します。 – ipmcc

答えて

1

提供された開始コードに基づいて、CellベースのNSOutlineViewsを使用して、何かを得ることができました。投稿したコードは不完全なようでしたので、欠けているFSEntityクラスから正確に何を取得したいのか分かりませんでした。私はちょうど基礎クラスを使いました:ノードのリスト(ルートノードと子)のためのNSArray、各ノード自身のためのNSDictionaries(ルートノードとサブノードの両方)、NSURLをファイルシステム参照として使用しました。私はできるだけあなたの元のコードの近くにとどまっていました。私はGitHubにサンプルプロジェクトを作業し、全体を掲載

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 

:最後に、それはこのようなものを見ました。

関連する問題