【问题标题】:Cocoa Programming, setting the delegateCocoa 编程,设置委托
【发布时间】:2012-03-15 11:41:42
【问题描述】:

我正在从 iOS 转向 Cocoa,并试图应付我最初的几个程序。我认为在我的表单中添加NSComboBox 会很简单,那部分就是。我在界面中添加了<NSComboBoxDelegate, NSComboBoxDataSource>、两个数据回调和通知器:

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

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

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

@end

我控制将组合框拖到应用程序委托(这是我的简单默认应用程序中的唯一类)并连接了委托和数据源,但这些事件都没有触发。我认为应用程序委托是正确的,但由于它没有触发,我也尝试了“文件所有者”和“应用程序”。我不认为那些会奏效,但他们没有。

在 Cocoa 应用程序中为 NSComboBox 连接代理/数据源的正确方法是什么?

谢谢!

【问题讨论】:

  • 当你说“它没有触发”时,你在做什么来测试它?调试器中的断点? NSLog?
  • “没有触发”是指我添加了委托方法并在其中设置了一个未达到的断点。您可能认为这两个数据方法未达到但comboBoxSelectionDidChange 应该可以访问是有道理的。再次是我的错,因为我错误地连接了该事件。所以我实际上有两个问题,但主要的解决方法是意识到有一个(新的?)复选框来表明我正在使用数据源。谢谢:)

标签: objective-c xcode cocoa interface-builder


【解决方案1】:

如果您已经在 spcAppDelegate.m 文件中实际实现了这些方法,您可能需要在 Interface Builder 的 nib 文件中仔细检查 Uses Data Source 是否已检查 NSComboBox

请注意,在我创建的快速测试项目中默认情况下没有设置它。当您启动应用程序时,如果不设置该复选框运行,则应将以下内容记录到控制台:

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

虽然NSComboBox Class Reference 有点帮助,但当我第一次学习时,我发现如果有与课程相关的配套指南,那么这些指南对于理解如何在实践中使用课程更有帮助。如果您查看 Companion GuideNSComboBox 类参考的顶部,您会看到 Combo Box Programming Topics

要设置使用数据源的组合框,您可以使用以下内容:

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

示例项目:http://github.com/NSGod/NSComboBox.

【讨论】:

  • 非常感谢。它是“使用数据源”。我做了几乎一切正确:)
  • 感谢您提供所有详细信息!超级有用
  • 令人难以置信的令人沮丧的是,即使在 OS 10.11 和 Xcode 8 中,如果您不选中 Xib 中的复选框,它也将无法工作——即使您以编程方式设置了 comboBox.usesDataSource = true
【解决方案2】:

我昨天遇到了类似的情况,直到我记得将文件所有者数据源连接到 IB 中的 IBOutlet:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 2011-05-19
    相关资源
    最近更新 更多