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

查看:159
本文介绍了编程创建可可应用程序(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 programatically 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];
}


$ b $ p这里,我已经创建了一个窗口,并使用windowController init这个窗口。窗口确实以这种方式显示,但我只能在这里指定内部元素,如按钮和标签,但不能在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];
}

之后,我要设置 loadWindow:在windowController中的函数如下:

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];
}


$ b。 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.

推荐答案

我花了整个星期天自己挖掘这个问题。像提出问题的人,我更喜欢编写iOS和OSX没有nib文件(大多数)或Interface Builder和去裸机。我尽管使用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.

原来是相当简单为了社区的利益,我想我会在这里张贴一个简明的最新回答。有一些较旧的博客文章在那里,我发现最有用的是来自 Lap Cat软件。 'Tip O The Hat'给你先生!

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这仅适用于主菜单。因为它甚至今天(2014年)显然没有办法轻松设置位置0菜单项。这是一个标题为您的应用程序名称。你可以使用 [NSApplication setMainMenu] 设置所有的权限,但不是那个。所以我选择在新项目中保留由Xcode创建的MainMenu Nib,并将其剥离到位置0项。我认为这是一个公平的妥协和我可以生活的东西。 UI Sanity的一个简单插件...当您创建菜单时,请遵循与其他Mac OSX应用程序相同的基本模式

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!

UPDATE :我不在代码中创建菜单,如上所示。我发现您可以在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天全站免登陆