Ios 在SwiftUI应用程序中实现暗模式切换

Ios 在SwiftUI应用程序中实现暗模式切换,ios,swift,swiftui,ios-darkmode,Ios,Swift,Swiftui,Ios Darkmode,我目前正在我的应用程序中查看黑暗模式。由于我的SwiftUI基础,暗模式本身并不困难,但我正在努力设置独立于系统配色方案的配色方案 我想实现这个特性。(链接:) 知道如何在SwiftUI中实现这一点吗?我找到了一些关于@Environment的提示,但没有关于这个主题的更多信息。(链接:)单一视图 要更改单个视图(可能是应用程序的主ContentView)的颜色方案,可以使用以下修改器: .environment(\.colorScheme, .light) // or .dark 或 此外,

我目前正在我的应用程序中查看黑暗模式。由于我的SwiftUI基础,暗模式本身并不困难,但我正在努力设置独立于系统配色方案的配色方案

我想实现这个特性。(链接:)

知道如何在SwiftUI中实现这一点吗?我找到了一些关于
@Environment
的提示,但没有关于这个主题的更多信息。(链接:)

单一视图 要更改单个视图(可能是应用程序的主
ContentView
)的颜色方案,可以使用以下修改器:

.environment(\.colorScheme, .light) // or .dark

此外,您还可以将其应用于
ContentView
,使整个应用程序变暗

假设您没有更改场景代理或
@main


整个应用程序(包括
UIKit
部件和
SwiftUI
) 首先,您需要访问窗口以更改在
UIKit
中调用
UserInterfaceStyle
的应用程序颜色方案

我在
SceneDelegate
中使用了这个:

private(set) static var shared: SceneDelegate?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    Self.shared = self
    ...
}
然后需要将一个动作绑定到切换。所以你需要一个模型

struct ToggleModel {
    var isDark: Bool = true {
        didSet { 
            SceneDelegate.shared?.window!.overrideUserInterfaceStyle = isDark ? .dark : .light 
        }
    }
}
最后,您只需切换开关:

struct ContentView: View {
     @State var model = ToggleModel()

     var body: some View {
         Toggle(isOn: $model.isDark) {
             Text("is Dark")
        }
    }
}

从应用程序的UIKit部分 每个
ui视图
都可以访问该窗口,因此您可以使用它设置
。将UserInterfaceStyle
值重写为所需的任何方案

myView.window?.overrideUserInterfaceStyle = .dark

使用
@AppStorage
切换暗模式的演示

PS:对于全局切换,修改器应添加到WindowGroup/MainContentView

导入快捷界面
结构SystemColor:可散列{
变量文本:字符串
颜色:颜色
}
让backgroundColors:[SystemColor]=[.init(文本:“红色”,颜色:.systemRed),.init(文本:“橙色”,颜色:.systemOrange),.init(文本:“黄色”,颜色:.systemYellow),.init(文本:“绿色”,颜色:.systemGreen),.init(文本:“蓝色”,颜色:.systemBlue),.init(文本:“靛蓝”,颜色:.systemIndigo),.init(文本:“紫色”,颜色:.systemPurple),.init(文本:“粉色”,颜色:.systemPink),.init(文本:“灰色”,颜色:.systemGray),.init(文本:“灰色2”,颜色:.systemGray2),.init(文本:“灰色3”,颜色:.systemGray3),.init(文本:“灰色4”,颜色:.systemGray4),.init(文本:“灰色5”,颜色:.systemGray5),.init(文本:“灰色6),颜色:.systemGray6)]
结构DarkModeColorView:视图{
@AppStorage(“IsDakMode”)变量IsDakMode:Bool=true
var body:一些观点{
形式{
节(标题:文本(“常用颜色”)){
ForEach(背景色,id:\.self){
ColorRow(颜色:$0)
}
}
}
.工具栏{
工具栏项(位置:。主体){//导航栏
选择器(“颜色”,选择:$isDarkMode){
文本(“灯光”)。标记(错误)
文本(“黑色”).tag(真)
}
.pickerStyle(SegmentedPickerStyle())
}
}
.modifier(DarkModelViewModifier())
}
}
私有结构ColorRow:视图{
让颜色:SystemColor
var body:一些观点{
HStack{
文本(color.Text)
垫片()
矩形()
.foregroundColor(颜色.颜色)
.框架(宽度:30,高度:30)
}
}
}
公共结构DarkModelViewModifier:ViewModifier{
@AppStorage(“IsDakMode”)变量IsDakMode:Bool=true
公共函数体(内容:content)->一些视图{
内容
.environment(\.colorScheme,IsDakMode?.dark:.亮)
.preferredColorScheme(IsDakMode?.dark:.light)//状态栏上的色调
}
}
结构DarkModeColorView\u预览:PreviewProvider{
静态var预览:一些视图{
导航视图{
DarkModeColorView()
}
}
}
答案确实帮了我的忙,但我使用了iOS14的
@main
而不是
SceneDelegate
,以及一些
UIKit
视图,所以我最终使用了类似的东西(这不会切换模式,但会在
SwiftUI
UIKit
之间设置暗模式:

@main
结构MyTestApp:App{
@环境(\.scenePhase)专用var阶段
var body:一些场景{
窗口组{
ContentView()
.accentColor(.red)
.preferredColorScheme(.dark)
}
.onChange(of:phase){in
setupColorScheme()
}
}
专用函数setupColorScheme(){
//我们通过窗口执行此操作,以便也可以访问UIKit组件。
让window=UIApplication.shared.windows.first
窗口?.overrideUserInterfaceStyle=.dark
窗口?.tintColor=UIColor(Color.red)
}
}

您链接到的文章来自2016年,当时没有系统范围的黑暗模式。您是指人机界面指南吗?它们是针对iOS 13更新的,但可能您是对的,设置部分是旧的。有一个谷歌工具可以检查网站上次更改的时间,它说是在2016年。HIG中有一个关于iOS的部分13次更改,但未提及设置。在这种情况下,很抱歉我链接了一篇旧文章,但它不是代码参考。更多的是“我想复制类似的内容”参考。不要抱歉。我想说的是它很旧,可能不再重要了。这帮了大忙!谢谢!有没有想法把它放入分段选择器并添加函数以使用系统颜色方案?与此类似。唯一不同的是模型。你指的是切换模型,对吗?你如何处理此任务?评论我的朋友,这里不是回答问题的地方。但是请随意回答。但是这次,请确保您阅读了指南,并用您已经尝试过的代码添加了一个最小的代码;)好的,我不必再问其他问题,解决方案是第三种情况:
。未指定的
。非常感谢
myView.window?.overrideUserInterfaceStyle = .dark