如何使用 swiftUI 设置最小 window 大小,以及如何使 window 在启动时使用指定的大小和位置?
How do I set the minimum window size with swiftUI, and how do I make the window use the specified size and position when launching?
我正在使用 swiftUI 制作一个 macOS 应用程序。我想将 window 的最小尺寸设置为 800、500。还有一点是,如果我关闭 window,然后重新打开,它会重新打开为上次关闭时的位置大小.我如何让它不记得上次关闭时的 window 位置和大小。我正在使用 Xcode 11.2.1 和 macOS Catalina,我正在为 macOS 而不是 iOS 制作应用程序。我该如何做这两件事?
如果您从基于 macOS SwiftUI 的模板创建项目,那么您需要做的所有更改都在 AppDelegate.swift。
window的大小是内容定义的,因此您需要指定根内容视图框架,并且要禁止window位置保存您需要删除setFrameAutosaveName
,作为结果您的 AppDelegate 应该如下所示
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView()
.frame(minWidth: 800, maxWidth: .infinity, minHeight: 500, maxHeight: .infinity)
// Create the window and set the content view.
window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 800, height: 500),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
window.center()
window.contentView = NSHostingView(rootView: contentView)
window.makeKeyAndOrderFront(nil)
}
...
更新: 对于 SwiftUI 生命周期方法是相同的 - 在 window 场景中将框架设置为内容视图,如
var body: some Scene {
WindowGroup {
ContentView()
.frame(minWidth: 800, maxWidth: .infinity, minHeight: 500, maxHeight: .infinity)
}
}
较新版本的 Xcode(和模板)现在使用 SwiftUI App 生命周期,而不是 AppKit App Delegate.在这种情况下,您可以使用 Layout.frame 方法设置 window 大小(或任何 SwiftUI 视图的大小)来设置边界。就像您使用任何修饰符一样:
VStack {
Text("You are Logged In")
Button(action: {
self.loggedIn = false
}, label: {
Text("Logout")
})
}
.frame(minWidth: 400, idealWidth: 600, minHeight: 450, idealHeight: 800)
同样,这可以与任何 SwiftUI 视图一起使用,因此它是布局视图的便捷方式。
编辑:此答案适用于所有平台,包括 macOS。
我正在使用 swiftUI 制作一个 macOS 应用程序。我想将 window 的最小尺寸设置为 800、500。还有一点是,如果我关闭 window,然后重新打开,它会重新打开为上次关闭时的位置大小.我如何让它不记得上次关闭时的 window 位置和大小。我正在使用 Xcode 11.2.1 和 macOS Catalina,我正在为 macOS 而不是 iOS 制作应用程序。我该如何做这两件事?
如果您从基于 macOS SwiftUI 的模板创建项目,那么您需要做的所有更改都在 AppDelegate.swift。
window的大小是内容定义的,因此您需要指定根内容视图框架,并且要禁止window位置保存您需要删除setFrameAutosaveName
,作为结果您的 AppDelegate 应该如下所示
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var window: NSWindow!
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Create the SwiftUI view that provides the window contents.
let contentView = ContentView()
.frame(minWidth: 800, maxWidth: .infinity, minHeight: 500, maxHeight: .infinity)
// Create the window and set the content view.
window = NSWindow(
contentRect: NSRect(x: 0, y: 0, width: 800, height: 500),
styleMask: [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView],
backing: .buffered, defer: false)
window.center()
window.contentView = NSHostingView(rootView: contentView)
window.makeKeyAndOrderFront(nil)
}
...
更新: 对于 SwiftUI 生命周期方法是相同的 - 在 window 场景中将框架设置为内容视图,如
var body: some Scene {
WindowGroup {
ContentView()
.frame(minWidth: 800, maxWidth: .infinity, minHeight: 500, maxHeight: .infinity)
}
}
较新版本的 Xcode(和模板)现在使用 SwiftUI App 生命周期,而不是 AppKit App Delegate.在这种情况下,您可以使用 Layout.frame 方法设置 window 大小(或任何 SwiftUI 视图的大小)来设置边界。就像您使用任何修饰符一样:
VStack {
Text("You are Logged In")
Button(action: {
self.loggedIn = false
}, label: {
Text("Logout")
})
}
.frame(minWidth: 400, idealWidth: 600, minHeight: 450, idealHeight: 800)
同样,这可以与任何 SwiftUI 视图一起使用,因此它是布局视图的便捷方式。
编辑:此答案适用于所有平台,包括 macOS。