在不同的班级中调用IBAction

时间:2011-06-10 18:40:41

标签: cocoa nsdocument ibaction

我的基于文档的应用程序有一个带有tableview的窗口。 tableview有一个数据源,它指向一个类型为NSObject的类(称为HopBill),它包含一个NSMutableArray(aHopBill)和所需的tableview方法。到目前为止一切都很好。

为了向tableview添加行,我添加了一个由NSWindowController(称为HopBillSheetController)控制的工作表。按下工作表中的确定按钮。我实际上需要做两个IBAction(这是不可能的):将行添加到tableview的数组并关闭工作表。我可以将工作表中的OK按钮连接到NSWindowController(关闭工作表)或将其连接到NSObject(将行添加到数组)。但我想要两个: - )

是否可以从NSObject调用NSWindowController中的IBAction?还是有另一种方法可以做到这一点吗?

我是Cocao和Objective-C的初学者,所以请保持温柔: - )

2 个答案:

答案 0 :(得分:1)

如果您的工作表是带有NSPanel的nib / xib,则关闭它的调用只是[panel close];假设您的窗口控制器具有面板的属性,您可以将关闭代码放在其行的末尾 - 添加IBAction。或者,如果您愿意,您可以让IBAction本身调用另一种方法。

如果您的面板正在运行模态,您可能还需要stopModal。 (如果在小组关闭后一切都保持冻结,那就是所需要的;否则不要紧。)

假设您的数据源hopBill是窗口控制器的属性,您在窗口控制器中编写的任何IBAction也可以访问hopBill;它可以做你需要的一切。

因此,将一个IBAction添加到窗口控制器并将面板的OK按钮连接到它。这应该有用。

至于从笔尖中的控件以外的地方调用IBAction,是的,你可以这样做。使用对控件的引用作为发送者arg,如果IBAction不使用发送者arg,则使用nil。

您也可以通过编程方式创建面板,或使用NSAlert。但听起来你的当前设置更简单 - 因此更好。


看看这个h文件的app控制器:Apple's ClockControl example

NSMutableArray * appointmentments属性是NSTableViewDataSource协议方法将使用的实际数据源。 IBAction“addAppointment”可以直接访问“约会”:[self.appointments addObject:无论atIndex:无论如何];

可以修改ClockControl示例以使用HopBill。您可以将其声明导入顶部:#import“HopBill.h”然后它将声明HopBill * hopBill而不是“appointmentments”属性。并且“addApointment”会像这样访问HopBill的可变数组(aHopBill):[self.hopBill.aHopBill addObject:无论atIndex:无论如何];

答案 1 :(得分:0)

为什么你不能向hopBill发送消息:

首先,因为虽然你声明它,但你永远不会初始化它。你有:

HopBill *hopBill;
[self.hopBill.aHopBill addObject: bHopAdditionAtInit];

应该是:

HopBill *hopBill = [[HopBill alloc] init];
[hopBill.aHopBill addObject: bHopAdditionAtInit]; // “self” won’t work here

其次,你在内部中声明了一个IBAction方法(doneHopBillSheet :),所以它是一个局部变量,只能在该方法中访问。如果HopBill持有表的数据源缓存,它应该是控制器的一个属性,它实现了NSTableViewDataSourceProtocol方法。

在HopBill界面中,将aHopBill数组声明为属性,并在HopBill的init方法中初始化它(您还应该在HopBill的dealloc方法中释放它)。你需要为控制器做同样的事情 - 它应该有一个HopBill实例作为属性,并且该实例应该在控制器的init方法中初始化。

如果您希望HopBillController管理tableview,其接口声明应如下所示:

@interface HopBillSheetController : NSWindowController <NSTableViewDelegate, NSTableViewDataSource> {
…
}

然后,当然,您必须实现相关的NSTableViewDelegate和NSTableViewDataSource方法。

此外,控制器必须具有tableview本身的IBOutlet属性,并且在控制器的awakeFromNib方法中,它必须将自己指定为委托和数据源:

[self.tableview setDelegate:self];
[self.tableview setDataSource:self];

(自我点语法假定您已经为tableview设置了@property和@synthesize代码。)

向表中添加项的IBAction方法必须位于该控制器类中,或者位于具有属性的类中,该属性是控制器类的实例。然后IBAction方法可以访问aHopBill数组并可以将新对象添加到数组中,之后它将调用[tableView reloadData],这将依次触发tableview协议方法并更新表。

现在,这意味着包含tableview的xib必须将控制器作为其文件的所有者。由于您正在使用NSDocument,我怀疑您将把tableview出口放在NSDocument子类中。你会给该doc子类一个属性,它是控制器的一个实例。 IBAction方法也可以在doc子类中,因此他们可以访问控制器及其HopBill属性。或者您可能只是将doc子类设为控制器,而不是使用单独的HopBillSheetController类。我不确定NSDocument的东西。但是,请记住,IBAction方法本身可以调用其他方法,只要它可以访问声明这些方法的类的实例。

Apple有一个使用tableview委托和数据源协议方法的示例。转到此链接并下载示例代码:tableview example

它看起来像一个不错的应用程序。祝你好运。