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