我如何在代码中重新定义应用程序 window 的 size/origin,覆盖 nib/xib 文件参数,使用 Obj-C,Xcode 11.3.1 on Mac OS X 10.15.2(卡特琳娜)?

How do I re-define size/origin of app window in code, overriding nib/xib file parameters, with Obj-C, Xcode 11.3.1 on Mac OS X 10.15.2 (Catalina)?

我会尽量保持简短。我想创建一个 3D FPS 游戏,只为我自己,可以 运行 在多个平台上,但我认为为了简单起见,也许最好从专为 macOS 设计的游戏开始。我选择 Objective-C 因为

(a) Window Xcode 中的应用项目只能用 Obj-C 或 Swift 编码(因为我们正在处理 Cocoa API) 和

(b) Obj-C 比 Swift 更接近老派。

但是在我通过编写代码学习 window 的 canvas 上的 draw/render 二维形状之前,我必须学习调用应用程序 window它的属性设置为我喜欢的。我花了几个小时研究和试验代码块。这是我尝试过的:我用

打开
#import <Cocoa/Cocoa.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {

那我跟...

1)

        NSWindow *window = [[[NSApplication sharedApplication] windows] firstObject];
        NSRect frame = [window frame];
        frame.origin.x = 100;
        frame.origin.y = 200;
        frame.size.width = 100;
        frame.size.height = 500;
        [window setFrame: frame display: YES];

... 并以 ...

结束

        NSApplicationMain(argc, argv); // runs the win display function.
    }

    return (0) ;
}

但没有明显的变化。什么都没有真正被重置。所以我尝试了而不是 (1) ...

2)

        NSWindow *window = [[[NSApplication sharedApplication] windows] firstObject];
        NSPoint newOrigin;
        newOrigin.x = 400;
        newOrigin.y = 100;
        [window setFrameOrigin : newOrigin];

仍然没有。然后我尝试了而不是(2):

3)

 NSWindowController* controller = [[NSWindowController alloc]
            initWithWindowNibName:@"MainMenu"];
        [controller showWindow:nil];

太棒了。现在它吐出一些我不明白的东西,特别是因为我是 Obj-C 的新手:

2020-02-08 21:53:49.782197-0800 
        tryout_macApp2[14333:939233] [Nib Loading] Failed 
        to connect (delegate) outlet from 
        (NSWindowController) to (AppDelegate): missing 
        setter or instance variable

我记得曾与 ApplicationDelegate、CGSizeMake() 等进行过切分,但这只会让体验变得非常令人沮丧和沮丧。什么都没发生。然后是NSView、NSViewController等类,真是令人费解,不禁要问:为什么有这么多类,而我只想覆盖[=64]的预设原点=] 和 MainMenu.xib 文件预设的尺寸? (顺便说一句,这个项目是从Xcode提供的一个Window应用项目派生出来的。)

我真的想不出还有什么可以补充的,可以让您了解我的困境的全貌,所以如果您觉得缺少什么,请补充。

[编辑:] 进入我项目的第 2 阶段:

我爱Objective-C但也感受到你的痛苦,它有这种暴躁的能力让你无休止地沮丧。

我还没有真正开发过游戏,但让我尝试为您指明正确的方向。我想你需要一个 UIViewController。

现在每个 UIViewController 都有一个内置的 UIView,代表它的可见部分。您可以使用它或添加一个 UIView 并使用它,具体取决于您的实现。现在我建议添加一个单独的 UIView 并使用它。一旦你感到舒服,你就可以根据需要将实现移动到 UIViewController 的视图。

无论如何,现在创建一个 UIView 子类,比如 MyGame 之类的,因为现在您的所有代码都将在那里结束。

做到以上几点并不容易,尤其是第一次。如果您可以按照一些教程进行操作,那就太好了。即使教程只是添加了一个按钮,您也可以使用它并将按钮替换为您的视图。

无论如何,现在您已经得到 运行 并且您添加的视图显示为绿色或其他一些霓虹色只是为了验证您确实可以更改其属性,你很好去。

现在开始。在 MyGame 中,实现 -(void)drawRect:(CGRect)rect 消息,通过获取上下文 UIGraphicsGetCurrentContext 然后开始在上面画线和东西,基本上是我知道你有兴趣做的东西。您还可以通过相同的上下文更改您正在做的事情的来源。

希望对您有所帮助。

简短的回答是 main() 尝试这样做还为时过早。相反,在您的应用程序委托 class 上实现 -applicationDidFinishLaunching:,并在那里执行。保留 main(),因为它最初是由 Xcode 的模板创建的。

在那之后,我会说要获得 window(如果只有一个主要的),最好向您的应用程序委托添加一个出口,然后在 NIB 中连接它window 的出口。然后,只要你想引用 window.

就可以使用那个出口

此外,请确保在 NIB 中为 window 禁用启动时可见。这样您就可以在显示之前根据需要进行配置。

对于更复杂的应用程序,最好不要将 window 放入主菜单笔尖。相反,为 window 创建一个单独的笔尖。然后,使用 window 控制器对象加载它并询问它的 window.