Xcode 11-SwiftUI预览黑暗模式

时间:2019-06-07 05:04:38

标签: swiftui xcode11

在Xcode 11中,我们可以通过在调试区域底部切换环境覆盖来启用暗模式,例如这样。

Environment Overrides

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

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

3 个答案:

答案 0 :(得分:12)

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

您将获得如下所示的输出:

Light and dark mode rendering of ExampleView above

为了使第二个预览显示在深色背景上,请在视图上调用.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)
    }
}

您将获得两个如下所示的预览:

Light and dark mode rendering of ExampleView above with background fixes

其他选项

您可以进行一些修改。首先,根据单元所在的层,可以将UIColor.systemBackground替换为UIColor.secondarySystemBackgroundUIColor.tertiarySystemBackground。详细了解动态系统颜色in the human interface guidelinesthe UI Element Colors portion of the UIColor developer documentation

最后,如果您将经常使用此功能,并且不想每次都写出对UIColor的整个调用,那么在{{1}上创建扩展名可能是个好主意},然后将其定义为静态变量:

Color

然后,您可以用更好的extension Color { static let systemBackground = Color(UIColor.systemBackground) static let secondarySystemBackground = Color(UIColor.secondarySystemBackground) static let tertiarySystemBackground = Color(UIColor.tertiarySystemBackground) } 替换对Color(UIColor.systemBackground)的呼叫。

答案 1 :(得分:4)

正在预览的文件的底部应该有类似的内容。这就是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示例以及预览功能的强大功能。

答案 2 :(得分:2)

  

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

Source - paid content

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

示例:

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

在黑暗模式下进行样品预览:

enter image description here