SwiftUI 显示基于计算的警报 属性

SwiftUI show alert based on computed property

我正在尝试根据计算的 属性 在 Swift 中显示警报。基本上,只要用户单击按钮,"round" 的值就会更新。当发生超过 10 轮时,将显示警报。

为此,我创建了一个名为 "showingAlert" 的布尔变量。这必须是一个 @State var,以便在用户关闭警报时它再次设置为 false。

但是,编译器告诉我像@State "cannot be applied to a computed property" 这样的 属性 包装器 :-(

这是我试过的代码:


@State var round = 0
@State var showingAlert:Bool {round > 10 ? true : false}

func result(player: Int, app: Int) {
if player > app {
 round += 1
 }
else {
 round += 1
}
}

var body: some View {
        Button(action: {self.result(player: 1, app: 1)}) {
        Text("Button")
        }
           .alert(isPresented: $showingAlert) {
                Alert(title: Text("title"), message: Text("message"), dismissButton: .default(Text("Continue"))
                )
} 

有什么办法解决这个问题吗?我很想创建一个不显示错误消息的警报。

我更喜欢将逻辑放在模型中——逻辑与视图的分离——但这里有一些可行的方法:

@State var round = 0
@State var showingAlert:Bool = false

func result(player: Int, app: Int) {
    if player > app {
        round += 1
    } else {
        round += 1
    }
    if round > 10 {
        showingAlert.toggle()
    }
}

基本上,将检查 移到 您的函数中。备注:

  • 我假设这是测试逻辑...如果不是,则您的 if/else 有错字,因为它们都做同样的事情。
  • 仅将 showingAlert 设置为 true - 让 SwiftUI 在关闭警报时将其设置为 false。
  • 将此逻辑与视图分开的真正原因是您可以使事情变得容易重置 round。这是执行此操作的代码:
import SwiftUI
import Combine

class Model : ObservableObject {
    var objectWillChange = PassthroughSubject<Void, Never>()
    @Published var showingAlert = false {
        willSet {
            objectWillChange.send()
            if newValue == false {
                round = 0
            }
        }
    }
    var round = 0
    func result(player: Int, app: Int) {
        if player > app {
            round += 1
        } else {
            round += 1
        }
        if round > 10 {
            showingAlert.toggle()
        }
    }
}

struct ContentView: View {
    @EnvironmentObject var model: Model

    var body: some View {
        Button(action: {self.model.result(player: 1, app: 1)}) {
            Text("Button")
            }
        .alert(isPresented: self.$model.showingAlert) {
                Alert(title: Text("title"), message: Text("message"), dismissButton: .default(Text("Continue")))
            }
    }
}

请注意,只有一个变量 (showingAlert) 标记为 @Published,您可以根据 willSet 正确编码,并且您需要在 [=18= 中进行更改] 正在正确添加 EnvironmentObjectafter your add it to yourSceneDelegate`。

第一组代码将在第 11 次点击后显示警报,然后是之后的每次点击。第二组代码将在第 11 次点击后显示警报,之后每 11 次点击。

您可以简单地使用 Binding.constant(_:)。将计算 属性 转换为绑定 属性.


@State var round = 0
var showingAlert:Bool {round > 10 ? true : false}

func result(player: Int, app: Int) {
  if player > app {
   round += 1
   }
  else {
   round += 1
  }
}

var body: some View {
        Button(action: {self.result(player: 1, app: 1)}) {
        Text("Button")
        }
           .alert(isPresented: .constant(showingAlert)) {
                Alert(title: Text("title"), message: Text("message"), dismissButton: .default(Text("Continue"))
                )
}