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!