我试图从笔尖加载和显示窗口,不知道如何正确地做到这一点。现在我使用以下代码:
import Cocoa
class AppDelegate: NSObject, NSApplicationDelegate {
var statusItem: NSStatusItem!
var statusButton: NSStatusBarButton!
var menu: NSMenu!
var menuItemTitle: NSMenuItem!
var menuItemInfo: NSMenuItem!
var menuItemQuit: NSMenuItem!
var menuImage: NSImage!
var titleView: TitleView!
func applicationDidFinishLaunching(_ aNotification: Notification) {
menuImage = NSImage(systemSymbolName: "menubar.rectangle", accessibilityDescription: "Image")
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
statusButton = statusItem.button
statusButton.image = menuImage
menuItemTitle = NSMenuItem(title: "First", action: nil, keyEquivalent: "")
menuItemInfo = NSMenuItem(title: "Info", action: #selector(actionInfo), keyEquivalent: "i")
menuItemQuit = NSMenuItem(title: "Quit", action: #selector(actionQuit), keyEquivalent: "q")
menu = NSMenu()
menu.addItem(menuItemTitle)
menu.addItem(menuItemInfo)
menu.addItem(NSMenuItem.separator())
menu.addItem(menuItemQuit)
statusItem.menu = menu
titleView = TitleView(frame: NSRect(x: 0, y: 0, width: 250, height: 70))
menuItemTitle.view = titleView
}
func applicationWillTerminate(_ aNotification: Notification) {
}
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
return true
}
@objc func actionQuit() {
NSApplication.shared.terminate(self)
}
var infoWindowController: InfoWindowController!
@objc func actionInfo() {
infoWindowController = InfoWindowController()
infoWindowController.showWindow(self)
// infoWindowController.showWin(self)
}
}
import Foundation
import Cocoa
class InfoWindowController: NSWindowController {
@IBOutlet var infoWindow: NSWindow!
@IBOutlet weak var infoIcon: NSImageView!
override var windowNibName: String! {
return "InfoWindow"
}
override func windowDidLoad() {
print("windowDidLoad")
}
func showWin(_ sender: Any) {
_ = window
showWindow(sender)
/// This does not work
// window?.center()
// window?.makeKeyAndOrderFront(self)
//This works with the first NSViewController.window access
// infoWindow?.center()
// infoWindow?.makeKeyAndOrderFront(self)
}
}
InfoWindow.xib
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="InfoWindowController" customModule="GUI" customModuleProvider="target">
<connections>
<outlet property="infoWindow" destination="QvC-M9-y7g" id="jBK-DN-ufD"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<window title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="QvC-M9-y7g">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="196" y="240" width="480" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2Ad-gr-Tqg">
<rect key="frame" x="185" y="166" width="56" height="16"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Hi there!" id="lZn-he-q8e">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
</view>
<point key="canvasLocation" x="105" y="144"/>
</window>
</objects>
</document>
我没有脚本,所以我使用main.swift:
import Foundation
import Cocoa
let app = NSApplication.shared
let delegate = AppDelegate()
app.delegate = delegate
_ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)
根据文档here,我需要“访问window属性,以便调用windowDidLoad()和windowWillLoad()方法”。我在执行_ = window
行之后观察到windowDidLoad。但即使在此之后,我的控制器的``window`属性仍然为nil。但IBOutlet开始工作,所以我的工作代码如下所示:
func show() {
_ = window
infoWindow?.center()
infoWindow?.makeKeyAndOrderFront(self)
}
我的问题是:有没有可能在没有IBOutlet的情况下从xib加载并显示窗口?或者只使用IBOutlet,而不访问NSWindowController的window属性?如何以“正确”的方式进行?还有,我如何防止用户多次激活此窗口?谢谢!
更新:亲爱的同事,谢谢你的帮助!我非常感激。我已经made a github repo,使它更容易跟踪您建议我尝试的更改。
3条答案
按热度按时间hfsqlsce1#
你问了很多问题这让事情变得非常混乱。从你的问题的标题来看,你似乎得到了多个信息窗口正在显示我认为这是因为每次调用
actionInfo
处理程序时都会创建一个新的示例。原始代码将使用新示例覆盖infoWindowController
属性。您可以创建一次Info窗口,然后使用
lazy
延迟创建,直到需要它:请注意,这将使信息窗口控制器的示例保持活动状态,即使您关闭窗口。
yfjy0ee72#
将以下代码添加到窗口控制器中。
然后创建一个窗口;
yhuiod9q3#
是否可以在没有infoWindow IBOutlet的情况下从xib加载和显示窗口?
是的。
InfoWindowController
有一个outlet属性infoWindow
。InfoWindowController
的超类NSWindowController
有一个属性window
。在xib中,infoWindow
的outlet连接到窗口,但window
的outlet没有。解决方案:将xib中的
window
插座连接到窗口。步骤:
1.选择InfoWindow.xib
1.选择文件的所有者
1.转到连接检查器
1.从窗口出口拖动到窗口
你不需要调用
_ = window
。当窗口加载时,方法windowDidLoad()
和windowWillLoad()
会被自动调用,例如showWindow
。