在使用 开发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的方式有误吗?还是我错过了其他东西?我已经尝试了上面代码的许多不同变体,但我无法使其工作。我希望有人会在某个地方看到并指出错误。