Xcode 11 - SwiftUI 预览暗模式 [重复]

Posted

技术标签:

【中文标题】Xcode 11 - SwiftUI 预览暗模式 [重复]【英文标题】:Xcode 11 - SwiftUI Preview Dark Mode [duplicate] 【发布时间】:2019-06-07 05:04:38 【问题描述】:

在 Xcode 11 中,我们可以在应用程序运行时启用暗模式,方法是像这样切换调试区域底部的环境覆盖。

SwiftUI 具有 Canvas 编辑器,可在您构建界面时生成应用程序的实时预览。

有没有办法让我们在这些预览中切换到暗模式?

【问题讨论】:

当您上下文单击预览旁边的播放按钮并选择“调试预览”时,您将获得一个调试会话,并且可以针对您的 SwiftUI 预览使用环境覆盖和其他调试功能。 这能回答你的问题吗? Dark mode in SwiftUI Preview doesn't have a dark background with Xcode 11.4 【参考方案1】:

您应该在正在预览的文件的底部有类似的内容。这是 Xcode 用来生成预览的:

#if DEBUG
struct ContentView_Previews : PreviewProvider 
    static var previews: some View 
        ContentView()
    

#endif

要将预览更改为暗模式,您只需指定一个colorScheme

static var previews: some View 
    ContentView().colorScheme(.dark)

或者,您甚至可以选择同时预览明暗模式:

static var previews: some View 
    Group 
        ContentView().colorScheme(.light)
        ContentView().colorScheme(.dark)
    

我建议观看Introducing SwiftUI 会话,了解更多 SwiftUI 示例以及预览功能的强大程度。

【讨论】:

仅供参考:我必须在两个 ContentViews() 周围添加一个“组”才能使最后一个工作。 这真的适用于任何人吗?我在 Beta1 中使用黑暗模式非常难过。当我在运行模拟器时手动切换到暗模式时,即使我在颜色资产目录中的 模式也不起作用。当然,所有默认的苹果控件都可以工作...... 如果您的预览未显示暗模式,请选中此项***.com/a/56593027/3815069 如何以编程方式检查配色方案是深色还是浅色?这是因为我需要在天黑时更改图像【参考方案2】:

TLDR:

只需将.background(Color(UIColor.systemBackground)).environment(\.colorScheme, .dark) 修饰符添加到预览中。如需解释、示例、一些修改和一些技巧,使其更漂亮甚至更简单,请阅读整个答案。

说明

我知道这个问题已经相当老了,但我找到了一种实施起来不会太痛苦并且不需要在 NavigationView 中进行任何包装的方法。此外,它还保留了.previewLayout(.sizeThatFits) 的正确行为。

本质上,当您定义符合PreviewProvider 的结构时,您只是在定义内容,但预览的背景由 Xcode 为您管理。因此,应用.environment(\.colorScheme, .dark) 只会将实际视图更改为暗模式,而不是背景。 NavigationView 解决这个问题的原因很简单——它为视图添加了一个背景,覆盖了预览的所有白色背景。

修复本身也相当简单 - 您需要做的就是在预览中为您的视图添加背景。所以对于像这样的简单视图:

struct ExampleView: View 
    var body: some View 
        Text("Hello, World!")
    

还有一组这样的预览:

struct ExampleView_Previews: PreviewProvider 
    static var previews: some View 
        Group 
            ExampleView()
            ExampleView()
                .environment(\.colorScheme, .dark)
        .previewLayout(.sizeThatFits)
    

您会得到如下所示的输出:

为了使第二个预览显示在深色背景上,请通过在视图上调用 .background(Color(UIColor.systemBackground)) 来添加它:

struct ExampleView_Previews: PreviewProvider 
    static var previews: some View 
        Group 
            ExampleView()
            ExampleView()
                .background(Color(UIColor.systemBackground))
                .environment(\.colorScheme, .dark)
        .previewLayout(.sizeThatFits)
    

您会得到两个如下所示的预览:

额外选项

您可以进行多种修改。首先,根据单元所在的层,您可以将UIColor.systemBackground 替换为UIColor.secondarySystemBackgroundUIColor.tertiarySystemBackground。阅读更多关于动态系统颜色的信息in the human interface guidelines 或the UI Element Colors portion of the UIColor developer documentation。

最后,如果您要经常使用它并且不想每次都写出对UIColor 的整个调用,那么在Color 上创建一个扩展并定义它们可能是个好主意作为静态变量:

extension Color 
    static let systemBackground = Color(UIColor.systemBackground)
    static let secondarySystemBackground = Color(UIColor.secondarySystemBackground)
    static let tertiarySystemBackground = Color(UIColor.tertiarySystemBackground)

然后你可以用更好的Color.systemBackground 替换你对Color(UIColor.systemBackground) 的调用。

【讨论】:

【参考方案3】:

注意:在撰写本文时,您需要一个 NavigationView 作为 .environment(.colorScheme, .dark) 工作的***视图。但是随后(大)导航栏覆盖了色块,因此两个导航栏修饰符使栏变小并将其隐藏......有点。这可能是 Xcode 中的一个错误。

Source - paid content

我在 Xcode 11.2.1 上对此进行了测试,NavigationView 的问题仍然存在。除非您的整个视图包含在 NavigationView 中,否则环境似乎不会改变。您可以尝试使用.navigationBarTitle("").navigationBarHidden(true) 隐藏NavigationView

例子:

struct ContentView: View 
    var body: some View 
        NavigationView 
            Text("Light vs Dark Mode")

            // Uncomment these lines if you don't want the navigation bar
            // .navigationBarTitle("")
            // .navigationBarHidden(true)

            // You can also apply a colorScheme here
            // which will impact how the view looks when the app
            // is launched on device. Regardless of the users theme settings
        // .environment(\.colorScheme, .dark)
    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        // ContentView().environment(\.colorScheme, .dark)
        // ContentView().environment(\.colorScheme, .light)

        // If you want you can display both schemes in a group
        Group 
            ContentView()
            .environment(\.colorScheme, .light)

           ContentView()
           .environment(\.colorScheme, .dark)
       
    

深色模式下的示例预览:

【讨论】:

Xcode 11.3.1 中的问题仍然存在。在没有NavigationView 的情况下可以在模拟器中正常工作... 很遗憾这仍然没有修复。此外,如果您将 previewLayout 设置为 fixed,它会显示导航视图,并且尝试隐藏它是行不通的。在苹果修复它之前,我们将不得不忍受这种解决方法以及它带来的任何缺陷

以上是关于Xcode 11 - SwiftUI 预览暗模式 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何与代码并排打开 SwiftUI 预览? [复制]

SwiftUI SignInWithAppleButton 暗模式 [重复]

SwiftUI Xcode 11 beta 7 @Binding for collections 正在打破预览

Swift UI 实时预览画布不适用于 macOS Catalina 和 Xcode 11.0

如何获得 SwiftUI 颜色的明暗模式版本?

无法使用 SwiftUI 实现暗模式 [重复]