以编程方式创建可可应用(OS X)的初始窗口 [英] programmatically create initial window of cocoa app (OS X)

查看:63
本文介绍了以编程方式创建可可应用(OS X)的初始窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常,我正在制作iOS应用程序,但现在我正在尝试制作OS X应用程序,一开始我迷路了.说我使iOS应用程序完全采用编程风格,没有xib文件或其他任何东西,仅仅是因为我通过打字比拖动拥有更多控制权.但是,在OS X编程中,它从带有菜单项和默认窗口的一些xib文件开始.菜单项中有很多项,因此可能不是我想要弄乱的东西,但我想以编程方式自己创建第一个窗口.

Usually I am making iOS app but now I am trying to make an OS X app, and I am lost at the very beginning. Say the style I make the iOS apps are totally programmatic, there's no xib files or whatsoever just because that I have a lot more control by typing than dragging. However in OS X programming, it starts with some xib files with the menu items and a default window. There are quite a lot of items in the menu items so that's probably not something I want to mess around, but I want to programmatically create my first window myself.

所以我做到了:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{    
    NSUInteger windowStyleMask = NSTitledWindowMask|NSResizableWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask;
    NSWindow* appWindow = [[NSWindow alloc] initWithContentRect:NSMakeRect(200, 200, 1280, 720) styleMask:windowStyleMask backing:NSBackingStoreBuffered defer:NO];
    appWindow.backgroundColor = [NSColor lightGrayColor];
    appWindow.minSize = NSMakeSize(1280, 720);
    appWindow.title = @"Sample Window";
    [appWindow makeKeyAndOrderFront:self];
    _appWindowController = [[AppWindowController alloc] initWithWindow:appWindow];
    [_appWindowController showWindow:self];
}

因此,在这里,我首先创建了一个窗口,并使用该windowController来初始化此窗口.窗口确实以这种方式显示,但是我只能指定内部元素,例如此处的按钮和标签,而不能在windowController中指定.这让我感到难过,所以我尝试了另一种方法.

So here, I have created a window first, and use that windowController to init this window. The window does show up in this way, but I can only specify the inner elements, like buttons and labels here, but not in the windowController. It makes me feel bad so I tried another way.

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    _appWindowController = [[AppWindowController alloc] init];
    [_appWindowController showWindow:self];
}

之后,我要像这样在windowController中的loadWindow:函数中设置其他元素:

and after this I want to set the other elements in the loadWindow: function in the windowController like this:

- (void)loadWindow
{
    [self.window setFrame:NSMakeRect(200, 200, 1280, 720) display:YES];
    self.window.title = @"Sample window";
    self.window.backgroundColor = [NSColor lightGrayColor];

    NSButton* sampleButton = [[NSButton alloc] initWithFrame:NSRectFromCGRect(CGRectMake(100, 100, 200, 23))];
    sampleButton.title = @"Sample Button!";
    [sampleButton setButtonType:NSMomentaryLightButton];
    [sampleButton setBezelStyle:NSRoundedBezelStyle];
    [self.window.contentView addSubview:sampleButton];
    NSLog(@"Loaded window!");
    [self.window makeKeyAndOrderFront:nil];
}

不幸的是,这永远行不通. loadWindow:从不被调用,windowDidLoad:也从不被调用.他们去哪了?

Unfortunately, this never works. the loadWindow: never gets called, nor windowDidLoad:. Where did they go?

请不要问为什么我不使用笔尖.我希望在内部(可能是OpenGL)制作一些高度自定义的视图,因此我认为笔尖无法处理它.如果有人可以提供帮助,我将不胜感激.谢谢.

And please don't ask why I don't use nibs. I wish to make some highly customized views inside, possibly OpenGL, so I don't think nibs can handle it. I am greatly appreciated if anyone could help. Thanks.

而且,还有谁知道如何以编程方式从头开始菜单项?

And also, who knows how to even start the menu items from scratch, programmatically?

我正在使用最新的XCode.

I am using the latest XCode.

推荐答案

我整个星期天都在自己研究这个问题.就像问这个问题的人一样,我更喜欢在不包含nib文件(大多数情况下)或Interface Builder的情况下对iOS和OSX进行编码,以简化工作.我确实使用NSConstraints.如果您要使用更简单的UI,那么避免IB可能是不值得的,但是,当您进入更复杂的UI时,它会变得越来越困难.

I spent an entire Sunday digging into this problem myself. Like the person asking the question, I prefer coding iOS and OSX without nib files (mostly) or Interface Builder and to go bare metal. I DO use NSConstraints though. It is probably NOT WORTH avoiding IB if you're doing simpler UIs, however when you get into a more complex UI it gets harder.

