swiftui - 如何检测iOS 13中浅\暗模式的变化?

标签 swiftui uikit ios-darkmode uitraitcollection

某些 UI 设置无法随着 UIColor 的深色/浅色模式更改而自动工作。例如图层中的阴影。由于我需要在深色和浅色模式下删除和放置阴影,因此我需要在某个地方放置 updateShadowIfNeeded() 函数。我知道如何检测当前的模式:

func dropShadowIfNeeded() {
    switch traitCollection.userInterfaceStyle {
    case .dark: removeShadow()
    case .light: dropShadowIfNotDroppedYet()
    default: assertionFailure("Unknown userInterfaceStyle")
    }
}

现在我将该函数放入 layoutSubviews 中,因为每次外观更改时都会调用它:

override func layoutSubviews() {
    super.layoutSubviews()
    dropShadowIfNeeded()
}

但是这个函数被调用很多。仅当 userInterfaceStyle 更改时才触发的正确函数是什么?

最佳答案

SwiftUI

\.colorScheme 键上使用一个简单的环境变量:

struct ContentView: View {
    @Environment(\.colorScheme) var colorScheme

    var body: some View {
        Text(colorScheme == .dark ? "Its Dark" : "Its. not dark! (Light)")
    }
}
<小时/>

UIKit

正如 WWDC 2019 - Session 214 中所述23:30左右。

正如我所料,这个函数被多次调用,包括颜色变化时。除了 ViewControllerpresentationController 的许多其他功能之外。但是有一些专门设计的特殊函数在所有 View 表示器中具有相似的签名。

看看该 session 中的这张图片:

WWDC 2019 - Session 214

灰色:调用但对我的问题不利,绿色:为此而设计

所以我应该调用它并在这个函数中检查它:

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
    
    if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
        dropShadowIfNeeded()
    }
}

这将保证每次更改只调用一次。

如果您只是寻找样式的初始状态, check out this answer here

关于swiftui - 如何检测iOS 13中浅\暗模式的变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58016866/

相关文章:

ios - 无法将点击手势识别器添加到 SwiftUI MKMapView UIViewRepresentable

ios - 在 Cocoa Touch/UIKit 上,如何从后台线程检测用户界面的变化?

swift - 支持不同 SwiftUI View 类型的 UIHostingController 数组

c++ - 为什么 UIKit 或 Cocoa 必须用 Objective-C 编码?

ios - 如何使用我的应用程序中使用的自定义颜色轻松支持浅色和深色模式?

ios - 是否可以手动设置/切换每个应用程序的 UserInterfaceStyle/暗模式?

swift - 不将任何内容传递到 @binding 属性中

geometry - 在 SwiftUI 中,如何确定 Circle() 的大小以与该圆按比例绘制叠加层?

swift - 如果从 Core Data SwiftUI 中删除,则删除本地通知

ios - Flutter:iOS 上的深色主题