Ios 动态更改SwiftUI列表中行的颜色

Ios 动态更改SwiftUI列表中行的颜色,ios,swiftui,swiftui-list,Ios,Swiftui,Swiftui List,在SwiftUI应用程序中,我想做以下工作,我想知道如何解决这个问题。我希望有人能给我一个提示 我有一个七八行的列表,下面是一个按钮。当我点击按钮时,应用程序会播放音频文件(每行一个)。这已经起作用了 以下是我想要实现的: 当我点击按钮时,我希望在播放匹配的音频文件时,每一行一行地改变颜色 声音文件由下面的类处理,该类使用AudioPlayerDidFinishPlay方法来检测文件播放何时结束 class AudioEngine: NSObject,ObservableObject,AVAud

在SwiftUI应用程序中,我想做以下工作,我想知道如何解决这个问题。我希望有人能给我一个提示

我有一个七八行的列表,下面是一个按钮。当我点击按钮时,应用程序会播放音频文件(每行一个)。这已经起作用了

以下是我想要实现的: 当我点击按钮时,我希望在播放匹配的音频文件时,每一行一行地改变颜色

声音文件由下面的类处理,该类使用AudioPlayerDidFinishPlay方法来检测文件播放何时结束

class AudioEngine: NSObject,ObservableObject,AVAudioPlayerDelegate {
    @Published var isPlaying:Bool = false {
        willSet {
            if newValue == true {
                playAudio()
            }
        }
    }
    ....
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer,   successfully flag: Bool) {
        ....
    }
}
AudioEngine的实例是通过以下方式创建的:

let soundManager = AudioEngine()
........
这将显示带有列表和按钮的视图:

VStack {
    // Display the list of items:
    ListItemsView(sentenceList: sntncLst, moc: moc)
    // Display the button to play all the items:
    Button(action: {
        if !soundManager.isPlaying {self.playAllAudio(sntncLst)}
        else {soundManager.stopAudio()}
    })
    {
        Image(uiImage: UIImage(named: "speaker.png")!)
            .padding(.bottom, 17)
    }
}
....

func playAllAudio(_ sndList:[AudioList]) {
    for sentence in sndList {
        soundManager.filesArray.append(sentence.soundFile!)
    }
    soundManager.serialPlayAudio()
}

在SwiftUI中,您需要正确地设置模型。你能展示一下你的模型吗?例如,假设它有一个项目数组;这些项目应该是结构或对象,带有音频文件的详细信息(名称等)和
isplay
boolean。现在,只要您的
isPlaying
boolean根据播放状态为true/false,您的SwiftUI视图就会检查它并呈现适当的颜色。诀窍是在
didfishplaying
delegate方法中更新模型。我在帖子中添加了一些更相关的代码。我在AudioEngine类中有一个isPlaying标志。但不是针对列表中的每一行。如果查看playAllAudio函数的内部,可以看到soundManager.serialPlayAudio()负责播放所有音频文件。soundManager应该有一种方法让列表视图知道给定的音频文件已经开始或结束播放。您的视图不应该知道有关soundManager的任何信息。您的视图模型应该有声音列表和声音管理器参考。视图要求视图模型播放声音;视图模型询问声音管理器。您需要为声音管理器提供一种方法,让视图模型知道声音何时结束或新声音何时开始播放-我建议视图模型向声音管理器提供闭包来完成此操作。然后,视图模型将更新发布的属性
nowPlaying
@Published。然后,视图需要生成列表,并将每个列表项与您编写的“视图模型为声音管理器提供闭包”进行比较。你到底是怎么做到的?您有什么例子吗?在您的声音管理器中,您可以声明一个属性something
var soundDidEndHandler:((AudioList)->Void)
,然后在您的模型中为该属性指定一个闭包。在
didfishplaying
delegate方法中,您可以调用closure
self.soundDidEndHandler?(currentAudio)