首页 > 解决方案 > SwiftUI - 如何将当前的强调色传递给工作表?

问题描述

到目前为止,SwiftUI 不会将当前的强调色传递给工作表。在以下示例中,工作表中按钮的强调色将不是红色。

// Some parent view which sets an accent color, can't change this
struct ContentView: View {
    var body: some View {
        ChildView()
            .accentColor(.red)
    }
}

// A child view that uses the accent color set by the parent
struct ChildView: View {
    @State var showSheet = false
    
    var body: some View {
        VStack {
            Button("this uses red"){
                showSheet = true
            }
            .sheet(isPresented: $showSheet){
                VStack {
                    Button("this will ignore accent color"){ }
                }
            }
        }
    }
}

我猜这是一个错误,但我正在寻找解决方法。问题是,我不能只设置.accentColor(.red)或在呈现的工作表内部进行任何设置,因为我的应用程序根据设置使用动态强调色。也就是说——我需要能够将 ChildView 的 accentColor 传递到工作表上,而不必知道它是什么。

我试过传递.accentColor(.accentColor)给工作表中的视图,但它不起作用。

有任何想法吗?

标签: iosswiftswiftui

解决方案


有很多方法可以做到这一点,以下只是一种方法:

(macos 11.4、xcode 12.5、目标 ios 14.5 和 macCatalyst 11.3。)

struct ContentView: View {
    @State var showSheet = false
    @State var accentColor = Color.red
    
    var body: some View {
        VStack {
            Button("this uses red"){
                showSheet = true
            }.sheet(isPresented: $showSheet){
                TheSheetView(accentColor: $accentColor)
            }
        }.accentColor(accentColor)
    }
}
struct TheSheetView: View {
    @Binding var accentColor: Color
    var body: some View {
        VStack {
            Button("this will not ignore accent color"){ }.accentColor(accentColor)
        }
    }
}

或者你可以试试这个:

@main
struct TestErrorApp: App {
    var myAccent = MyAccent()
    var body: some Scene {
        WindowGroup {
            ContentView().environmentObject(myAccent)
        }
    }
}

class MyAccent: ObservableObject {
    @Published var color = Color.red
}

struct ContentView: View {
    @EnvironmentObject var myAccent: MyAccent  // <--- will be available to all child views
    @State var showSheet = false
    
    var body: some View {
        VStack {
            Button("this uses red"){
                showSheet = true
            }.sheet(isPresented: $showSheet){
                TheSheetView().environmentObject(myAccent) // <--- need this for sheets
            }
        }.accentColor(myAccent.color)
    }
}
struct TheSheetView: View {
    @EnvironmentObject var myAccent: MyAccent
    var body: some View {
        VStack {
            Button("this will ignore accent color"){ }.accentColor(myAccent.color)
        }
    }
}

推荐阅读