首页 > 解决方案 > SwiftUI for macOS - 触发表 .onDismiss 问题

问题描述

在一个多平台应用程序中,我展示了一张用于收集少量用户输入的表格。在 iOS 上,当工作表被关闭时,.onDismiss会调用相关方法,但在 macOS 上不会。

我已经读到有.onDismissinList可能会导致问题,所以我将它附加到按钮本身而没有任何改进。我也尝试过通过isPresented绑定并在工作表本身内切换它以将其关闭,但再次没有成功。

我正在使用一个NavigationView但删除它没有任何区别。以下简化示例演示了我的问题。有任何想法吗?我是否应该在 macOS 上为此使用工作表?

我只是想明确一点,关闭工作表没有问题。我发现的其他问题是关于关闭工作表的问题 - 我可以做到这一点。

import SwiftUI

@main
struct SheetTestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            ListView()
        }
    }
}

列表视图。

struct ListView: View {
    
    @State private var isPresented: Bool = false
    
    var body: some View {
        VStack {
            Text("Patterns").font(.title)
            
            Button(action: {
                isPresented = true
            }, label: {
                Text("Add")
            })
            .sheet(isPresented: $isPresented, onDismiss: {
                doSomethingAfter()
            }) {
                TestSheetView()
            }
            
            List {
                Text("Bingo")
                Text("Bongo")
                Text("Banjo")
            }
            .onAppear(perform: {
                doSomethingBefore()
            })
        }
    }
    
    func doSomethingBefore() {
        print("Johnny")
    }
    
    func doSomethingAfter() {
        print("Cash")
    }
}

这是工作表视图。

struct TestSheetView: View {
    
    @Environment(\.presentationMode) var presentationMode
    
    @State private var name = ""
    
    var body: some View {
        Form {
            TextField("Enter name", text: $name)
                .padding()
            
            HStack {
                Spacer()
                Button("Save") {
                    presentationMode.wrappedValue.dismiss()
                }
                Spacer()
            }
        }
        .frame(minWidth: 300, minHeight: 300)
        .navigationTitle("Jedward")
    }
}

标签: macosviewswiftuimodal-dialog

解决方案


坏问题..你是对的。不调用 OnDismiss。这是 Proxybinding 的解决方法

var body: some View {
    VStack {
        Text("Patterns").font(.title)
        
        Button(action: {
            isPresented = true
        }, label: {
            Text("Add")
        })
        
        List {
            Text("Bingo")
            Text("Bongo")
            Text("Banjo")
        }
        .onAppear(perform: {
            doSomethingBefore()
        })
    }
    .sheet(isPresented: Binding<Bool>(
            get: {
                isPresented
            }, set: {
                isPresented = $0
                if !$0 {
                    doSomethingAfter()
                }
            })) {
        TestSheetView()
    }
}

推荐阅读