简体   繁体   中英

Cocoa Programming, setting the delegate

I'm moving on from iOS to Cocoa and trying to muddle through my first few programs. I thought it would be simple to add an NSComboBox to my form, well that part was. I added <NSComboBoxDelegate, NSComboBoxDataSource> to my interface, two data callbacks, and the notifier:

@interface spcAppDelegate : NSObject <NSApplicationDelegate,
                      NSComboBoxDelegate, NSComboBoxDataSource>

- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index;
- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox;

- (void)comboBoxSelectionDidChange:(NSNotification *)notification;

@end

I control dragged the combobox to the app delegate (which is the only class in my simple default app) and wired up the delegate and data source but none of those events fire. I thought app delegate was correct but since it didn't fire, I also tried "file owner" and "application". I didn't think those would work and they didn't.

Whats the right way to wire up the delegate/data source for an NSComboBox in a Cocoa app?

Thanks!

Provided you've actually implemented those methods in your spcAppDelegate.m file, you may want to double-check that Uses Data Source is checked for the NSComboBox in the nib file in Interface Builder:

在此输入图像描述

Note that it wasn't set by default in a quick test project I created. Running without that checkbox set should log the following to console when you launch the app:

NSComboBox[2236:403] *** -[NSComboBox setDataSource:] should not be called when
          usesDataSource is set to NO
NSComboBox[2236:403] *** -[NSComboBoxCell setDataSource:] should not be called 
             when usesDataSource is set to NO

While the NSComboBox Class Reference is somewhat helpful, when I was first learning, I found that if there were companion guides linked to for a class, those were much more helpful in understanding how one should use the class in practice. If you look at the top of the NSComboBox class reference at the Companion Guide , you'll see Combo Box Programming Topics .

To set up a combo box that uses a data source, you could use something like the following:

spcAppDelegate.h:

#import <Cocoa/Cocoa.h>

@interface spcAppDelegate : NSObject <NSApplicationDelegate,
                  NSComboBoxDelegate, NSComboBoxDataSource> {
    IBOutlet NSWindow            *window;
    IBOutlet NSComboBox            *comboBox;
    NSMutableArray                *comboBoxItems;
}

@property (assign) IBOutlet NSWindow *window;

@end

spcAppDelegate.m:

#import "spcAppDelegate.h"
@implementation spcAppDelegate
@synthesize window;
- (id)init {
    if ((self = [super init])) {
        comboBoxItems = [[NSMutableArray alloc] initWithArray:
               [@"Cocoa Programming setting the delegate"
                                        componentsSeparatedByString:@" "]];
    }
    return self;
}
- (void)dealloc {
    [comboBoxItems release];
    [super dealloc];
}
- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox {
    return [comboBoxItems count];
}
- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index {
    if (aComboBox == comboBox) {
        return [comboBoxItems objectAtIndex:index];
    }
    return nil;
}
- (void)comboBoxSelectionDidChange:(NSNotification *)notification {
    NSLog(@"[%@ %@] value == %@", NSStringFromClass([self class]),
      NSStringFromSelector(_cmd), [comboBoxItems objectAtIndex:
        [(NSComboBox *)[notification object] indexOfSelectedItem]]);

}
@end

Sample Project: http://github.com/NSGod/NSComboBox .

I was having a similar situation yesterday until I remembered to hook up the File Owner data source to the IBOutlet in IB:

在此输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM