Home > front end >  Is there a simpler way to zip two .onReceive in swiftui
Is there a simpler way to zip two .onReceive in swiftui

Time:01-27

@State private var showUpEmotion = false
@State private var showDownEmotion = false

When two pieces of data from an observableobject come online some view is shown

HStack {
    if showUpEmotion && showDownEmotion
    {
          SomeViewIsShown()
    }
}
.onReceive(model.$meLike) { value in
                        withAnimation {
                            if value != nil {
                                showUpEmotion = true
                            } else {
                                showUpEmotion = false
                            }
                        }
}
.onReceive(model.$meDislike) { value in
                        withAnimation {
                            if value != nil {
                                showDownEmotion = true
                            } else {
                                showDownEmotion = false
                            }
                        }
                    }

Is there a simpler/cleaner way to zip that data from ObservableObject ? naturally withAnimation does not compile in the observableobject proper -> I have to use that inside the view :(

CodePudding user response:

It's not clear from the question what you're trying to achieve, but possibly moving some of your Bools into structs would simplify?

struct ShowEmotions {
    var up = false
    var down = false

    var both: Bool {
        up && down
    }
}

struct Likes {
    var like = false
    var dislike = false
}

class Model: ObservableObject {
    @Published var me = Likes()
}

struct ContentView: View {
    @State private var showEmotions = ShowEmotions()
    @StateObject var model = Model()
        
    var body: some View {
        HStack {
            if showEmotions.both {
                SomeViewIsShown()
            }
        }
        .onReceive(model.$me) { me in
            withAnimation {
                showEmotions.up = me.like
                showEmotions.down = me.dislike
            }
        }
    }
}

This way you only need a single onReceive

  • Related