SwiftUI 警报无法在 MacOS 菜单栏应用程序中正确显示

问题描述 投票:0回答:1

我正在 Mac 上开发一个简单的菜单栏应用程序。它有一个窗口,其中包含一个按钮,上面写着“做某事”,当然,是为了模拟网络请求。在所述请求期间,可能会发生错误,在这种情况下,警报应显示包含详细信息的信息。此错误来自 ViewModel,每当将其从 nil 设置为字符串值时,就会出现警报。

警报中的“OK”按钮应通过将视图模型的错误消息设置回 nil 来关闭警报。

这是我对 ViewModel.swift 文件的实现:

import Foundation

@Observable
class ViewModel {
    var errorMessage: String?
    
    func doSomething() {
        self.errorMessage = "The image could not be downloaded"
    }
}

这是我的 ContentView.swift

import SwiftUI

struct ContentView: View {
    @State var viewModel = ViewModel()
    var body: some View {
        VStack {
            Button("Do something") {
                viewModel.doSomething()
            }
        }
        .alert(viewModel.errorMessage ?? "", isPresented: Binding(get: {
            viewModel.errorMessage != nil
        }, set: { value in
            viewModel.errorMessage = nil
        })) {
            Button("OK") {
                viewModel.errorMessage = nil
                // Here the view should be refreshed, then the "viewModel.errorMessage != nil" would hide the alert
            }
        }
    }
}

以及应用程序入口点

@main
struct Macos_SwiftUI_Alert_issueApp: App {
    var body: some Scene {
        MenuBarExtra("", systemImage: "square.fill") {
            ContentView()
                .frame(width: 500, height: 500)
        }
        .menuBarExtraStyle(.window)
    }
}

我的问题:

我在视图中按下“执行某些操作”按钮(这会导致出现警报),但是当我按下警报中的“确定”按钮时,整个应用程序视图都会消失,而不仅仅是警报消失。此外,当我再次打开菜单栏应用程序时,警报仍然存在。当我第二次按“确定”后,整个视图再次消失,第三次打开我的应用程序时,警报终于消失了。有人以前见过这个或者有解决办法吗?提前致谢。也许我什至不应该使用警报来显示错误消息......?

enter image description here

swift macos swiftui alert menubarextra
1个回答
0
投票

@State
应该是一个结构体,并在显示某些内容时使用
sheet(item:)
,例如

struct Content {
    var errorMessage: String?
    
    mutating func doSomething() {
        self.errorMessage = "The image could not be downloaded"
    }
}
struct ContentView: View {

    @State var content = Content()

    var body: some View {
        VStack {
            Button("Do something") {
                content.doSomething()
            }
        }
        .alert(item: $content.errorMessage)
© www.soinside.com 2019 - 2024. All rights reserved.