swift 将滑块值存储到全局变量

quhf5bfb  于 2023-03-11  发布在  Swift
关注(0)|答案(1)|浏览(132)

在Swift程序中,我有几个嵌套的视图。在最底层的视图中,我有一个滑块。我想把它的值从这个视图传递到Swift主文件,在那里全局变量存储在一个结构中。这个值将用于控制使用AudioKit播放的音频的音量。
滑块的代码(此处未包括完整视图,因为其余部分无关紧要):

struct MasterFaderView: View {
    var body: some View {
        Slider(
            value: master.Value,
            in: 0...127,
            step: 1.0)
    }
}

正在设置的顶级全局变量:

struct channel {
    var Value: Double = 0.0             // Default fader value
    ... // Other variables being stored
}

var master = channel()

@main
struct MEngProjectApp: App {
    
    var body: some Scene {
        WindowGroup {
            FreePlayView()
        }
    }
}

FreePlayView()是包含audioKit内容的主视图,将控制音量:

class MixerClass: ObservableObject {
    let engine = AudioEngine()
    var fullTrack = AudioPlayer()
    
    init() {
        engine.output = fullTrack
        loadFiles()
        try? engine.start()
    }
    
    func loadFiles() {
        do {
            if let fileURL = Bundle.main.url(forResource: "DQ_FullTrack", withExtension: "wav") {
                try fullTrack.load(url: fileURL)
            } else {
                Log("Could not find file")
            }
        } catch {
            Log("Could not load full track")
        }
    }
}

struct FreePlayView: View {
    @StateObject var conductor = MixerClass()
    @State var trackPlaying: Bool = false
    
    var body: some View {
        Button(action: {
        if trackPlaying == false {
            conductor.fullTrack.start()
            conductor.fullTrack.volume = master.Value
            trackPlaying = true
        } else {
            conductor.fullTrack.stop()
            trackPlaying = false
        }
   }) {
      Text("Start Audio")
   }

我在MasterFaderView中得到的错误代码是Cannot convert value of type 'Double' to expected argument type 'Binding<Double>'
有人知道怎么解决吗?
先谢了。

3zwjbxry

3zwjbxry1#

要在App中的不同位置使用变量,可以使用ObservableObject类,类中有@Published var value: Double = 0.0,如class ChannelModel: ObservableObject所示,只要value发生变化,界面就会刷新。
在您的应用中声明此ChannelModel,并使用.environmentObject(channelModel)@EnvironmentObject var channel: ChannelModel传递它,如FreePlayViewMasterFaderView所示。
下面是此方法的一些示例代码:

@main
struct MEngProjectApp: App {
    @StateObject var channelModel = ChannelModel() // <-- here

    var body: some Scene {
        WindowGroup {
            FreePlayView()
                .environmentObject(channelModel)  // <-- here
        }
    }
}

class ChannelModel: ObservableObject {  // <-- here
    @Published var value: Double = 0.0  // <-- here
    // ... Other variables being stored
}

struct FreePlayView: View {
    @EnvironmentObject var channelModel: ChannelModel  // <-- here
    
    @StateObject var conductor = MixerClass()
    @State var trackPlaying: Bool = false
    
    var body: some View {
        Button(action: {
            if trackPlaying == false {
                conductor.fullTrack.start()
                conductor.fullTrack.volume = channelModel.value  // <-- here
                trackPlaying = true
            } else {
                conductor.fullTrack.stop()
                trackPlaying = false
            }
        }) {
            Text("Start Audio")
        }
    }
}

struct MasterFaderView: View {
    @EnvironmentObject var channelModel: ChannelModel  // <-- here
    
    var body: some View {
        Slider(value: $channelModel.value, in: 0...127, step: 1.0)  // <-- here
    }
}

相关问题