SwiftUI sheet 没有在 macOS Big Sur 上动画解雇

SwiftUI sheet not animating dismissal on macOS Big Sur

我想要 sheet 解雇动画就像外观一样但相反。我认为这也是标准行为。例如,当您创建一个新文件时,您可以在 Xcode 中看到它。

但是如你所见,它只是在没有动画的情况下消失了

这是我的代码:

struct ContentView: View {

    @State var isAnotherViewPresented: Bool = false

    var body: some View {
        HStack {
            Button(action: {
                isAnotherViewPresented.toggle()
            }, label: {
                Text("Button")
            }).sheet(isPresented: $isAnotherViewPresented, content: {
                AnotherView()
            })
        }
        .frame(width: 500, height: 300, alignment: .center)
    }
}

struct AnotherView: View {

    @Environment(\.presentationMode) var presentationMode

    var body: some View {
        VStack {
            Button(action: {
                presentationMode.wrappedValue.dismiss()
            }, label: {
                Text("Close")
            })
        }.padding()
    }
}

我在

但我可以在

上复制它

免责声明: 我 had/have 同样的问题,如果我尝试通过绑定关闭 sheet,它只会消失而不是有动画.以下解决方案对我有用,但我不清楚它为什么起作用。

解决方案

显然,您将模态“附加”到的视图会影响它如何从呈现状态过渡到不呈现状态。例如,在您的代码中,sheet 附加到按钮视图:

Button(action: {
  isAnotherViewPresented.toggle()
 }, label: {
   Text("Button")
      // sheet is attached here
 }).sheet(isPresented: $isAnotherViewPresented, content: {
    AnotherView()
})

当您在第二个视图中调用 presentationMode.wrappedValue.dismiss() 时,模态会震动并消失,而不是滑开。但是,如果您将 sheet 附加到外部 HStack 视图,那么它会正常工作并按预期滑开:

var body: some View {
    HStack {
        Button(action: {
            isAnotherViewPresented.toggle()
        }, label: {
            Text("Button")
        })
    }
    .frame(width: 500, height: 300, alignment: .center)
    .sheet(isPresented: $isAnotherViewPresented, content: {
       AnotherView()
    })
    // sheet is now here
}

对我来说,只要 sheet 没有附加到按钮上,动画就会起作用。我不知道为什么会这样,但它对我有用,希望对你也有用。

我终于想出了怎么做,在我的 SwiftUI 应用程序中,如果我在关闭 sheet:

isSheetVisible = false
NSApp.mainWindow?.endSheet(NSApp.keyWindow!)

示例:

struct SheetView: View {
    @Binding var isSheetVisible: Bool

    var body: some View {
        Button("Close") {
            isSheetVisible = false
            NSApp.mainWindow?.endSheet(NSApp.keyWindow!)
        }
    }
}

我喜欢这个组合:

假设你有:

@Environment(\.presentationMode) var presentationMode

然后:

presentationMode.wrappedValue.dismiss() // this updates the binding from .sheet(isPresented: ...) to false
NSApp.mainWindow?.endSheet(NSApp.keyWindow!) // this runs the animation