事实证明,这样做非常简单,为了社区"的利益,我想在这里发布一个简洁的最新答案.有一些较旧的Blog帖子,我发现最有用的是 Lap Cat软件中的博客.先生,给您帽子的提示"!

It turns out to be fairly simple to do, and for the benefit of the "Community" I thought I'd post a concise up to date answer here. There ARE some older Blog Posts out there and the one I found most useful were the ones from Lap Cat Software. 'Tip O The Hat' to you sir!

这假定为ARC.修改您的main()看起来像这样:

This Assumes ARC. Modify your main() to look something like this:

#import <Cocoa/Cocoa.h>
#import "AppDelegate.h"

int main(int argc, const char *argv[])
{
    NSArray *tl;
    NSApplication *application = [NSApplication sharedApplication];
    [[NSBundle mainBundle] loadNibNamed:@"MainMenu" owner:application topLevelObjects:&tl];

    AppDelegate *applicationDelegate = [[AppDelegate alloc] init];      // Instantiate App  delegate
    [application setDelegate:applicationDelegate];                      // Assign delegate to the NSApplication
    [application run];                                                  // Call the Apps Run method

    return 0;       // App Never gets here.
}

您会注意到那里仍然有一个Nib(xib).这仅用于主菜单.事实证明,即使在今天(2014年),显然也无法轻松设置位置0菜单项.那就是标题=您的应用程序名称的那个.您可以使用[NSApplication setMainMenu]将所有内容都设置在其右侧,但不能使用该设置.因此,我选择将Xcode创建的MainMenu Nib保留在新项目中,并将其剥离到仅位置0的位置.我认为这是一个公平的妥协,我可以接受. 一个简短的UI Sanity插件...在创建菜单时,请遵循与其他Mac OSX Apps相同的基本模式.

You'll note that there is still a Nib (xib) in there. This is for the main menu only. As it turns out even today (2014) apparently no way to easily set the position 0 menu item. That's the one with the title = to your App name. You can set everything to the right of it using [NSApplication setMainMenu] but not that one. So I opted to keep the MainMenu Nib created by Xcode in new projects, and strip it down to just the position 0 item. I think that is a fair compromise and something I can live with. One brief plug for UI Sanity... when you're creating Menus please follow the same basic pattern as other Mac OSX Apps.

接下来,修改AppDelegate使其类似于以下内容:

Next modify the AppDelegate to look something like this:

-(id)init
{
    if(self = [super init]) {
        NSRect contentSize = NSMakeRect(500.0, 500.0, 1000.0, 1000.0);
        NSUInteger windowStyleMask = NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;
        window = [[NSWindow alloc] initWithContentRect:contentSize styleMask:windowStyleMask backing:NSBackingStoreBuffered defer:YES];
        window.backgroundColor = [NSColor whiteColor];
        window.title = @"MyBareMetalApp";

        // Setup Preference Menu Action/Target on MainMenu
        NSMenu *mm = [NSApp mainMenu];
        NSMenuItem *myBareMetalAppItem = [mm itemAtIndex:0];
        NSMenu *subMenu = [myBareMetalAppItem submenu];
        NSMenuItem *prefMenu = [subMenu itemWithTag:100];
        prefMenu.target = self;
        prefMenu.action = @selector(showPreferencesMenu:);

        // Create a view
        view = [[NSTabView alloc] initWithFrame:CGRectMake(0, 0, 700, 700)];
    }
    return self;
 }

 -(IBAction)showPreferencesMenu:(id)sender
 {
    [NSApp runModalForWindow:[[PreferencesWindow alloc] initWithAppFrame:window.frame]];
 }

-(void)applicationWillFinishLaunching:(NSNotification *)notification
{
    [window setContentView:view];           // Hook the view up to the window
}

-(void)applicationDidFinishLaunching:(NSNotification *)notification
{
    [window makeKeyAndOrderFront:self];     // Show the window
} 

还有宾果游戏……你很好!就像您熟悉的一样,您可以从那里开始在AppDelegate中工作.希望有帮助!

And Bingo... you're good to go! You can start working from there in the AppDelegate pretty much like you're familiar with. Hope that helps!

更新:如上所述,我不再在代码中创建菜单.我发现您可以在Xcode 6.1中编辑 MainMenu.xib 源.效果很好,非常灵活,只需要做一点试验就可以知道它是如何工作的.比弄乱代码更快,并且易于本地化!看到图片以了解我的意思:

UPDATE: I don't create menus in code anymore as I've shown above. I've discovered you can edit MainMenu.xib source in Xcode 6.1. Works nice, very flexible and all it takes is a little experimentation to see how it works. Faster than messing around in code and easy to localize! See the picture to understand what I am on about:

这篇关于以编程方式创建可可应用(OS X)的初始窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