Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > Table view example?

Table view example?
Thread Tools
Mac Elite
Join Date: Oct 2000
Status: Offline
Reply With Quote
May 29, 2002, 10:07 PM
 
OK, this is really what's been limiting me for a while. Does anyone know how to do a really simple table view? My objective: To have a global (I believe they're what they're called) which is an array filled with A, B, and C. Then I want to put that in a single-columned table view...

| A |
| B |
| C |

In case anyone needs a visual.. Then at any time I want to be able to pass it any array and have it be populated.. So if I just happen to have an array like X, Y, Z I want to pass it to it and have it update. again..

| A |
| B |
| C | ↓

| X |
| Y |
| Z |

No extra fluff, I won't be deleting items, doing whatever.. this is all I need to do. Keep in mind that I am a Cocoa newbie.
     
Fresh-Faced Recruit
Join Date: May 2002
Location: Ft Lauderdale
Status: Offline
Reply With Quote
May 29, 2002, 10:21 PM
 
see this article:
<a href="http://www.cocoadevcentral.com/tutorials/showpage.php?show=00000036.php" target="_blank">http://www.cocoadevcentral.com/tutorials/showpage.php?show=00000036.php</a>
You will need to implement these 2 functions
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">- (int)numberOfRowsInTableViewNSTableView *)aTableView;
- (id)tableViewNSTableView *)aTableView objectValueForTableColumnNSTableColumn *)aTableColumn</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">The first one should return [myArray count], the second should return [myArray objectAtIndex:rowIndex].
When you update the table views data source call [myTableView reloadData].
Don't forget to set the table views delegate and data source to whatever class you implement it in(in IB).
     
Synotic  (op)
Mac Elite
Join Date: Oct 2000
Status: Offline
Reply With Quote
May 30, 2002, 12:46 AM
 
OK, thanks for the response.. lemme just try to get some things cleared up.. When I put myArray in objectForValue and numberOfRows.. does this basically make myArray the data source?..

I've made MyController the delegate and data source for my table view.. so the class is is the data source? Here is my code.. prepare to cringe.. I've done very little Cocoa..

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">/* MyController */

#import &lt;Cocoa/Cocoa.h&gt;

@interface MyController : NSObject {
NSArray *myArray;
IBOutlet id mytableview;
}
- (void)tableViewSelectionDidChangeNSNotification *)aNotification;
- (int)numberOfRowsInTableViewNSTableView *)aTableView;
- (id)tableViewNSTableView *)aTableView objectValueForTableColumnNSTableColumn *)aTableColumn;
- (void)awakeFromNib;
@end</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">and then..

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#import &quot;MyController.h&quot;

@implementation MyController
- (void)tableViewSelectionDidChangeNSNotification *)aNotification {
NSLog(@&quot;selection did change&quot;
}

- (int)numberOfRowsInTableViewNSTableView *)aTableView {
return [myArray count];
}

- (id)tableViewNSTableView *)aTableView objectValueForTableColumnNSTableColumn *)aTableColumn {
return [myArray objectAtIndex:[mytableview selectedRow]];
}

- (void)awakeFromNib {
myArray = [NSArray arrayWithObjects:@&quot;A&quot;, @&quot;B&quot;, @&quot;C&quot;, nil];
}

@end</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Also, I will look at the source for the the tutorial you posted above, I'm sure it'll answer all my questions.. but just wanted to show you my code just in case anything blatantly obvious stuck out

Thanks a lot!
     
Mac Enthusiast
Join Date: Nov 2001
Status: Offline
Reply With Quote
May 30, 2002, 01:38 AM
 
Code looks good, just remember to retain the array when you in the awakeFromNib method. It should look like:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">myArray = [[NSArray arrayWithObjects:@&quot;A&quot;, @&quot;B&quot;, @&quot;C&quot;, nil] retain];</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Also remember to release it in the dealloc method:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">- (void)dealloc
{
[myArray release];
[super dealloc];
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">BTY, you have made the MyController class your data source, but that's fine. If you want to, you could add a category to NSArray and then make any array your data source. You can do this:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">@implementation NSArray (ArrayDataSource)

- (int)numberOfRowsInTableViewNSTableView *)aTableView
{
return [self count];
}

