Swift UI: обновить представление случайным элементом из массива - PullRequest
1 голос
/ 30 мая 2020

Я пытаюсь обновить представление в Swift и не могу понять, как заставить его работать. В моем приложении есть вопросы, которые загружаются из Core data. Оттуда вверху должен отображаться случайный вопрос. После сохранения ответа (нажав кнопку с действием: сохранить) должен отобразиться новый случайный вопрос.

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)

    }

Что я пробовал:

1) @State var currentQuestion: String = questions.randomElement()!.question! -> Невозможно используйте "вопросы" члена экземпляра в инициализаторе свойства; Инициализаторы свойств запускаются до того, как станет доступным "self". Здесь проблема, похоже, заключается в том, что сначала должен быть загружен массив вопросов.
2) var currentQuestion: String { return questions.randomElement()!.question! } -> Здесь currentQuestion пересчитывается каждый раз, когда к нему обращаются, но представление не обновляется. То же самое, если я перемещу вопрос questions.randomElement () !.! в компонент Text ().
3) lazy var currentQuestion = questions.randomElement()!.question! -> Невозможно использовать изменяющийся геттер для неизменяемого значения: 'self' неизменяем (в компоненте Text ()). Ленивая часть должна была решить проблему, которая есть у меня в решении 1), но тогда я не могу использовать ее в компоненте Text ().

... и некоторые другие незначительные изменения. Я новичок в Swift / Swift UI, и у меня заканчиваются идеи, как обновлять отображаемый текущий вопрос каждый раз при нажатии кнопки. Есть у кого-нибудь на это идеи?
Большое спасибо!

1 Ответ

2 голосов
/ 30 мая 2020

Попробуйте следующее (царапается)

@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 ?? ""
}
...