在 SwiftUI 中播放音频时无法更新行颜色
Posted
技术标签:
【中文标题】在 SwiftUI 中播放音频时无法更新行颜色【英文标题】:Cannot update row color while playing audio, in SwiftUI 【发布时间】:2021-04-29 09:01:49 【问题描述】:在使用SwiftUI
开发ios
应用程序时,我面临以下情况。我已经设置了一个自定义环境键。这是 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的方式有误? 还是我错过了其他东西?我已经尝试了上面代码的许多不同变体,但我无法使其工作。我希望有人会在某个地方看到并指出错误。
【问题讨论】:
【参考方案1】:以防万一这对其他人有用,我想报告我通过参考this 解决了我的问题,同时再看一下我自己的代码。
【讨论】:
以上是关于在 SwiftUI 中播放音频时无法更新行颜色的主要内容,如果未能解决你的问题,请参考以下文章