Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
412 views
in Technique[技术] by (71.8m points)

ios - What is a good way to bind a SwiftUI alert or action sheet to the optionality of a value type model property (show the view when the property is nil)?

SwiftUI alerts and action sheets take Boolean bindings, but I want mine to display when a model property is nil. The model property is var servicePlayer: Player!, and I want an alert or action sheet to be presented when the tennis serving player is not yet selected (nil), but I'm not sure what would be a good way to approach this.

My model layer is composed of value type structs, so at the moment marking the property as @Published isn't an option. It doesn't sound worth it refactoring my whole model layer to a class reference type to be able to adopt Combine (I depend on the model instances being value type copies for undoing and redoing), but I may be wrong.

struct Match: Codable {
    ...
    var servicePlayer: Player!
    ...
}

.alert(isPresented: $isPresented) {
    Alert(title: Text("Who will serve?"),
              primaryButton: .default(Text("You")) {
                match.servicePlayer = .playerOne
            },
              secondaryButton: .default(Text("Opponent")) {
                match.servicePlayer = .playerTwo
            })
}

The $isPresented binding is just a placeholder. Since servicePlayer starts out nil, the idea is for the alert to be initially presented, but also reappear later in the tennis match when service player is nil again and yet to be selected.

question from:https://stackoverflow.com/questions/65946899/what-is-a-good-way-to-bind-a-swiftui-alert-or-action-sheet-to-the-optionality-of

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As you probably understand, the isPresented parameter of .alert requires a Binding<Bool>.

I assume Match is a @State property in your view:

struct ContentView: View {
   @State var match: Match

   var body: some View { ... }
}

which means that when that changes, the view will recompute. This means that your particular case you can use Binding.constant(bool):

.alert(isPresented: .constant(match.servicePlayer == nil)) {
   Alert(...)
}

because the Alert will modify the state by changing match.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...