1

I'm trying to update a view in Swift and I can't figure out how to make it work. My app has questions, which are loaded from Core data. From there, a random question should be displayed at the top. After saving the answer (by pressing the Button with action: save), a new random question should be displayed.

struct RecordView: View {
@Environment(\.managedObjectContext) var moc


@FetchRequest(entity: Question.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Question.question, ascending: false)])
var questions: FetchedResults<Question>
var currentQuestion: String { return questions.randomElement()!.question! }

@State private var newEntryText = ""


    var body: some View {
         VStack {
            Section(header: Text(currentQuestion)){
                       TextField("New entry", text: self.$newEntryText)
                        .padding(100)

                       HStack {
                           SwiftSpeech.RecordButton().scaleEffect(0.8).swiftSpeechToggleRecordingOnTap(locale: Locale(identifier: "de"), animation: .spring(response: 0.3, dampingFraction: 0.5, blendDuration: 0))
                               .onRecognize(update: self.$newEntryText)

                        Button(action: save)
                           {
                            Image(systemName: "plus.circle.fill").foregroundColor(.green).imageScale(.large).scaleEffect(2.0)
                               }

                       }
                   }.automaticEnvironmentForSpeechRecognition()
    }
}

    func save() {
        let newEntry = Entry(context: self.moc)
             newEntry.text = self.newEntryText
             newEntry.createdAt = Date()
        do {
            try self.moc.save()
        }catch{
            print(error)
        }
        self.newEntryText = ""
        print(currentQuestion)

    }

What I tried:

1) @State var currentQuestion: String = questions.randomElement()!.question!-> Cannot use instance member 'questions' within property initializer; property initializers run before 'self' is available. Here the problems seems to be that the questions array has to be loaded first.
2) var currentQuestion: String { return questions.randomElement()!.question! } -> Here the currentQuestion is recomputed every time it is accessed, but the View does not update. Same thing if I move the questions.randomElement()!.question! to the Text() component.
3) lazy var currentQuestion = questions.randomElement()!.question!-> Cannot use mutating getter on immutable value: 'self' is immutable (at the Text() component). The lazy part should have solved the problem I have at the 1) solution, but then I cannot use it at the Text() component.

... and some other minor variations. I'm a Swift/Swift UI Beginner, and I am running out of ideas how to update the displayed current question everytime the button is pressed. Does anyone has an idea for this?
Many thanks!

1 Answer 1

2

Try the following (scratchy)

@State var currentQuestion: String = "" // as state !!

var body: some View {
    VStack {
        Section(header: Text(currentQuestion)){

           // ... other your code here

        }.automaticEnvironmentForSpeechRecognition()
    }.onAppear {
        self.nextQuestion()    // << here !!
    }
}

...

func save() {
    // ... other your code here

   self.nextQuestion()         // << here !!
}

private func nextQuestion() {
   self.currentQuestion = questions.randomElement()?.question ?? ""
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.