【问题标题】:SwiftUI - How can I pass the current accent color to a sheet?SwiftUI - 如何将当前的强调色传递给工作表?
【发布时间】:2021-05-29 22:48:00
【问题描述】:

到目前为止,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) 传递给工作表中的视图,但不起作用。

有什么想法吗?

【问题讨论】:

  • 如果你把.accentColor(.red)放在VStack上,它应该可以工作
  • 正如问题中所述,我不能这样做,因为我正在为整个应用程序动态设置强调色,并且需要尊重设置。
  • 不幸的是,通过.sheet 呈现视图不会继承环境。有人说这是一个 bug,但在 SwiftUI 2.0 之前就一直是这样,现在仍然存在。另一个问题是某些内置环境设置,例如 accentColor 使用的设置,不是公开的,因此您无法访问它们并传递它们。

标签: ios swift swiftui


【解决方案1】:

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

(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)
        }
    }
}

【讨论】:

  • 这不起作用。强调色通过环境传递到 .accentColor 修饰符的任何子视图——我需要一种从环境中获取该值的方法。通常,访问 Color.accentColor 会返回当前环境的强调色,但这在工作表修饰符中不起作用。
  • 向我们展示您正在使用的代码,而不是不具有代表性的示例。
  • 我无法显示确切的代码,因为它是专有的。但是,我的示例+描述完全代表了我的问题。我已对其进行了更新以使其更清晰。
猜你喜欢
  • 1970-01-01
  • 2016-11-17
  • 1970-01-01
  • 2021-05-20
  • 2020-07-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-17
  • 1970-01-01
相关资源
最近更新 更多