BLACK FRIDAY: Save 50% on all my Swift books and bundles! >>

SOLVED: .sheet dismisses itself as soon as it opens

Forums > SwiftUI

I am trying to open a sheet with the summary of a times tables quiz for the day 35 challenge. But whenever it opens it closes immediately.

Thankyou in advance:

PlayView (This opens the sheet)

import SwiftUI

struct PlayView: View {
    @ObservedObject var variable: variables
    @State private var number1 = 8
    @State private var number2 = 2
    @State private var answer = 0
    @State private var givenAnswer = ""

    @State private var doneQuestions = 0

    @State private var showingSheet = false
    var comparableAnswer: Int{
        Int(givenAnswer) ?? 0
    }
    var body: some View {
        ZStack{
            LinearGradient(colors: [.blue, .white], startPoint: .top, endPoint: .bottom)
                .ignoresSafeArea()
            ZStack{
            VStack(spacing: 40){
                HStack{
                    Spacer()
                Text("\(variable.correct)")
                        .padding(20)
                        .background(.green)
                        .clipShape(RoundedRectangle(cornerRadius: 20))
                    Text("\(variable.wrong)")
                        .padding(20)
                        .background(.red)
                        .clipShape(RoundedRectangle(cornerRadius: 20))
                }.padding()
                Text("Question: ").font(.largeTitle)
                Text("\(number1) X \(number2)").font(.largeTitle)
                TextField("Enter Answer", text: $givenAnswer)
                    .font(.largeTitle)
                Button("Submit"){
                    if (comparableAnswer == answer){
                        variable.correct += 1
                    }else {
                        variable.wrong += 1
                    }
                    newQuestion()
                    doneQuestions += 1
                    if (doneQuestions == variable.questions){
                        variable.playing = false
                        doneQuestions = 0
                        showingSheet = true
                    }
                }.font(.largeTitle).padding(10).background(.blue).foregroundColor(.white).clipShape(Capsule())

            }
            .sheet(isPresented: $showingSheet) {
                Summaryiew(variable: variable)
            }
            .frame(width: 300, height: 440)
            .padding()
            .background(.ultraThinMaterial)
            .clipShape(RoundedRectangle(cornerRadius: 50))

            }.padding()
        }
        .onAppear(){
            newQuestion()
        }
    }
    func newQuestion() {
        number1 = variable.table
        number2 = Int.random(in: 2..<13)
        answer = number1 * number2
    }
}

struct PlayView_Previews: PreviewProvider {
    static var previews: some View {
        PlayView(variable: variables())
    }
}

SummaryView(What the sheet opens)

import SwiftUI

struct Summaryiew: View {
    @ObservedObject var variable: variables
    var body: some View {
        ZStack{
            LinearGradient(colors: [.blue,.white], startPoint: .top, endPoint: .bottom)
                .ignoresSafeArea()
            VStack(spacing: 20){
                Button("Next"){
                    variable.playing = false
                    variable.wrong = 0
                    variable.correct = 0
                }.padding().font(.largeTitle).foregroundColor(.white).background(.blue).clipShape(RoundedRectangle(cornerRadius: 20))
                Text("Well Done").font(.largeTitle).foregroundColor(.white)
                HStack{
                    Text("Correct:").font(.largeTitle)
                    Text("\(variable.correct)").padding().foregroundColor(.white).background(.green).font(.largeTitle).clipShape(RoundedRectangle(cornerRadius: 15))
                }
                HStack{
                    Text("Wrong:").font(.largeTitle)
                    Text("\(variable.wrong)").padding().foregroundColor(.white).background(.red).font(.largeTitle).clipShape(RoundedRectangle(cornerRadius: 15))
                }

            }
        }
    }
}

struct Summaryiew_Previews: PreviewProvider {
    static var previews: some View {
        Summaryiew(variable: variables())
    }
}

2      

Your state value change right before showing the sheet is causing a redraw on the View, thus resetting the state Bool to false, methinks. Try decoupling the state changes you make before it, or DispatchQueue.main.async{...}'ing the Bool change to show. In short, though, your best time spent is some redesign work, and ensure that your button push's only real responsibility is to set that Bool to true to show the Sheet. That's your biggest issue - making state changes, then showing a Sheet (or anything else) right on the heels of that while the View is redraw(n / ing)

2      

All of this....

Button("Submit"){
    if (comparableAnswer == answer){
        variable.correct += 1
    }else {
        variable.wrong += 1
    }
    newQuestion()
    doneQuestions += 1
    if (doneQuestions == variable.questions){
        variable.playing = false
        doneQuestions = 0
        showingSheet = true
    }
}

... is your problem.

Maybe consider making the State changes (that cause the View redraw) as the after-the-sheet-is-dismissed functionality.

.sheet(isPresented: $showingSheet) {
    // your state updates go here
} content: {
    // your sheet content goes here
}

Like... deal with all the stuff involving THIS question here and now, THEN prep, calculate scores (etc), for the View draw on the next question.

So to expand on your ideal here, ask the question, get the the answer, show the subview with parent view's data + new values without changing the old values, then on dismiss, update the old values, pluck the new question, redraw.

Doing your user-visibile View updates after the sheet goes away is perfectly fine since (in theory, not having seen your sheet content), the Sheet covers the current View (or at least obscures it enough) that the updates having later don't matter - and may make for a more cohesive workflow anyway.

$.02

(the design just needs more thought put into it, in terms of flow and how the data informs the draw)

3      

To expand... state, and all incoming information should inform the View how to draw itself, rather than being some fungible pool of bits that each view can swizzle around at a whim. If you go into SwiftUI with the mindset that "every single thing I touch will make this View draw again", you can start to see why extra-View data manipulation, and pre-View ducks-in-a-row setup becomes an early-in-the-design consideration, long before you start writing the code.

2      

Save 50% in my WWDC sale.

SAVE 50% All our books and bundles are half price for Black Friday, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.