提问人:KanKonga 提问时间:9/19/2023 最后编辑:Dávid PásztorKanKonga 更新时间:9/21/2023 访问量:76
为什么这个窗口根本没有显示?
Why this window does not show up at all?
问:
我正在尝试了解如何在两个不同的视图或函数之间更改变量(var 或标签)中的数据。
我正在从 迁移,我习惯于在整个应用程序中创建。但现在可可框架让我有点困惑。swiftUi
stateobject and accessing the variable through environment variables
因此,我创建了两个视图,其中一个包含一个按钮,另一个包含一个标签。因此,当按钮单击时,标签的字符串值应更改。CustomView1
CustomView2
但问题是运行时什么都没有显示。甚至没有出现。window
错误:无错误
main.swift
import Cocoa
let app = NSApplication.shared
let appDelegate = App2()
app.delegate = appDelegate
app.setActivationPolicy(.regular)
app.activate(ignoringOtherApps:true)
app.run()
App2.swift
import Cocoa
class App2: NSObject, NSApplicationDelegate {
var window:NSWindow!
var view: NSView!
var customView1: CustomView1!
var customView2: CustomView2!
func buildMenu() {
let mainMenu = NSMenu()
NSApp.mainMenu = mainMenu
// **** App menu **** //
let appMenuItem = NSMenuItem()
mainMenu.addItem(appMenuItem)
let appMenu = NSMenu()
appMenuItem.submenu = appMenu
appMenu.addItem(withTitle: "Quit", action:#selector(NSApplication.terminate), keyEquivalent: "q")
}
func buildWnd() {
let _wndW: CGFloat = 400
let _wndH: CGFloat = 400
//@State var title: String = "app title"
let appTitle: String = "app title"
window = NSWindow(contentRect: NSMakeRect(0, 0, _wndW, _wndH), styleMask: [.titled, .closable, .miniaturizable, .resizable], backing: .buffered, defer: false)
window.center()
window.title = appTitle
window.makeKeyAndOrderFront(window)
// Create a label
let labelFrame = NSRect(x: 50, y: 50, width: 200, height: 30)
let labelText = "Hello, Cocoa!"
customView1 = CustomView1(frame: NSRect(x: 10, y: 50, width: 120, height: 50))
customView2 = CustomView2(frame: NSRect(x: 10, y: 100, width: 120, height: 50))
window.contentView?.addSubview(customView1)
window.contentView?.addSubview(customView2)
}
class CustomView1: NSView {
let customView2 = CustomView2(frame: NSRect(x: 10, y: 50, width: 100, height: 30))
func createButton(frame: NSRect, title: String) -> NSButton {
let button = NSButton(frame: frame)
button.title = title
button.bezelStyle = .rounded
button.target = self
button.action = #selector(buttonClicked(_:))
return button
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
let button = createButton(frame: NSRect(x: 10, y: 10, width: 100, height: 30), title: "Click me!")
self.addSubview(button)
self.addSubview(customView2)
}
@objc func buttonClicked(_ sender: NSButton) {
customView2.label.stringValue = "Button clicked!"
}
}
class CustomView2: NSView {
let label = NSTextField(frame: NSRect(x: 10, y: 10, width: 100, height: 20))
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
label.stringValue = "Hello, world!"
label.isEditable = false
label.isSelectable = false
label.isBezeled = false
label.drawsBackground = false
self.addSubview(label)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
func applicationDidFinishLaunching(_ notification: Notification) {
buildMenu()
buildWnd()
}
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
}
答:
-1赞
apodidae
9/20/2023
#1
以下源代码是对演示的重新排列。这两个自定义视图需要与 appDelegate 分开。就添加控件而言,自定义视图 2 比自定义视图 1 更正确。您需要使用 Xcode 的 File/New/File 创建一个名为“main.swift”的新文件。将以下代码完整复制/粘贴到该文件中,然后删除预先提供的 AppDelegate,它应该可以正常运行,而不会出错。
import Cocoa
var customView1: CustomView1!
var customView2: CustomView2!
class CustomView1: NSView {
let button = NSButton(frame:NSMakeRect(10,12,100,24))
@objc func buttonClicked(_ sender: NSButton) {
customView2.label.stringValue = "Button clicked!"
}
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
button.title = "Click Me"
button.bezelStyle = .rounded
button.target = self
button.action = #selector(buttonClicked(_:))
self.addSubview(button)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
let bkgrnd = NSBezierPath(rect: dirtyRect)
NSColor.lightGray.set()
bkgrnd.fill()
}
}
class CustomView2: NSView {
let label = NSTextField(frame: NSMakeRect(10,14,100,20))
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
label.stringValue = "Hello, world!"
label.isBordered = false
label.isSelectable = false
label.backgroundColor = NSColor.clear
self.addSubview(label)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
let bkgrnd = NSBezierPath(rect: dirtyRect)
NSColor.orange.set()
bkgrnd.fill()
}
}
class ApplicationDelegate: NSObject, NSApplicationDelegate {
var window:NSWindow!
func buildMenu() {
let mainMenu = NSMenu()
NSApp.mainMenu = mainMenu
// **** App menu **** //
let appMenuItem = NSMenuItem()
mainMenu.addItem(appMenuItem)
let appMenu = NSMenu()
appMenuItem.submenu = appMenu
appMenu.addItem(withTitle: "Quit", action:#selector(NSApplication.terminate), keyEquivalent: "q")
}
func buildWnd() {
let _wndW: CGFloat = 400
let _wndH: CGFloat = 300
let appTitle: String = "app title"
window = NSWindow(contentRect: NSMakeRect(0,0,_wndW,_wndH), styleMask: [.titled, .closable, .miniaturizable, .resizable], backing: .buffered, defer: false)
window.center()
window.title = appTitle
window.makeKeyAndOrderFront(window)
// Create a label from NSTextField
let txtFld = NSTextField (frame:NSMakeRect(30,_wndH - 50,300,30))
txtFld.isSelectable = false
txtFld.isBordered = false
txtFld.backgroundColor = NSColor.clear
txtFld.textColor = NSColor.red
txtFld.font = NSFont(name: "Menlo", size: 28)
txtFld.stringValue = "Hello, Cocoa!"
window.contentView!.addSubview(txtFld)
customView1 = CustomView1(frame: NSMakeRect(30,_wndH - 190,120,50))
customView2 = CustomView2(frame: NSMakeRect(30,_wndH - 130,120,50))
window.contentView!.addSubview(customView1)
window.contentView!.addSubview(customView2)
}
func applicationDidFinishLaunching(_ notification: Notification) {
buildMenu()
buildWnd()
}
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
}
let applicationDelegate = ApplicationDelegate()
let application = NSApplication.shared
application.setActivationPolicy(NSApplication.ActivationPolicy.regular)
application.delegate = applicationDelegate
application.activate(ignoringOtherApps:true)
application.run()
评论
0赞
KanKonga
9/20/2023
抛出错误,其中之一是 var “customView1: CustomView1!”你确定你可以像这样将变量放在顶层吗?
0赞
apodidae
9/20/2023
源代码在此处运行没有错误。顶部的变量称为“全局变量”,这两个视图需要位于该位置,以便您可以在 customView1 中使用 customView2.label 调用。您在名为“main.swift”的文件中有代码吗?
评论