我有一个带有几个弹出按钮的主窗口。我想清除它们,然后从自定义类中的方法加载列表。我的视图控制器工作正常,我知道自定义类(newRequest)中的方法正常工作,因为我在方法执行时添加了一个NSLog命令来打印“Test”。在AppDelegate中,我通过以下方式调用方法: [polyAppRequest newRequest];。 正如我所说,我知道该方法正在执行。为什么我不能从这个自定义类方法中弹出popupbutton中的allitems? 谢谢 基思
答案 0 :(得分:0)
我读到你应该使用NSWindowController来管理一个窗口。见这里:
Windows and window controllers
Adding views or windows to MainWindow
然后,如果你的窗口变得足够复杂,NSWindowController可以使用各种NSViewControllers来管理部分窗口。
无论如何,我在答案中使用了NSWindowController。
下面的图片显示了文件所有者的出口,即MainWindowController
:
我在Xcode6.2
创建了MainWindowController .h / .m:
Subclass of:
also create .xib file for user interface
然后我在默认的MainMenu.xib中删除了窗口 - 而不是菜单 - 我将上面步骤创建的MainWindowController.xib的名称更改为MainWindow.xib。
以下代码适用于我(但我是Cocoa初学者!):
//
// AppDelegate.m
// PopUpButtons
#import "AppDelegate.h"
#import "MainWindowController.h"
@interface AppDelegate ()
@property(strong) MainWindowController* mainWindowCtrl;
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
[self setMainWindowCtrl:[[MainWindowController alloc] init]];
[[self mainWindowCtrl] showWindow:nil];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
@end
...
//
// MainWindowController.m
// PopUpButtons
//
#import "MainWindowController.h"
#import "MyData.h"
@interface MainWindowController ()
@property(strong) MyData* data;
@property(weak) IBOutlet NSPopUpButton* namePopUp;
@property(weak) IBOutlet NSPopUpButton* agePopUp;
@end
@implementation MainWindowController
-(id)init {
if (self = [super initWithWindowNibName:@"MainWindow"]) {
_data = [[MyData alloc] init]; //Get data for popups
}
return self;
}
- (void)windowDidLoad {
[super windowDidLoad];
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
[[self namePopUp] removeAllItems];
[[self namePopUp] addItemsWithTitles:[[self data] drinks]];
[[self agePopUp] removeAllItems];
[[self agePopUp] addItemsWithTitles:[[self data] extras]];
}
@end
...
//
// MyData.h
// PopUpButtons
//
#import <Foundation/Foundation.h>
@interface MyData : NSObject
@property NSArray* drinks;
@property NSArray* extras;
@end
...
//
// MyData.m
// PopUpButtons
//
#import "MyData.h"
@implementation MyData
- (id)init {
if (self = [super init]) {
_drinks = @[@"coffee", @"tea"];
_extras = @[@"milk", @"sugar", @"honey"];
}
return self;
}
@end
我希望有所帮助。如果您需要更多屏幕截图,请与我们联系。
<强> EDIT1:强>
我想我知道你在问什么。虽然我不认为这是一个非常好的方法,但如果我将代码更改为:
//
// MyData.h
// PopUpButtons
//
#import <Cocoa/Cocoa.h>
@interface MyData : NSObject
@property (copy) NSArray* drinks;
@property (copy) NSArray* extras;
-(void)newRequest;
@end
...
//
// MyData.m
// PopUpButtons
//
#import "MyData.h"
@interface MyData()
@property (weak) IBOutlet NSPopUpButton* drinksPopUp;
@property (weak) IBOutlet NSPopUpButton* extrasPopUp;
@end
@implementation MyData
- (id)init {
if (self = [super init]) {
_drinks = @[@"coffee", @"tea"];
_extras = @[@"milk", @"sugar", @"honey"];
}
return self;
}
-(void)newRequest {
[[self drinksPopUp] removeAllItems];
[[self drinksPopUp] addItemsWithTitles:[self drinks]];
[[self extrasPopUp] removeAllItems];
[[self extrasPopUp] addItemsWithTitles:[self extras]];
}
@end
我无法填充NSPopUpButtons。这就是我所做的:
我将一个Object从Object Library拖到IB中的dock,在Identity Inspector中,我将Object的类更改为MyData。
然后我点击了Connections Inspector,并在Outlets中列出了MyData,drinkPopUp和extrasPopUp中的两个实例变量。
我从出口拖到相应的NSPopUpButtons。
我想我和你一样认为,当我的程序运行时,NSPopUpButtons会被分配给实例变量drinkPopUp和extrasPopUp--但似乎并非如此。根据{{3}},您应该可以这样做:
应用程序通常在其自定义之间设置插座连接 用户界面上的控制器对象和对象,但它们可以 在任何可以表示为实例的对象之间进行的 Interface Builder,...
<强> EDIT2:强>
我能够将NSPopUpButtons从我的MainWindowController传递给newRequest方法,我可以使用newRequest中的NSPopUpButtons来成功填充数据。
<强> EDIT3:强>
我知道自定义类(newRequest)中的方法正在工作,因为 我添加了一个NSLog命令来打印&#34;测试&#34;当方法执行时。
但是当您记录指向NSPopUpButtons的变量时会发生什么?使用Edit1
中的代码,我得到变量的NULL,这意味着NSPopUpButtons永远不会被分配给变量。
<强> Edit4 强>:
如果我向MyData添加awakeFromNib
方法,并且在awakeFromNib中我记录了Edit1中代码的NSPopUpButton变量,我得到非NULL值。这告诉我MainWindowController的windowDidLoad方法在MyData的awakeFromNib方法之前执行,因此你不能在MainWindowController的windowDidLoad方法中调用newRequest,因为MyData还没有完全初始化。
<强> Edit5 强>:
好的,我在Edit1中获得了代码。 Apple docs说出这个:
关于顶级对象
当程序加载nib文件时,Cocoa会重新创建整个图形 您在Xcode中创建的对象。该对象图包括所有 找到的窗口,视图,控件,单元格,菜单和自定义对象 nib文件。顶级对象是这些对象的子集 没有父对象[在IB中]。通常是顶级对象 仅包括窗口,菜单栏和自定义控制器对象 你添加到nib文件[像MyData对象]。 (File's Owner,First等对象 响应者和应用程序是占位符对象,不予考虑 顶级对象。)
通常,您使用File的Owner对象中的outlet来存储 引用nib文件的顶级对象。如果不使用 但是,您可以从中检索顶级对象 nib-loaded例程直接。你应该总是保持一个指针 这些对象因为您的应用程序负责而在某处 使用它们时释放它们。有关的更多信息 加载时的nib对象行为,请参阅管理生命周期 来自Nib文件的对象。
按照上面的粗线,我在MainWindowController.m中更改了这个声明:
@interface MainWindowController ()
@property(strong) MyData* data;
...
@end
到此:
@interface MainWindowController ()
@property(strong) IBOutlet MyData* data;
...
@end
然后,在IB中,我将一个连接从MainWindowController 数据插件拖到MyData对象(我以前从对象库中拖出的对象和文档)。
我想这会导致MyData从.xib文件中取消归档并在MainWindowController之前初始化。