以编程方式创建的NSToolbar开始为空,无法保存 [英] NSToolbar created programmatically starts empty and won't save
问题描述
我目前正在尝试编写Mac应用程序.这样做时,尝试设置NSToolbar时遇到一些特殊的问题.
I'm currently trying to write a Mac application. In doing so, I'm having some peculiar problems when trying to setup an NSToolbar.
尽管我已经按照API文档设置了所有组件,但是当应用程序加载时,工具栏总是开始为空.打开自定义窗格时,工具栏项已存在,可以将它们拖动到工具栏中,但是当我退出应用程序并重新启动更改后,更改就消失了.
Although I have setup all the components as per the API documentation, when the application loads, the toolbar always starts empty. When I open the customisation pane, the toolbar items are there, and I can drag them into the toolbar, but when I quit the application and restart the changes are gone.
注意:我知道很多人会认为解决此问题的最佳方法是使用接口生成器,而不是在代码中完成.那不是我要寻找的答案-为了更好地了解Cocoa应用程序的内部结构,我选择不使用IB制作此应用程序.
Note: I am aware that many of you will be of the opinion that the best way to solve this is to use interface builder rather than doing it in code. That is not the answer I am looking for - I chose to make this application without IB in order to better understand the internals of a Cocoa app.
我已经使用NSLogs验证了 toolbarAllowedItemIdentifiers
和 toolbarDefaultItemIdentifiers
委托方法在首次初始化工具栏时都不会被调用,但是在您进入时会被调用自定义窗格.
I have verified (with NSLogs) that neither the toolbarAllowedItemIdentifiers
nor the toolbarDefaultItemIdentifiers
delegate methods get called when the toolbar is first initialised, but they do get called when you enter the customisation pane.
请在下面找到基本应用的最小,可验证且完整的示例版本,以证明此错误.任何可以对此事有所了解的人将不胜感激!
Below, please find a minimal, verifiable and complete example version of a basic app that demonstrates this bug. Anyone that can shed some light on this matter would be hugely appreciated!
谢谢
Defines.h
Defines.h
#define UNUSED(x) (void)(x)
#define TOOLBAR_ONE @"ONE"
#define TOOLBAR_TWO @"TWO"
#define TOOLBAR_IDENT @"TOOLBAR"
#define WINDOW_MASK NSTitledWindowMask | \
NSClosableWindowMask | \
NSResizableWindowMask | \
NSMiniaturizableWindowMask
main.m
#import "BWAppDelegate.h"
#import <AppKit/AppKit.h>
int main(void) {
@autoreleasepool {
NSApplication* application = [NSApplication sharedApplication];
BWAppDelegate* delegate = [[BWAppDelegate alloc] init];
application.delegate = delegate;
[application run];
return EXIT_SUCCESS;
}
}
BWAppDelegate.h
BWAppDelegate.h
#import <Cocoa/Cocoa.h>
#import "BWMainToolbarDelegate.h"
@interface BWAppDelegate : NSObject<NSApplicationDelegate>
@property (atomic, strong) NSWindow* window;
@property (atomic, strong) BWMainToolbarDelegate* toolbarDelegate;
@end
BWAppDelegate.m
BWAppDelegate.m
#import <AVFoundation/AVFoundation.h>
#import <AppKit/AppKit.h>
#import <Cocoa/Cocoa.h>
#import "BWAppDelegate.h"
#import "Defines.h"
@implementation BWAppDelegate
@synthesize window, toolbarDelegate;
- (void) applicationDidFinishLaunching: (NSNotification*) aNotification
{
UNUSED(aNotification);
NSRect dims = NSMakeRect(0, 0, 300, 300);
self.window = [[NSWindow alloc] initWithContentRect:dims
styleMask:WINDOW_MASK
backing:NSBackingStoreBuffered
defer:NO];
[self.window makeKeyAndOrderFront:nil];
self.window.toolbar = [[NSToolbar alloc] initWithIdentifier:TOOLBAR_IDENT];
toolbarDelegate = [[BWMainToolbarDelegate alloc] initWithToolbar:self.window.toolbar];
}
@end
BWMainToolbarDelegate.h
BWMainToolbarDelegate.h
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
@interface BWMainToolbarDelegate : NSObject<NSToolbarDelegate>
- (instancetype) initWithToolbar: (NSToolbar*) theToolbar;
- (NSArray*) toolbarAllowedItemIdentifiers: (NSToolbar*) toolbar;
- (NSArray*) toolbarDefaultItemIdentifiers: (NSToolbar*) toolbar;
- (NSToolbarItem*) toolbar: (NSToolbar*) toolbar
itemForItemIdentifier: (NSString*) identifier
willBeInsertedIntoToolbar: (BOOL) flag;
@end
BWMainToolbarDelegate.m
BWMainToolbarDelegate.m
#import "BWMainToolbarDelegate.h"
#import "Defines.h"
@implementation BWMainToolbarDelegate {
NSToolbar* toolbar;
}
- (instancetype) initWithToolbar: (NSToolbar*) theToolbar
{
self = [super init];
if(self) {
toolbar = theToolbar;
toolbar.displayMode = NSToolbarDisplayModeIconAndLabel;
toolbar.allowsUserCustomization = YES;
toolbar.autosavesConfiguration = YES;
toolbar.delegate = self;
}
return self;
}
- (NSArray*) toolbarAllowedItemIdentifiers: (NSToolbar*) theToolbar
{
UNUSED(theToolbar);
return @[TOOLBAR_ONE, TOOLBAR_TWO];
}
- (NSArray*) toolbarDefaultItemIdentifiers: (NSToolbar*) theToolbar
{
UNUSED(theToolbar);
return @[TOOLBAR_ONE, TOOLBAR_TWO];
}
- (NSToolbarItem*) toolbar: (NSToolbar*) theToolbar
itemForItemIdentifier: (NSString*) identifier
willBeInsertedIntoToolbar: (BOOL) flag
{
UNUSED(flag);
NSToolbarItem* returnVal = nil;
NSString* label;
if([theToolbar.identifier isEqualToString:TOOLBAR_IDENT]) {
if([identifier isEqualToString:TOOLBAR_ONE]) {
returnVal = [[NSToolbarItem alloc] initWithItemIdentifier:TOOLBAR_ONE];
label = @"Toolbar One";
} else if([identifier isEqualToString:TOOLBAR_TWO]) {
returnVal = [[NSToolbarItem alloc] initWithItemIdentifier:TOOLBAR_TWO];
label = @"Toolbar TWO";
}
}
returnVal.label = label;
returnVal.paletteLabel = label;
return returnVal;
}
@end
推荐答案
在将工具栏添加到窗口之前,设置工具栏的委托.
Set the delegate of the toolbar before adding the toolbar to the window.
这篇关于以编程方式创建的NSToolbar开始为空,无法保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!