I have a problem in the following code, that whenever I use the Toggle()-Button the SettingsEx1View disappears and the Exercise1View() appears. They are connected with the ObservableObject Profile(). I get this error when starting the app, but it seems that is a bug with SwiftUI Apple has to fix. The weird thing is, that when I delete line 18 and 19
let osc = DynamicOscillator()
let audioEngine = AudioEngine()
it works perfectly fine. Is there something I have overlooked or do you know anything I could do? Any help is appreciated, thanks!!
import SwiftUI
import AVFoundation
import AudioKit
import SoundpipeAudioKit
import Foundation
class Profile: ObservableObject {
@Published var playSoundeffects = true
@Published var waveformIndex = 0
}
struct Exercise1View: View {
@EnvironmentObject var profile: Profile
let osc = DynamicOscillator()
let audioEngine = AudioEngine()
var body: some View {
NavigationLink(
destination: SettingsEx1View())
{
Image(systemName: "gearshape.circle")
}
.navigationTitle("Exercise1")
}
}
struct SettingsEx1View: View {
@EnvironmentObject var profile: Profile
let waveformOptions = ["sine", "triangle", "sawtooth", "square"]
var body: some View {
Form {
Section(header: Text("General")) {
Toggle("play soundeffects", isOn: $profile.playSoundeffects)
Picker("waveform", selection: $profile.waveformIndex) {
ForEach(0 ..< waveformOptions.count) {
Text(self.waveformOptions[$0])
}
}
}
}
.navigationTitle("Settings")
}
}
struct HomeScreen: View {
@EnvironmentObject var profile: Profile
@AppStorage("playSoundeffects") var playSoundeffectsSave: Bool = true
@AppStorage("waveform") var waveformIndexSave: Int = 0
var body: some View {
NavigationView{
NavigationLink(destination: Exercise1View())
{Text("Exercise1")}
}
.onAppear {
profile.playSoundeffects = playSoundeffectsSave
profile.waveformIndex = waveformIndexSave
}
.onChange(of: profile.playSoundeffects) { newValue in
playSoundeffectsSave = profile.playSoundeffects
}
.onChange(of: profile.waveformIndex) { newValue in
waveformIndexSave = profile.waveformIndex
}
}
}
struct ContentView: View {
var body: some View {
HomeScreen()
.environmentObject(Profile())
}
}
CodePudding user response:
The HomeScreen.body depends on Profile settings, so when latter updated it is refreshed and NavigationView is recreated as part of body, so its navigation stack destroyed.
As NavigationView does not depend on Profile itself a simplest solution is to separate it into stand-alone view, like
struct HomeScreen: View {
// ... other code
var body: some View {
MainView()
.onAppear {
profile.playSoundeffects = playSoundeffectsSave
// ... other code
}
struct MainView: View {
var body: some View {
NavigationView{ // << here !!
NavigationLink(destination: Exercise1View())
{Text("Exercise1")}
}
}
}
See also this for more info: https://stackoverflow.com/a/72824345/12299030