- (id)tableViewNSTableView *)aTableView objectValueForTableColumnNSTableColumn *)aTableColumn
{
return [self objectAtIndex:[aTableView selectedRow]];
}
@end</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Then just import that file (let's call it ArrayDataSource.m) and then all you need to do is set myArray as your table's data source and then you can remove the data source methods from your controller. If you do this, any array can instantly become a table's data source--it's very convenient. Also, you don't need to define any of the methods you have in your header file--they're already defined elsewhere in the AppKit's headers.

<small>[ 05-30-2002, 02:46 AM: Message edited by: Ibson ]</small>
     
Fresh-Faced Recruit
Join Date: May 2002
Location: Ft Lauderdale
Status: Offline
Reply With Quote
May 30, 2002, 01:50 AM
 
Looks alright, I don't know about [myTableView selectedRow]. Play around with it and see. Also call [myTableView reloadData] after you add items to the array in awakeFromNib.
     
Synotic  (op)
Mac Elite
Join Date: Oct 2000
Status: Offline
Reply With Quote
May 30, 2002, 02:18 AM
 
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">quote:</font><hr /><font size="1" face="Geneva, Verdana, Arial, sans-serif">Originally posted by Ibson:
<strong>Code looks good, just remember to retain the array when you in the awakeFromNib method. It should look like:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">myArray = [[NSArray arrayWithObjects:@&quot;A&quot;, @&quot;B&quot;, @&quot;C&quot;, nil] retain];</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Also remember to release it in the dealloc method:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">- (void)dealloc
{
[myArray release];
[super dealloc];
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">BTY, you have made the MyController class your data source, but that's fine. If you want to, you could add a category to NSArray and then make any array your data source. You can do this:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">@implementation NSArray (ArrayDataSource)

- (int)numberOfRowsInTableViewNSTableView *)aTableView
{
return [self count];
}

- (id)tableViewNSTableView *)aTableView objectValueForTableColumnNSTableColumn *)aTableColumn
{
return [self objectAtIndex:[aTableView selectedRow]];
}
@end</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Then just import that file (let's call it ArrayDataSource.m) and then all you need to do is set myArray as your table's data source and then you can remove the data source methods from your controller. If you do this, any array can instantly become a table's data source--it's very convenient. Also, you don't need to define any of the methods you have in your header file--they're already defined elsewhere in the AppKit's headers.</strong></font><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">OK, so if I make that ArrayDataSource.m file, I no longer need to have MyController be the data source? Or should I keep it? I also found the init method, I should probably use this rather than awakeFromNib right? Since I am doing nothing with any interface items..

So in the init method I should be something like this..

[mytableview setDataSource:myArray];

Then the "objectForValue" "numberOfRows" etc.. can all be removed from MyController? Also, should I import it through MyController.m or .h?

So now my table view and and array will be in sync? I update my array, I tell the table view to update, it updates?

Does the basic format of arrays if they are multi-columned (doesn't really pertain to this but just for future reference) the array looks like this right?

{{1, 2, 3, 4}, {5, 6, 7, 8}}

becomes..

| 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 |

right? is there any way to make it so that.. {{1, 2, 3, 4}, {5, 6, 7, 8}} turns into..

| 1 | 5 |
| 2 | 6 |
| 3 | 7 |
| 4 | 8 |

? This second question isn't really imperative.. just if any of you have time.

again.. thanks a lot this is a big help.
     
Mac Enthusiast
Join Date: Nov 2001
Status: Offline
Reply With Quote
May 30, 2002, 02:50 AM
 
If you implement the ArrayDataSource category, you can remove all data source methods from MyController. Import ArrayDataSource.m through MyController.m. You still need an awakeFromNib method, as you can't change properties of objects (your table view) that haven't been unarchived yet. So awakeFromNib should look like:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">- (void)awakeFromNib
{
myArray = [[NSArray arrayWithObjects:@&quot;A&quot;, @&quot;B&quot;, @&quot;C&quot;, nil] retain];
[mytableview setDataSource:myArray];
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">If you update your array (in which case, myArray should be an NSMutableArray), and call [mytableview reloadData], everything will be in sync. As to your second question, multi-columned table views are generally managed using NSArrays of NSDictionaries (or other custom objects). So, in IB, give your two table columns an identifier (eg if 1 column is a name of something, and the second is its description, the first column should have the identifier "Name", the second, "Description"). Then, create an array of NSDictionaries, with each dictionary having the keys "Name" and "Description" and their associated values. Eg:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">myArray = [[NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:
@&quot;Cat&quot;, @&quot;Name&quot;, @&quot;Funky, and furry.&quot;, @&quot;Description&quot;, nil],
[NSDictionary dictionaryWithObjectsAndKeys:
@&quot;Dog&quot;, @&quot;Name&quot;, @&quot;Barks a lot.&quot;, @&quot;Description&quot;, nil],
nil] retain];</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Then, in ArrayDataSource.m, do this:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">- (id)tableViewNSTableView *)aTableView objectValueForTableColumnNSTableColumn *)aTableColumn
{
return [[self objectAtIndex:[aTableView selectedRow]] objectForKey:[aTableColumn identifier]];
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">(If you wanted to, you could see whether the array's object is a string or a dictionary--ask how if you need to know).
If you implement this, the table columns will then be automatically filled with their respective values.
Hope this makes sense!
(BTY, see the excellent <a href="http://www.cocoadev.com/index.pl?SortingTableViewByColumn" target="_blank">tutorial</a> at CocoaDev for more info)

<small>[ 05-30-2002, 04:04 AM: Message edited by: Ibson ]</small>
     
Synotic  (op)
Mac Elite
Join Date: Oct 2000
Status: Offline
Reply With Quote
May 31, 2002, 09:27 PM
 
OK, I really appreciate it but I can't get it to work!?!? Frustrating to say in the least..

MyController.h:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#import &lt;Cocoa/Cocoa.h&gt;

@interface MyController : NSObject
{
IBOutlet id tableview;
NSArray *myArray;
}
- (void)awakeFromNib;
- (void)dealloc;
@end</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">MyController.m:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#import &quot;MyController.h&quot;
#import &quot;ArrayDataSource.m&quot;

@implementation MyController

- (void)awakeFromNib
{
myArray = [[NSArray arrayWithObjects:@&quot;A&quot;, @&quot;B&quot;, @&quot;C&quot;, nil] retain];
[tableview setDataSource:myArray];
}

- (void)dealloc {
[myArray release];
[super dealloc];
}
@end</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Note that it's imported..

ArrayDataSource.m:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#import &quot;MyController.h&quot;

@implementation NSArray (ArrayDataSource)

- (int)numberOfRowsInTableViewNSTableView *)aTableView
{
return [self count];
}

- (id)tableViewNSTableView *)aTableView objectValueForTableColumnNSTableColumn *)aTableColumn
{
return [self objectAtIndex:[aTableView selectedRow]];
}
@end</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">I don't have an ArrayDataSource.h.. still no luck.. although I put virtually nothing in there.

