Cocoa
Creating a sortable NSTableView in under five
minutes.
(null)/(null)/(null) (null) |
Permalink
Ok, the Uncle
Mac thing has prompted me to write this
quick and simple tutorial on creating a sortable
table view in Cocoa.
Note, for this example I am going to use bindings, mostly because I could really see no reason not to. Now, I know this is a bit of a newbie topic and it's probably covered better and in more depth elsewhere, but everyone's a n00b at something and I don't think google is in danger of running out of places to index stuff anytime soon.
Note, for this example I am going to use bindings, mostly because I could really see no reason not to. Now, I know this is a bit of a newbie topic and it's probably covered better and in more depth elsewhere, but everyone's a n00b at something and I don't think google is in danger of running out of places to index stuff anytime soon.
So, what we are going to build is a simple application that populates a table column with random numbers, the column will be sortable by clicking on the column header (default behavior for OS X). The intention is to show how easily this can be achieved using Cocoa/Objective-C and not as an introduction to the Objective-C language or the Cocoa Frameworks.
The first thing to do is create a new XCode Cocoa project. So, in XCode we choose File from the menu, then New Project... and from the list pick 'Cocoa Application'. Give it a suitable name (e.g. Sort Columns).
XCode will create most of the stuff we'll need to get going, in fact if you click on 'Build and Go' you'll see an empty window and the menu for your new application appear. You should notice that it already has quite a bunch of functionality, try choosing Print from the File menu of your Application...
Neat, eh? Right, now lets get our hands dirty with some code - don't worry though there's, like, 20 lines of it.
We'll need to create a class that represents our data, in this case a number. When it is created it will be populated by random and will have two methods; one to get the value of the number and one to change it. These types of methods are commonly called accessors or mutators, as they allow you to access or change the data stored in a class.
Create a class in XCode by chosing File-> New File... and then selecting Objective-C Class from the list of file types. Call it TableThing.
You'll see XCode has created two files,
TableThing.h the interface and
TableThing.m the implementation.
Change
TableThing.h to read:
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
@interface TableThing : NSObject {
float aNumber;
}
-(float)aNumber;
-(void)setANumber: (float)newNumber;
@end
And TableThing.m to read:
#import "TableThing.h"
@implementation TableThing
-(id)init{
[super init];
[self setANumber: (random() % 100) + 1];
return self;
}
-(float)aNumber;{
return aNumber;
}
-(void)setANumber: (float)newNumber;{
aNumber = newNumber;
}
-(void)dealloc{
[super dealloc];
}
@end
That's all the code we're going to write. With the new properties shortcuts in Objective-C 2.0 even this will be reduced. Next, we'll plumb in the UI, in your XCode project there will be a file called MainMenu.nib, double click it to open it in Interface Builder.
Once in Interface Builder open the Window and add the following controls to it, an NSTableView and two NSButton instances. (I also added a label for clarity.)
Once your window looks something like this we can wire it all together. The next thing to do is to drag an NSArrayController into the MainMenu.nib window, as shown below.
Now we'll need to set the NSArrayController up to actually control something, in our example it'll control an array of TableThing objects, so in order to set it up to do that we need to set the Class Name and Keys in the NSArrayController's inspector. To pull up the inspector select the controller and press Option-Shift and 'i', set the Class Name to TableThing and add a key for the aNumber property of the TableThing class as shown below.
Ok, now we can wire in the buttons. You can do this by ctrl-dragging from the button to the NSArray controller.
Set the Target/Action for the 'new' button to '
insert' and do the same for the
'remove' button but set it's target to
'remove'.
Next double click on the table column itself and pull up it's inspector (option-shift-i) and in the bindings pane set the value settings as below -
There, nearly done. Now there's just sorting to add, this is implemented in it's entirety in the Attributes pane of the NSTableColumn Inspector.
That's it! Build and run the application, press 'new' a few times to fill up the table with random numbers and then sort them by clicking on the title bar of the column.
To get this working even more quickly, you can download the source here.
I hope this post demonstrates how easy it is to get going with Cocoa development and how much functionality you simply get 'For Free' using it. For the sake of brevity I deliberately wrote a lot on the 'how's and not much on the 'why's and 'what's of what we were doing, however, if this is something people are interested in I could quite happily write a few more in-depth tutorials.
|
Uncle Mac takes a cup of cold cocoa?
(null)/(null)/(null) (null) | Permalink
Someone emailed me a link to this blog post today.
http://www.regdeveloper.co.uk/2006/12/29/grumpy_old_man_on_cocoa/
Now, before I start. Fair play to the guy, he's obviously new to Mac development (so welcome) and he's trying to write something and I can't knock him for that.
What I am somewhat nonplussed about is that he's decided to write a fairly damning blog post about the Cocoa frameworks and the XCode tools without really appearing to have taken the trouble to understand some of the basics.
So, in the hope that he (or you) finds some of this useful, I'd like to address some of his criticisms and comments.
Firstly, he starts by stating that "Cocoa objects don’t actually have properties" but then, somewhat confusingly adds, "Of course, we Delphi and C# developers understand that a property is usually just syntactic sugar-coating around a method call, right?"
Ok, I can see where you're coming from, us Java/Objective C developers also understand that. The 'syntatcic sugar coating' as he puts it is coming in Objective C 2.0, but really it's not an issue (at least for me). Follow the same rules as you would for any other language (including C#) i.e. writing getters and setters and you'll be ok and you'll also get the many 'for free' benefits of Key-Value Coding.
One such benefit is the ability to use Cocoa Bindings. I suspect that the author wasn't aware of Bindings (despite "[reading] three Cocoa programming books"). But really, using them would have solved a lot of his problems (writing array controllers, sorting columns in a table)
Plus, using Bindings you get a load of doohickeys that you can tick in the Inspector which look a whole lot like those things he was just moaning that there weren't any of (I won't call them properties, but I'm thinking of tick boxes with descriptions like 'Allows Editing Multiple Values' and so on).
"Imagine being able to drop a pushbutton control onto a form, double-click it and – bang! – there you are in the code editor, with an insertion caret inside your event handler." Nooooooo! I can imagine this. I've seen it, in Visual Basic and C#. I've also seen 'event handlers' performing most of the application logic.
Don't like it.
Imagine instead, a proper OO approach where you can assign selectors dynamically at runtime, use delegates to modify the behavior of the UI, send messages to any object willing to listen to them and retain the context of where they've come from. Like it or not, the UI is kind of separate from the rest of your code if you're using the Model, View, Controller pattern which is kind of enforced by the Cocoa approach (as well as other frameworks such as Rails) and is generally considered a good thing™
The other good thing™ about it is that, as sometimes happens, I can send just a .NIB file away to be localized or redesigned.
But seriously, if the VB.net/C# code/form designers are so good why are they all being replaced with WPF? Come on, they suck, really.
Oh, and I'm no Microsoft Hater :)
"But I really think that if the average Cocoa programmer spent some time with Delphi, s/he’d be totally blown away" I've spent some time with a Delphi developer, does that count?
http://www.regdeveloper.co.uk/2006/12/29/grumpy_old_man_on_cocoa/
Now, before I start. Fair play to the guy, he's obviously new to Mac development (so welcome) and he's trying to write something and I can't knock him for that.
What I am somewhat nonplussed about is that he's decided to write a fairly damning blog post about the Cocoa frameworks and the XCode tools without really appearing to have taken the trouble to understand some of the basics.
So, in the hope that he (or you) finds some of this useful, I'd like to address some of his criticisms and comments.
Firstly, he starts by stating that "Cocoa objects don’t actually have properties" but then, somewhat confusingly adds, "Of course, we Delphi and C# developers understand that a property is usually just syntactic sugar-coating around a method call, right?"
Ok, I can see where you're coming from, us Java/Objective C developers also understand that. The 'syntatcic sugar coating' as he puts it is coming in Objective C 2.0, but really it's not an issue (at least for me). Follow the same rules as you would for any other language (including C#) i.e. writing getters and setters and you'll be ok and you'll also get the many 'for free' benefits of Key-Value Coding.
One such benefit is the ability to use Cocoa Bindings. I suspect that the author wasn't aware of Bindings (despite "[reading] three Cocoa programming books"). But really, using them would have solved a lot of his problems (writing array controllers, sorting columns in a table)
Plus, using Bindings you get a load of doohickeys that you can tick in the Inspector which look a whole lot like those things he was just moaning that there weren't any of (I won't call them properties, but I'm thinking of tick boxes with descriptions like 'Allows Editing Multiple Values' and so on).
"Imagine being able to drop a pushbutton control onto a form, double-click it and – bang! – there you are in the code editor, with an insertion caret inside your event handler." Nooooooo! I can imagine this. I've seen it, in Visual Basic and C#. I've also seen 'event handlers' performing most of the application logic.
Don't like it.
Imagine instead, a proper OO approach where you can assign selectors dynamically at runtime, use delegates to modify the behavior of the UI, send messages to any object willing to listen to them and retain the context of where they've come from. Like it or not, the UI is kind of separate from the rest of your code if you're using the Model, View, Controller pattern which is kind of enforced by the Cocoa approach (as well as other frameworks such as Rails) and is generally considered a good thing™
The other good thing™ about it is that, as sometimes happens, I can send just a .NIB file away to be localized or redesigned.
But seriously, if the VB.net/C# code/form designers are so good why are they all being replaced with WPF? Come on, they suck, really.
Oh, and I'm no Microsoft Hater :)
"But I really think that if the average Cocoa programmer spent some time with Delphi, s/he’d be totally blown away" I've spent some time with a Delphi developer, does that count?