SwiftUI macOS NSWindow 实例
SwiftUI macos NSWindow instance
使用 xcode 12.3
和 swift 5.3
以及 SwiftUI App
生命周期来构建 macOS
应用程序,访问和更改外观和行为的最佳方式是什么NSWindow
?
编辑:我真正想要的是 NSWindow
实例。
我添加了一个AppDelegate
,但据我了解,NSWindow
很可能是nil
,因此无法修改,只是在这里创建一个类似于AppKit App Delegate
生命周期方法导致两个 windows 在启动时出现。
一个解决方案是阻止默认 window 出现,并将其全部留给 applicationDidFinishLaunching
方法,但不确定这是否可能或明智。
WindowStyle
协议看起来是一个可能的解决方案,但不确定现阶段如何最好地利用 CustomWindowStyle
,以及它是否提供对 NSWindow
的访问用于细粒度控制的实例。
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
// In AppKit simply create the NSWindow and modify style.
// In SwiftUI creating an NSWindow and styling results in 2 windows,
// one styled and the other default.
}
}
@main
struct testApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate : AppDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
虽然我不完全确定这是正确的方法,但基于对这个问题的回答:我已经能够访问 NSWindow
实例并修改它的外观。
为了快速参考,这里有一个基于 Asperi 使用 xcode 12.3
、swift 5.3
和 SwiftUI 应用程序生命周期提供的原始代码的工作示例。
@main
struct testApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class Store {
var window: NSWindow
init(window: NSWindow) {
self.window = window
self.window.isOpaque = false
self.window.backgroundColor = NSColor.clear
}
}
struct ContentView: View {
@State private var window: NSWindow?
var body: some View {
VStack {
Text("Loading...")
if nil != window {
MainView(store: Store(window: window!))
}
}.background(WindowAccessor(window: $window))
}
}
struct MainView: View {
let store: Store
var body: some View {
VStack {
Text("MainView with Window: \(store.window)")
}.frame(width: 400, height: 400)
}
}
struct WindowAccessor: NSViewRepresentable {
@Binding var window: NSWindow?
func makeNSView(context: Context) -> NSView {
let view = NSView()
DispatchQueue.main.async {
self.window = view.window
}
return view
}
func updateNSView(_ nsView: NSView, context: Context) {}
}
有趣的方法@hillmark。
我还使用 NSApplicationDelegateAdaptor
.
的方法得到了它
我相信下面的代码只会帮助您处理单个 window MacOS SwiftUI 应用程序 - 多个 window 应用程序可能需要处理所有 windows,而不仅仅是取第一个。
我也不确定我的方法是否有任何注意事项。
现在这正好解决了我的问题,但我也会检查你的方法。
import SwiftUI
final class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ notification: Notification) {
if let window = NSApplication.shared.windows.first {
window.titleVisibility = .hidden
window.titlebarAppearsTransparent = true
window.isOpaque = false
window.backgroundColor = NSColor.clear
}
}
}
@main
struct AlreadyMacOSApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
WindowGroup {
NewLayoutTest()
}
}
}
使用 xcode 12.3
和 swift 5.3
以及 SwiftUI App
生命周期来构建 macOS
应用程序,访问和更改外观和行为的最佳方式是什么NSWindow
?
编辑:我真正想要的是 NSWindow
实例。
我添加了一个AppDelegate
,但据我了解,NSWindow
很可能是nil
,因此无法修改,只是在这里创建一个类似于AppKit App Delegate
生命周期方法导致两个 windows 在启动时出现。
一个解决方案是阻止默认 window 出现,并将其全部留给 applicationDidFinishLaunching
方法,但不确定这是否可能或明智。
WindowStyle
协议看起来是一个可能的解决方案,但不确定现阶段如何最好地利用 CustomWindowStyle
,以及它是否提供对 NSWindow
的访问用于细粒度控制的实例。
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
// In AppKit simply create the NSWindow and modify style.
// In SwiftUI creating an NSWindow and styling results in 2 windows,
// one styled and the other default.
}
}
@main
struct testApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate : AppDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
虽然我不完全确定这是正确的方法,但基于对这个问题的回答:NSWindow
实例并修改它的外观。
为了快速参考,这里有一个基于 Asperi 使用 xcode 12.3
、swift 5.3
和 SwiftUI 应用程序生命周期提供的原始代码的工作示例。
@main
struct testApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class Store {
var window: NSWindow
init(window: NSWindow) {
self.window = window
self.window.isOpaque = false
self.window.backgroundColor = NSColor.clear
}
}
struct ContentView: View {
@State private var window: NSWindow?
var body: some View {
VStack {
Text("Loading...")
if nil != window {
MainView(store: Store(window: window!))
}
}.background(WindowAccessor(window: $window))
}
}
struct MainView: View {
let store: Store
var body: some View {
VStack {
Text("MainView with Window: \(store.window)")
}.frame(width: 400, height: 400)
}
}
struct WindowAccessor: NSViewRepresentable {
@Binding var window: NSWindow?
func makeNSView(context: Context) -> NSView {
let view = NSView()
DispatchQueue.main.async {
self.window = view.window
}
return view
}
func updateNSView(_ nsView: NSView, context: Context) {}
}
有趣的方法@hillmark。
我还使用 NSApplicationDelegateAdaptor
.
我相信下面的代码只会帮助您处理单个 window MacOS SwiftUI 应用程序 - 多个 window 应用程序可能需要处理所有 windows,而不仅仅是取第一个。
我也不确定我的方法是否有任何注意事项。
现在这正好解决了我的问题,但我也会检查你的方法。
import SwiftUI
final class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ notification: Notification) {
if let window = NSApplication.shared.windows.first {
window.titleVisibility = .hidden
window.titlebarAppearsTransparent = true
window.isOpaque = false
window.backgroundColor = NSColor.clear
}
}
}
@main
struct AlreadyMacOSApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
WindowGroup {
NewLayoutTest()
}
}
}