如何检查 SwiftUI 是否处于预览模式?

Ken*_*ler 18 xcode if-statement ios swift swiftui

有没有办法检查 SwiftUI 应用程序是否处于预览模式?例如,您可以使用#if DEBUG. 你能做类似的事情来检查你是否正在预览吗?

ars*_*ius 52

您可以使用ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"]. "1"在画布中运行时,该值将在运行时出现。

  • 无论如何,在我的 applicationDidFinishLaunching 中使用保护语句检查这一点,而不是初始化破坏我的 SwiftUI 预览的东西,让我的预览再次工作。最好将此防护措施包装在 #if DEBUG / #endif 中以达到良好的效果。 (6认同)

Nat*_*ton 17

Though there is no compilation flag currently available for checking if the active build is intended for the Previews Canvas, I would still recommend using a compiler directive over a runtime check, if it can meet your needs.

例如,对于模拟器预览版,此检查都解析为 true:

#if targetEnvironment(simulator)
// Execute code only intended for the simulator or Previews
#endif
Run Code Online (Sandbox Code Playgroud)

如果您希望代码仅在物理设备上执行(例如与相机相关的操作,否则肯定会失败),请否定该条件。

运行时检查代码是否正在执行预览(如接受的答案中给出的)可能不会增加显着的性能开销,但在我看来,交付该代码仍然感觉有点恶心。因此,如果您的情况需要这种程度的特殊性,至少值得首先考虑。如果确实如此,我建议将该代码包装在编译器检查中,以将其从发布版本中删除。


Ork*_*nov 16

如果您像我一样正在寻找一个环境变量来在构建脚本中使用,xcode 在构建 SwiftUI 预览时设置该环境变量,结果是ENABLE_PREVIEWS.

当我的脚本更新文件时,SwiftUI 正在暂停预览Info.plist。为了解决这个问题,如果我们处于预览版本中,我会在某个时刻退出脚本。

if [ "${ENABLE_PREVIEWS}" = "YES" ]; then
  exit 0;
fi
Run Code Online (Sandbox Code Playgroud)

  • 可以确认它有效。我一直在寻找它,因为我使用 SwiftFormat 在构建时重新格式化代码,并且在处理 SwiftUI 视图时会导致问题。请参阅 https://github.com/nicklockwood/SwiftFormat/issues/969 (2认同)

Ale*_*cur 10

如果您不想依赖该ProccessInfo值,您可以随时在 SwiftUI 中设计自己的环境变量。

\n
import SwiftUI\n\nprivate struct IsPreviewKey: EnvironmentKey {\n    static let defaultValue = false\n}\n\nextension EnvironmentValues {\n    var isPreview: Bool {\n        get { self[IsPreviewKey.self] }\n        set { self[IsPreviewKey.self] = newValue }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

然后,当您创建预览时注入变量

\n
MyView().environment(\\.isPreview, true)\n
Run Code Online (Sandbox Code Playgroud)\n

你可以在你的视图中使用它,如下所示:

\n
struct MyView: View {\n    @Environment(\\.isPreview) var isPreview\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我通常有一种方法可以生成预览的所有不同版本(浅色模式、深色模式、iPad、iPhone、\xe2\x80\xa6),因此我将其注入到所有预览中。

\n