Personalizing NSTableView in three ways
-
19-12-2020 - |
Question
I'd like to use an NSTableView for displaying a list of disks to the user and I think it would be better to display them a bit differently than the normal NSTableView does. Here is an image as example:
The features I'd like are these:
- Thicker rows (just like this one)
- The nice gradient used for selection, instead of the normal colors
- One image on the left (the drive's icon) and the text on the right (it's name), but using only one column (with a name like "Available Disks")
I am specially reluctant to do the third as I think it will envolve doing my own cell subclass and drawing the text and image myself, which I have NO clue how to do :(
The other ones I reckon they will not be that difficult once someone points me in the right direction...
PS: The image is from Xcode 4 in the preferences.
Solution 2
Alright! I have found how all these three things can be done:
- You can change the row thickness in IB
- That nice gradient you can also be done in IB by changing "Highlight" to "Source List" instead of "Regular"
Now for the third I did something a wee bit differently than I said I wanted:
- In IB I checked "Headers" off, so using two columns is possible without the user knowing it
- The first column I put an image cell, while on the second I put a text cell
- Then, because I had changed the height of the rows, I noticed NSTextViewCell doesn't vertically align the text, nor does it have options for that, which means I ended up having a NSTextViewCell subclass for centering the text. Here it is:
`
@interface ACTCenteredTextFieldCell : NSTextFieldCell
{
}
@end
@implementation ACTCenteredTextFieldCell
- (NSRect)titleRectForBounds: (NSRect)theRect {
NSRect titleFrame = [super titleRectForBounds: theRect];
NSSize titleSize = [[self attributedStringValue] size];
titleFrame.origin.y = theRect.origin.y + (theRect.size.height - titleSize.height) / 2.0;
return titleFrame;
}
- (void)drawInteriorWithFrame: (NSRect)cellFrame inView: (NSView*)controlView {
NSRect titleRect = [self titleRectForBounds: cellFrame];
[[self attributedStringValue] drawInRect: titleRect];
}
@end
There! Worked fine for me so far!
OTHER TIPS
You could use an NSCollectionView, and design a custom NSView that would be used for your rows, although see this question and answers for some cavets with XCode 4.