Home > Blockchain >  How to create a button that can be pressed repeatedly for new views? [SwiftUI]
How to create a button that can be pressed repeatedly for new views? [SwiftUI]

Time:02-06

I have a button ("Next Word") that when pressed shows a new view ("PracticeResult"). The idea is that everytime you press it, a new random word appears on the screen. But so far, I have to press the button twice to get it to show the next image because it's triggered with a boolean state.

I've tried changing the State back to false with an ".onAppear" toggle but it doesn't work. I've also tried using an origin State to toggle the variable back to false but it hasn't worked either. I'm quite new to SwiftUI so any tips would be appreciated! Thanks in advance.

struct PracticeView: View {
    @State var isTapped: Bool = false
    
    var body: some View {
        NavigationView {
            ZStack {
                Color.white
                VStack() {
                    Image("lightlogolong")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: 300.0, height: 100.0)
                        .cornerRadius(100)
                        .animation(.easeIn, value: 10)
                    
                    NavigationLink(destination:
                        ContentView().navigationBarBackButtonHidden(true) {
                        HomeButton()
                    }

                    Group {
                        if (isTapped == true){
                            PracticeResult()      
                        }
                    }.onAppear{
                        isTapped.toggle()
                    }

                    Button("Next Word", action:{
                        self.isTapped.toggle()
                    })
                    .padding()
                    .frame(width: 150.0, height: 40.0)
                    .font(.title2)
                    .accentColor(.black)
                    .background(Color("appblue"))
                    .clipShape(Capsule())

                }
            }
        }
    }
}

CodePudding user response:

You could try this simple approach, using a UUID or something like it, to trigger your PracticeResult view every time you tap the button. Note in particular the PracticeResult().id(isTapped)

 struct PracticeView: View {
     @State var isTapped: UUID? // <--- here
     
     var body: some View {
         NavigationView {
             ZStack {
                 Color.white
                 VStack() {
                     Image("lightlogolong")
                         .resizable()
                         .aspectRatio(contentMode: .fit)
                         .frame(width: 300.0, height: 100.0)
                         .cornerRadius(100)
                         .animation(.easeIn, value: 10)

                     NavigationLink(destination:
                         ContentView().navigationBarBackButtonHidden(true) {
                         HomeButton()
                     }
  
                     if isTapped != nil {
                         PracticeResult().id(isTapped)  // <--- here
                     }
                     
                     Button("Next Word", action:{
                         isTapped = UUID()  // <--- here
                     })
                     .padding()
                     .frame(width: 150.0, height: 40.0)
                     .font(.title2)
                     .accentColor(.black)
                     .background(Color.blue)
                     .clipShape(Capsule())
                 }
             }
         }
     }
 }

 // for testing
 struct PracticeResult: View {
    @State var randomWord: String = UUID().uuidString
    var body: some View {
       Text(randomWord)
   }
}

CodePudding user response:

if you want your button trigger a new random word appears on the screen, you should use button to change that random word

for example (you can try it on Preview):

struct PracticeView: View {
    let words = ["one","two","three"]
    @State var wordToDisplay: String?
    
    var body: some View {
        VStack {
            if let wordToDisplay = wordToDisplay {
                Text(wordToDisplay)
            }
            Spacer()
            Button("Next Word") {
                wordToDisplay = words.filter { $0 != wordToDisplay }.randomElement()
            }
        }.frame(height: 50)
    }
}
  • Related