Equivalent to a "ListBox" in XCode?

Viewed 5911

You know Visual Studio, that awesome element called "ListBox"? Just a box that would list a bunch of strings.

I am now working with XCode, and I found this class in the interface builder "NSScrollView". It seems to be able to list me a couple strings. It says it got a NSTextView inside, but, how do I access it?

I am not even sure if NSScrollView is the correct solution I need, but if I could simply access the NSTextView inside it, I think it would be enough.

3 Answers

Josh's answer above to use NSTableView is correct. For those not that familiar with it, it can seem like a much bigger task than it actually turns out to be. Hopefully this saves people some time.

Rather than fight with NSTableCellView assumptions, you can create any type of simple view you want and use auto layout (or even return a simple NSTextView. This is what I did to get more control over layout of my text strings:

@interface PreferenceTableViewCell : NSView
@property (nonnull, strong, readonly) NSTextField *tf;
@end

@implementation PreferenceTableViewCell
-(id)init
{
    self = [super init];
    if(self) {
        self.translatesAutoresizingMaskIntoConstraints = NO;
        self.autoresizesSubviews = YES;
        _tf = [NSTextField labelWithString:@""];
        _ tf.translatesAutoresizingMaskIntoConstraints = NO;
        _tf.autoresizesSubviews = YES;
        [self addSubview:_tf];
        [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[_tf]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_tf)]];
        [self addConstraint:[NSLayoutConstraint constraintWithItem:_tf attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
    }
    return self;
}
@end

Then put this whereever you need the list of strings (or controls, or whatever):

_tv = [NSTableView new];
_tv.translatesAutoresizingMaskIntoConstraints = NO;
_tv.autoresizesSubviews = YES;
_tv.focusRingType = NSFocusRingTypeNone;
_tv.delegate = self;
_tv.dataSource = self;
_tv.rowHeight = 40; // Use this to adjust the height of your cell or do it in cell.
_tv.headerView = nil;
_tv.selectionHighlightStyle = NSTableViewSelectionHighlightStyleRegular;
_tv.allowsColumnReordering = NO;
_tv.allowsColumnResizing = NO;
_tv.allowsEmptySelection = NO;
_tv.allowsTypeSelect = NO;
_tv.gridStyleMask = NSTableViewGridNone;
[panel addSubview:_tv];

// TableView Column
NSTableColumn *col1 = [[NSTableColumn alloc] initWithIdentifier:@"c1"];
col1.resizingMask = NSTableColumnAutoresizingMask;
[_tv addTableColumn:col1];

Then in whatever is set as the delegate and datasource for the NSTableView add these methods:

-(NSInteger)numberOfRowsInTableView:(NSTableView *)tv
{
   return stringArray.count;
}

-(NSView *)tableView:(NSTableView *)tv viewForTableColumn:(NSTableColumn *)tc row:(NSInteger)row
{
    // This can be ANY NSView based control built as shown above.
    PreferenceTableViewCell *cell = [PreferenceTableViewCell new];
    cell.tf.stringValue = stringArray[row];        
    return cell;
}

-(void)tableViewSelectionDidChange:(NSNotification *)notification
{
    // Code to do whatever when a list item is selected.
}

That is basically it for a simple list. See the Apple Docs on NSTableView for more details on how to bind the table to a data sources and more complicated problems.

Related