如何用纯Swift 3替换我的.xib文件?

时间:2017-03-18 13:04:36

标签: swift xcode macos cocoa

我正在制作一个只在菜单栏中运行的macOS Cocoa应用程序。当我最初创建项目时,Xcode给了我一个名为MainMenu.xib的文件。此MainMenu.xib文件似乎不包含与我的菜单栏应用程序相关的任何内容,因此我希望将其删除。

Cocoa入口点the function NSApplicationMain和#34;从应用程序的主包"加载主nib文件。我在其他地方读过Cocoa找到的主要nib文件"通过查询我的NSMainNibFile中的密钥Info.plist,该密钥已设置为字符串MainMenu。我删除了密钥NSMainNibFile,我的程序仍然表现相同。由此,我假设Cocoa看到没有这个键,所以它跳过了它的nib / xib加载步骤。

由于我的MainMenu.xib文件不再从任何地方引用,我删除了它(从我的project.pbxproj中删除了一些无辜的引用)。但是,删除MainMenu.xib后,我的应用程序不再有效。我的applicationDidFinishLaunching课程上的AppDelegate方法未被调用!

这意味着两件事。首先,这意味着即使MainMenu.xib不存在,Cocoa仍会神奇地找到我的NSMainNibFile文件(如果我将文件重命名为Foo.xib,Cocoa仍会找到该文件)。更重要的是,这意味着我的MainMenu.xib 中的某些内容仍然是,我的应用程序仍然需要运行。这是完整的MainMenu.xib

<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
    </dependencies>
    <objects>
        <customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
            <connections>
                <outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
            </connections>
        </customObject>
        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
        <customObject id="-3" userLabel="Application" customClass="NSObject"/>
        <customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Foo" customModuleProvider="target"/>
    </objects>
</document> 

我认为问题是我的MainMenu.xib引用了我的AppDelegate类,Cocoa使用它来实例化AppDelegate类,然后调用applicationDidFinishLaunching物体。这很令人困惑,因为我认为@NSApplicationMain课程上的AppDelegate注释已经足够了。

由于这个原因,我有几个问题:

  1. Cocoa(即NSApplicationMain)如何找到我的MainMenu.xib文件? Cocoa的搜索程序是什么?如何告诉Cocoa跳过此加载步骤?
  2. 我的MainMenu.xib文件在做什么?也就是说,Cocoa如何解释MainMenu.xib文件,结果是什么?具体来说,这个文件如何导致我的AppDelegate类被实例化?
  3. 如何在Swift 3中以编程方式重新创建此逻辑,以便删除MainMenu.xib文件?我需要使用哪些API?

2 个答案:

答案 0 :(得分:0)

  1. 您的XIB文件的名称存储在Info.plist中。您可以通过选择Xcode项目文件并单击“信息”选项卡直接修改它,也可以在“主界面”下的“常规”选项卡中进行更改。

  2. 在每个默认MainMenu.xib的顶层是一个AppDelegate对象。该对象是接收所有app委托消息的对象。它已连接到占位符Application对象的delegate出口。

  3. 要复制此行为,您需要继承NSApplication并修改您的目标&#34;主要类&#34; Info.plist设置反映新的子类。在您的子类中,您可以覆盖finishLaunching()之类的内容来创建您的app委托对象并进行设置。但是,请记住,当这样做时,您需要确保您的新委托在某处具有强大的引用,因为它不再由nib文件拥有。我建议在您的子类中添加一个强大的属性,可能类似于strongDelegate

答案 1 :(得分:0)

回答问题#3:

  • 创建一个Swift文件main.swift
  • main.swift中的代码替换为

    import Cocoa
    
    let appDelegate = AppDelegate()
    NSApplication.shared().delegate = appDelegate
    _ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
    
  • 删除@NSApplicationMain中的AppDelegate
  • 删除NSMainNibFile中的键/值对Info.plist
  • 删除.xib文件。