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.secondarySystemBackground
或UIColor.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 SignInWithAppleButton 暗模式 [重复]
SwiftUI Xcode 11 beta 7 @Binding for collections 正在打破预览