f1()
onDisappear
似乎不会被调用
@main
struct DemoApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
Window("test", id: "test") {
Color.red
.onDisappear {
print("onDisappear")
f1()
}
}
}
func f1() {
print("f1 called")
}
}
struct ContentView: View {
@Environment(\.openWindow) private var openWindow
var body: some View {
Button("show red") {
openWindow(id: "test")
}
}
}
对于执行此操作的“SwiftUI 方式”,请查看环境属性
controlActiveState
。当窗口失去焦点以及窗口关闭时,该值将设置为 .inactive
。
struct ContentView: View {
@Environment(\.controlActiveState) private var controlActiveState
var body: some View {
Text("Hello, World!")
.onChange(of: controlActiveState) { newValue in
switch newValue {
case .key, .active:
break
case .inactive:
// Do your stuff.
@unknown default:
break
}
}
}
}
如果有人觉得这很有趣,我已经以不同的(可能更好)的方式解决了这个问题。
@main
struct DemoApp: App {
var body: some Scene {
Window("test", id: "test") {
Color.red
.task {
// perform action when window is opened
await Task.waitTillCancel()
// perform action after window is closed
}
}
}
}
extension Task where Success == Void, Failure == Never {
static func waitTillCancel() async {
let asyncStream = AsyncStream<Int> { _ in }
for await _ in asyncStream { }
}
}
根据 Apple 文档,
task(priority:_:)
修饰符创建一个与视图生命周期匹配的任务,并在视图被丢弃时取消。我们可以创建一个无限的AsyncStream
(空但从未完成)来等待任务被取消(因此在上面的示例中窗口被关闭),然后执行所需的操作。
我认为这是 SwiftUI 中唯一正确记录的情况,我们确实可以检测到窗口何时关闭。
您可以使用
NSWindow.willCloseNotification
通知:
struct ContentView: View {
var body: some View {
Text("xyz")
.onReceive(NotificationCenter.default.publisher(for: NSWindow.willCloseNotification)) { newValue in
print("close")
}
}
}
在 Swift
5.10
Xcode 15.3
onDismiss
似乎工作正常,我猜这只是实现上的一个错误。
关闭 Window
(手动或编程)时调用
onDismiss。
示例:
WindowGroup {
ContentView()
.onDisappear {
// window was closed
}
}