BTW, I stuck in an "import "MyController.h"" at the top because it wasn't recognizing all the table views. After all the errors are gone I get one error:

"Build failed (see build log for details)"

and the build log..

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">quote:</font><hr /><font size="1" face="Geneva, Verdana, Arial, sans-serif">/usr/bin/jam -d1 JAMBASE=/Developer/Makefiles/pbx_jamfiles/ProjectBuilderJambase JAMFILE=- build ACTION=build _DEFAULT_GCC_VERSION=2.95.2 _GCC3_IS_IN_OFFICIAL_LOCATION=YES BUILD_STYLE=Development "CPP_HEADERMAP_FILE=/Users/synotic/Cocoa Table/build/Cocoa Table.build/Cocoa Table.build/Cocoa Table.hmap" "SRCROOT=/Users/synotic/Cocoa Table" "OBJROOT=/Users/synotic/Cocoa Table/build" "SYMROOT=/Users/synotic/Cocoa Table/build" "DSTROOT=/tmp/Cocoa Table.dst"
...updating 13 target(s)...
Cp /Users/synotic/Cocoa Table/build/Cocoa Table.app/Contents/PkgInfo
BuildPhase &lt;CopyResources&gt;Cocoa Table.app
Completed phase &lt;CopyResources&gt; for &lt;CopyResources&gt;Cocoa Table.app
CompileC /Users/synotic/Cocoa Table/build/Cocoa Table.build/Cocoa Table.build/Objects-normal/ppc/MyController.o
CompileC /Users/synotic/Cocoa Table/build/Cocoa Table.build/Cocoa Table.build/Objects-normal/ppc/ArrayDataSource.o
BuildPhase &lt;DeriveAndCompileSources&gt;Cocoa Table.app
Completed phase &lt;DeriveAndCompileSources&gt; for &lt;DeriveAndCompileSources&gt;Cocoa Table.app
MasterObjectFile.Combine /Users/synotic/Cocoa Table/build/Cocoa Table.build/Cocoa Table.build/Objects-normal/ProjectBuilderMasterObjectFile.o
/usr/bin/ld: multiple definitions of symbol .objc_category_name_NSArray_ArrayDataSource
/Users/synotic/Cocoa Table/build/Cocoa Table.build/Cocoa Table.build/Objects-normal/ppc/MyController.o definition of absolute .objc_category_name_NSArray_ArrayDataSource (value 0x0)
/Users/synotic/Cocoa Table/build/Cocoa Table.build/Cocoa Table.build/Objects-normal/ppc/ArrayDataSource.o definition of absolute .objc_category_name_NSArray_ArrayDataSource (value 0x0)

