2012-08-27 8 views
6

में सरणी की गणना की गई वस्तुओं के लिए कस्टम अनुभाग सूचीबद्ध वस्तुओं के लिए कस्टम हेडर समूह (पैरेंट नोड) के साथ एक NSOutlineVew बनाने की कोशिश कर रहा हूं। (नोट: मेरे पास सेल-आधारित NSOutlineView है)। उदाहरण के लिए यह एक्सकोड "नेविगेटर" या नंबर साइडबार जैसा दिखता है। मैंने प्रति वर्ग अलग-अलग गुणों के लिए डिफ़ॉल्ट समूह का उपयोग किया, लेकिन ऐसा लगता है कि मैं क्या चाहता हूं। मुझे एक पैरेंट नोड (सेल) की आवश्यकता है, जिसे मैं दृष्टि से समायोजित कर सकता हूं (नियंत्रण तत्व और छवि जोड़ें)।NSOutlineView

मैंने NSDictionary को ऑब्जेक्ट्स की एक सरणी पास करके ऐसा करने का प्रयास किया, जिससे प्रत्येक समूह को एक निश्चित विशिष्ट कुंजी दी गई। और नतीजतन, एनएसएलओजी के माध्यम से सबकुछ ठीक से प्रदर्शित होता है, लेकिन इस चर के हस्तांतरण को NSOulineView प्रोग्राम के स्रोत के रूप में स्थानांतरित करने में विफल रहता है।

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

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 

आसान करने के लिए यह कैसा दिखेगा कल्पना कर सकते हैं, मैं यह योजना पर पता चला

और अब मेरे पास क्या है (NSOulineView NSTreeController का उपयोग किए बिना);

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

मैं उदाहरण एप्पल "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]; 
} 

इस विधि प्रदर्शित करता है केवल पहले वस्तुओं, के रूप में यह बाद योजना पर दिखाया गया है।

और एक और सवाल, जैसा कि मैंने पहले कहा था, सेल के दाईं ओर नोड ** "फाइडर फाइल" ** बटन में कैसे जोड़ें।

क्या आप इससे मेरी सहायता कर सकते हैं? मुझे पता है, शायद इतना कठिन नहीं है, लेकिन मैंने अभी उद्देश्य-सी सीखना शुरू किया और मुझे नहीं पता कि यह कैसे करें। धन्यवाद।

+0

मुझे एहसास है कि यह शायद पूरी तरह से सहायक नहीं है, लेकिन मुझे संदेह है कि आपको NSView- आधारित NSOutlineView (बनाम एनएससीएल-आधारित) के साथ पूरा करना अधिक आसान लगेगा। कारण-आधारित NSOutlineViews के साथ, आप किसी भी संख्या में सबव्यूव जोड़ सकते हैं और अपनी सभी मानक कार्यक्षमता बरकरार रख सकते हैं। सेल-आधारित दृष्टिकोण के साथ आप एक ही सेल के साथ फंस जाएंगे, और इसे कई नियंत्रणों के व्यवहार को गठबंधन करने में एक कस्टम एनएससीएल सबक्लास और कस्टम ड्राइंग और इवेंट हैंडलिंग कोड के बहुत सारे लेखन शामिल होंगे। व्यू-आधारित NSOutlineView आपको मुफ्त में देगा। – ipmcc

उत्तर

1

आपके द्वारा प्रदान किए गए प्रारंभिक कोड के आधार पर, मैं सेल-आधारित NSOutlineViews का उपयोग करके कुछ काम करने में सक्षम था। आपके द्वारा पोस्ट किया गया कोड अधूरा लग रहा था, इसलिए यह जानना मुश्किल था कि आप लापता FSENTITY वर्ग से बाहर निकलना चाहते थे। मैंने सिर्फ नींव वर्गों का उपयोग किया: नोड्स (यानी रूट नोड्स और बच्चों) की सूची के लिए एनएसएआरएआरई, प्रत्येक नोड के लिए एनएसडीयूज (रूट नोड्स और सब-नोड्स दोनों), और NSURLs फ़ाइल-सिस्टम संदर्भ के रूप में। मैंने जितना संभव हो सके अपने मूल कोड के करीब रहने की कोशिश की। अंत में, यह कुछ इस तरह देखा:

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 के लिए नमूना परियोजना काम कर रहे।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^