1

I have the following code below to show a Message to the user and then disappear. Everything works fine for the first 1 to 3 tries, but anything above that the Message window does not disappear as it did on the previous attempts/required.

struct ContentView: View {
    @State var showingNotice = false

    var body: some View {
        ZStack {
            Button(action: {
                self.showingNotice = true
            }, label: {
                Text("Show Notice")
            })

            if showingNotice {
                FloatingNotice(showingNotice: $showingNotice)
            }
        }
        .animation(.easeInOut(duration: 1))
    }
}

struct FloatingNotice: View {
    @Binding var showingNotice: Bool

    var body: some View {
        VStack (alignment: .center, spacing: 8) {
            Image(systemName: "checkmark")
                .foregroundColor(.white)
                .font(.system(size: 48, weight: .regular))
                .padding(EdgeInsets(top: 20, leading: 5, bottom: 5, trailing: 5))
        
            Text("Review added")
                .foregroundColor(.white)
                .font(.callout)
                .padding(EdgeInsets(top: 0, leading: 10, bottom: 5, trailing: 10))
        }
        .background(Color.snackbar.opacity(0.75))
        .cornerRadius(5)
        .transition(.scale)
        .onAppear(perform: {
            DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
                self.showingNotice = false
            })
        })
    }
}

Can anyone see what I am missing or help figure why it "stops" working after multiple executions?

Learn2Code
  • 1,974
  • 5
  • 24
  • 46
  • 1
    Are you using which xCode and iOS version? – Purvesh Dodiya Nov 13 '22 at 13:35
  • 1
    Put a print as the first line in onAppear. Is it being called when you expect? Add an onAppear to the FloatingNotice in ContentView with a print and see what that does – Lou Franco Nov 13 '22 at 13:42
  • 1
    @PurveshDodiya Version 14.1 (14B47b) – Learn2Code Nov 13 '22 at 13:42
  • It seems to only not disappear for me if I click the button when it is in the middle of the disappearing animation. If I wait for it to fully disappear then press the button again, it works no matter how many times I press it. – Sweeper Nov 13 '22 at 13:47
  • @LouFranco i put in the print statement and after a number of times the print statement didnt print and the message didnt go away!? The solution that purvesh provided did the trick tho!! – Learn2Code Nov 13 '22 at 14:04

1 Answers1

3

Sometimes onAppear will not called so your self.showingNotice = false is not getting called. So you can do one thing move your delay block inside the button click it self as below.

struct ContentView: View {
    @State var showingNotice = false

    var body: some View {
        ZStack {
            Button(action: {
                self.showingNotice = true
                DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
                    self.showingNotice = false
                })
            }, label: {
                Text("Show Notice")
            })

            if showingNotice {
                FloatingNotice(showingNotice: $showingNotice)
            }
        }
        .animation(.easeInOut(duration: 1))
    }
}

struct FloatingNotice: View {
    @Binding var showingNotice: Bool

    var body: some View {
        VStack (alignment: .center, spacing: 8) {
            Image(systemName: "checkmark")
                .foregroundColor(.white)
                .font(.system(size: 48, weight: .regular))
                .padding(EdgeInsets(top: 20, leading: 5, bottom: 5, trailing: 5))
               
        
            Text("Review added")
                .foregroundColor(.white)
                .font(.callout)
                .padding(EdgeInsets(top: 0, leading: 10, bottom: 5, trailing: 10))
        }
        .background(Color(.red))
        .cornerRadius(5)
        .transition(.scale)
        
    }
}


Purvesh Dodiya
  • 594
  • 3
  • 17