objective c - Displaying an object hierarchy within NSOutlineView - cannot get it to work correctly, any tips? -
so, want use nsoutlineview in application display specific, lack of better name, hierarchy. explain, here's how looks in code: have protocol declares few methods used objects i'd display:
@protocol outlineviewitem <nsobject> @required -(bool)haschildren; //tells whether object has children @required -(nsinteger)numberofchildren; //returns 0 if none or number of children @required -(id)getchildren; //return nsmutablearray containing children @required -(nsstring*)getdisplayablename; //returns string displayed in nsoutlineview @end
as can guessed, these methods should make task little bit easier.
then, i've got following hierarchy of objects (all of them implement protocol) ->
main application contains 1 instance of project class, contains nsmutablearray of subproject class instances, contains nsmutablearray of subprojectitem class instances.
an example of how i'm using these protocol methods in project class (subprojects aforementioned nsmutablearray:
-(bool)haschildren{ if(subprojects == nil || [subprojects count] < 1){ return no; } return yes; } -(nsinteger)numberofchildren{ if(subprojects == nil){ return 0; } return [subprojects count]; } -(id)getchildren{ return subprojects; } -(nsstring*)getdisplayablename{ return name; }
subproject , subprojectitem classes implement these methods in similar way.
in application, i've defined main window class (projectwindow) implement nsoutlineviewdatasource , delegate protocols, , i've bound nsoutlineview's data source , delegate projectwindow.
in projectwindowclass, i've implemented methods follow:
- (id)outlineview:(nsoutlineview *)outlineview child:(nsinteger)index ofitem:(id)item { return item == nil ? project : [item getchildren]; //if understand correctly, return children of given node. //if item nil, should return root, is, project, or children of item. } - (bool)outlineview:(nsoutlineview *)outlineview isitemexpandable:(id)item { return item == nil? yes : [item haschildren]; //same above: project expendable, other nodes can expanded if contain children } - (nsinteger)outlineview:(nsoutlineview *)outlineview numberofchildrenofitem:(id)item { return item == nil? 1 : [item numberofchildren]; //same above: there's 1 project, or returns num of children; } - (id)outlineview:(nsoutlineview *)outlineview objectvaluefortablecolumn:(nstablecolumn *)tablecolumn byitem:(id)item { return item == nil ? @"root" : [item getdisplayablename]; //i think that's going displayed in nsoutlineview, next expendable arrow }
however, when try run it, i'm met following exception:
2013-08-23 22:45:12.930 myproject[1903:303] -[__nsarraym haschildren]: unrecognized selector sent instance 0x101a16f30
if understood whole nsoutlineviewdatasource, should either return root item, if requested item == nil, of children of item if item != nil. but, although i've thought it's how should be, doesn't work, , application hangs.
so, how should implement these data source methods make work intended?
- (id)outlineview:(nsoutlineview *)outlineview child:(nsinteger)index ofitem:(id)item { return item == nil ? project : [item getchildren]; //if understand correctly, return children of given node.
not of them @ once!
outlineview:child:ofitem:
takes index because it's expected return child @ index. it's supposed return 1 child @ time.
you're telling outline view array of children of project every child of project. don't think that's meant.
you want:
return item == nil ? project : item[index];
(by way, should not name variable index
. there function name, if forget or misspell variable's declaration, hilarity ensue when use index
function array index.)
- (id)outlineview:(nsoutlineview *)outlineview objectvaluefortablecolumn:(nstablecolumn *)tablecolumn byitem:(id)item { return item == nil ? @"root" : [item getdisplayablename]; //i think that's going displayed in nsoutlineview, next expendable arrow
yes, want localized string. use nslocalizedstring
around @"root"
string. better yet, move method in project, , ask item's displayable name unconditionally.
Comments
Post a Comment