为什么preferredColorScheme对SwiftUI中ColorPicker呈现的视图没有影响?

问题描述 投票:0回答:1

我有一个应用程序,让用户选择

colorScheme
,这样它就可以保持自适应模式,或者可以强制进入白天或夜间模式,即使设备的系统方案不同。

问题是

ColorPicker
呈现的弹出窗口并不反映所选的
ColorScheme
,而仅反映(设备的)系统之一。

建议的代码会生成一个列表,例如自动反映

preferredColorScheme
。然后它会生成一个
ColorPicker
来设置背景颜色和一些可点击的文本,以将
colorScheme
更改为
setColorScheme

import SwiftUI

struct ColorPickerTest: View {
    
    @Environment(\.colorScheme) var colorScheme
    @State var setColorScheme: ColorScheme? = nil
    
    @State var selectedColor = Color.green
    
    var body: some View {
        ZStack {
            selectedColor.ignoresSafeArea()
            VStack {
                List {
                    ForEach(1..<6) { n in
                        Text("item \(n)")
                    }
                }
                .frame(height: 500)
                .cornerRadius(30)
                
                ColorPicker("Color", selection: $selectedColor)
                    .fixedSize().padding()
                    .background(colorScheme == .dark ? .blue : selectedColor)
                    .cornerRadius(30).padding()
                
                HStack {
                    Text("Theme:")
                    Text("Adaptive").onTapGesture { setColorScheme = nil }
                    Text("Night").onTapGesture { setColorScheme = .dark }
                    Text("Day").onTapGesture { setColorScheme = .light }
                }
            }
        }
        .preferredColorScheme(setColorScheme)
    }
}

#Preview {
    ColorPickerTest()
}

这个效果很好,除了

ColorPicker
呈现的弹出窗口,在这种情况下,
setColorScheme
没有任何效果,仅反映系统方案,忽略强加的
preferredColorScheme

有人有解决办法或解释吗?

swiftui color-scheme color-picker nscolorpanel
1个回答
0
投票

我不知道如何让 SwiftUI 的

ColorPicker
自动应用背景颜色,但我可以提出这个小技巧:

ColorPicker
的窗口是我们可以在应用程序的窗口层次结构中搜索的
NSColorPanel
。在那里我们可以设置它的属性。

struct ContentView: View {
    @State private var selectedColor: Color = .gray
    
    var body: some View {
        VStack {
            ColorPicker("Pick", selection: $selectedColor)
                .onAppear {
                    DispatchQueue.main.async {
                        guard let panel = colorPanel else { return }
                        /// Now we can access all NSWindow/NSPanel/NSColorPanel properties
                        print("\(panel.backgroundColor)") // "Optional(Catalog color: System windowBackgroundColor)"
                        panel.backgroundColor = NSColor(selectedColor)
                        // panel.titlebarAppearsTransparent = true
                        // panel.titleVisibility = NSWindow.TitleVisibility.hidden
                        // panel.title = "Random text"
                        print("\(panel.backgroundColor)")
                    }
                }
                .onChange(of: selectedColor) { newColor in
                    colorPanel?.backgroundColor = NSColor(selectedColor)
                }
        }
        .padding()
        .fixedSize()
        .background(selectedColor)
    }
}

请注意,在

onAppear
中,我们需要使用
DispatchQueue.main.async
“等待”面板才能存在于应用程序的
windows
数组中。

您仍然需要了解如何应用自适应配色方案,但如果需要,如何应用颜色。

© www.soinside.com 2019 - 2024. All rights reserved.