如何解决在 SwiftUI 中播放音频时无法更新行颜色
在使用 iOS
开发 SwiftUI
应用程序时,我面临以下情况。我已经设置了一个自定义环境键。这是 SceneDelegate.swift 文件中的相关代码。
private struct RowColorMaster: EnvironmentKey {
static var defaultValue: Binding<[[String:Color]]> = .constant([[:]])
}
extension EnvironmentValues {
var rowColorMasterDico: Binding<[[String:Color]]> {
get {self[RowColorMaster.self]}
set {self[RowColorMaster.self] = newValue}
}
}
class SceneDelegate: UIResponder,UIWindowSceneDelegate {
var window: UIWindow?
var rowColorMasterDico:[[String:Color]] = []
func scene(_ scene: UIScene,willConnectTo session: UIScenesession,options connectionoptions: UIScene.Connectionoptions) {
.....
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
.....
rowColorMasterDico = .....
print("rowColorMasterDico -> \(rowColorMasterDico.count)")
let contentView = ContentView(sectionsList: sectionsList,itemmasterList: sentceMasterarray)
.environment(\.managedobjectContext,context)
.environment(\.rowColorMasterDico,Binding(get: {self.rowColorMasterDico},set: {
newValue in
self.rowColorMasterDico = newValue
}))
.....
}
.....
}
再往下,在视图层次结构中,在一些视图文件中:
struct SectionView: View {
var moc:NSManagedobjectContext
.....
@Environment(\.rowColorMasterDico) var rowColorMasterDico
.....
func handleEvent(_ file: String,flag: Bool) {
// This function is called when an audio file
// starts or ends playing.
if rowColorMasterDico.wrappedValue.count != 10 {
// This should not happen! But for some reason it sometimes does.
print("rowColorMasterDico is messed up !")
return
}
// Check that rowColorMasterDico.wrappedValue[page.index][file] changes value.
print("CLR(Before)=\(rowColorMasterDico.wrappedValue[page.index][file]!)")
rowColorMasterDico.wrappedValue[page.index][file] = flag ? Color.red : Color.white
print("CLR(After)=\(rowColorMasterDico.wrappedValue[page.index][file]!)")
}
.....
var body: some View {
vstack {
ListItemView(itemList: itmMstrList[page.index],moc: moc,rowColorDico: rowColorMasterDico.wrappedValue[page.index])
Button(action: {
if !soundManager.isPlaying {self.playAllAudio(itmMstrList[page.index])}
else {soundManager.stopAudio()}
})
{
Image(uiImage: UIImage(named: "speaker.png")!)
.padding(.bottom,17)
}
}
}
.....
struct ListItemView: View {
let crnrRad:CGFloat = 13.0,bgGreyLvl = 0.37,fgGreyLvl = 0.93
var itemList:[ItemList],moc:NSManagedobjectContext
@State var rowColorDico:[String:Color]
.....
func diddismiss() {
// Handle the dismissing action.
print(#function)
}
var body: some View {
List {
ForEach(self.itemList) {
item in
HStack {
Spacer()
Button(action: {
self.handleRowItem(item)
})
{
RowItemView(expression: item.expression!,fgTxtColor: rowColorDico[item.soundFile!] ?? Color.orange)
}
Spacer()
}
}
}.sheet(item: $itemPage,ondismiss: diddismiss) {
sntnc in
.....
}
}
}
struct RowItemView: View {
var expression:String
@State var fgTxtColor:Color
let crnrRad:CGFloat = 13.0,bgGreyLvl = 0.37
var body: some View {
Text(expression)
.foregroundColor(fgTxtColor)
.font(.headline)
.padding(.horizontal,11).padding(.vertical,15)
.background(Color(.sRGB,red: bgGreyLvl,green: bgGreyLvl,blue:bgGreyLvl,opacity: 1.0))
.cornerRadius(crnrRad)
.overlay(RoundedRectangle(cornerRadius: crnrRad)
.stroke(Color.yellow,linewidth: 3))
}
}
问题来了。当我在 ListItemView 中播放音频文件列表时,匹配的行项目应该更改播放文件的颜色。该工作在 handleEvent 函数内完成,我可以检查这是否按预期发生。但是列表中显示的颜色不会改变。这是为什么?
我设置环境变量 rowColorMasterDico 的方式有误吗? 还是我错过了其他东西?我已经尝试了上面代码的许多不同变体,但我无法让它工作。我希望有人能看到并指出某个地方的错误。
解决方法
以防万一这对其他人有用,我想报告我通过参考 this 解决了我的问题,同时再次查看了我自己的代码。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。