/usr/bin/c++ -arch ppc -keep_private_externs -nostdlib -filelist "/Users/synotic/Cocoa Table/build/Cocoa Table.build/Cocoa Table.build/Objects-normal/LinkFileListPrelink" -r -o "/Users/synotic/Cocoa Table/build/Cocoa Table.build/Cocoa Table.build/Objects-normal/ProjectBuilderMasterObjectFile.o"

...failed MasterObjectFile.Combine /Users/synotic/Cocoa Table/build/Cocoa Table.build/Cocoa Table.build/Objects-normal/ProjectBuilderMasterObjectFile.o ...</font><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Any ideas?
     
Mac Enthusiast
Join Date: Nov 2001
Status: Offline
Reply With Quote
Jun 1, 2002, 02:53 AM
 
OK, this should be the contents of each file:

a) MyController.h:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#import &lt;Cocoa/Cocoa.h&gt;

@interface MyController : NSObject
{
IBOutlet NSTableView *tableview;
NSArray *myArray;
}
@end</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">A hint: in IB, you should define what class each outlet is. That is, when you created the tableview outlet, define it as an NSTableView. Then change your header to like it is above. It just makes everything a little nicer and lets the compiler do better checking. You don't need to define awakeFromNib and dealloc, as they're already defined in the Cocoa headers.
b) MyController.m:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#import &quot;MyController.h&quot;
#import &quot;ArrayDataSource.h&quot;

@implementation MyController

- (void)awakeFromNib
{
myArray = [[NSArray arrayWithObjects:@&quot;A&quot;, @&quot;B&quot;, @&quot;C&quot;, nil] retain];
[tableview setDataSource:myArray];
}

- (void)dealloc
{
[myArray release];
[super dealloc];
}

@end</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">c) ArrayDataSource.h:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#import &lt;AppKit/AppKit.h&gt;

@interface NSArray (ArrayDataSource)
- (int)numberOfRowsInTableViewNSTableView *)aTableView;
- (id)tableViewNSTableView *)aTableView objectValueForTableColumnNSTableColumn *)aTableColumn rowint)rowIndex;
@end</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">d) ArrayDataSource.m:
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#import &quot;ArrayDataSource.h&quot;

@implementation NSArray (ArrayDataSource)

- (int)numberOfRowsInTableViewNSTableView *)aTableView
{
return [self count];
}

- (id)tableViewNSTableView *)aTableView objectValueForTableColumnNSTableColumn *)aTableColumn rowint)rowIndex
{
return [self objectAtIndex:rowIndex];
}
@end</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">I guarantee that will compile properly --last night I had just copy-and-pasted your and changed it a bit--I don't know how objectAtIndex:[aTableView selectedRow] snuck in (it was late).

<small>[ 06-01-2002, 03:56 AM: Message edited by: Ibson ]</small>
     
Synotic  (op)
Mac Elite
Join Date: Oct 2000
Status: Offline
Reply With Quote
Jun 1, 2002, 04:11 PM
 
OK, now everything works perfectly, even updating, thanks a lot I wish this was hte only problem I was facing though.. more will be in a different topic.
     
   
Thread Tools
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Top
Privacy Policy
All times are GMT -5. The time now is 01:16 PM.
All contents of these forums © 1995-2011 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.7 © 2000-2011, Jelsoft Enterprises Ltd., Content Relevant URLs by vBSEO 3.3.2