无法在不可变值上使用突变成员:'self'在SwiftUI中是不可变的

时间:2019-09-28 06:39:21

标签: swiftui

对于以下代码,出现以下错误。我不知道该如何解决。点击按钮后如何呼叫volumeCheck()

struct ContentView: View {

    var player = AVAudioPlayer()

    var body: some View {
        HStack {
            Button(action: {
                self.volumeCheck()
            }) {
                Text("Click to test chimes volume")
            }
        }
    }

    mutating func volumeCheck() {
        guard let url = Bundle.main.url(
            forResource: "chimes",
            withExtension: "mp3"
            ) else { return }

        do {
            player = try AVAudioPlayer(contentsOf: url)
            player.prepareToPlay()
            player.volume = Float(self.sliderValue)
            player.play()
        } catch let error {
            print(error.localizedDescription)
        }
        print("volume checked print")
    }
}

2 个答案:

答案 0 :(得分:1)

您正在尝试将播放器设置为volumeCheck()中的新对象。在播放器中设置播放器:

struct ContentView: View {

    private var player: AVAudioPlayer?

    public init() {
        if let url = Bundle.main.url(forResource: "chimes",
                                     withExtension: "mp3") {
            self.player = try? AVAudioPlayer(contentsOf: url)
        }
    }

    var body: some View {
        HStack {
            Button("Click to test chimes volume") {
                self.volumeCheck()
                }   .disabled(player == nil)
        }
    }

    private func volumeCheck() {
        player?.prepareToPlay()
        player?.volume = Float(self.sliderValue)
        player?.play()
        print("volume checked print")
    }
}

请注意,即使未在任何地方定义它,您也在代码中使用sliderValue。

答案 1 :(得分:0)

问题在于Viewstruct,而body字段是具有 nonmutating 吸气剂的计算属性。在您的代码中,在该非突变型吸气剂中会调用 muting 方法。因此,您需要做的就是将播放器设置为某种模型:

class Model {
    var player: AVPlayerPlayer()
}

struct ContentView: View {

    var model = Model()

    // player can be changed from anywhere
}

P.S。在某些其他情况下,您可能希望模型中的更改反映在视图中,因此您必须在模型声明之前添加@ObservedObject。

希望有帮助