我实现了更改应用程序配色方案的功能。除了其中有
.alert()
的 TextField
的配色方案之外,一切都工作正常。
如果是日光且配色方案更改为
.dark
,则 .alert()
配色方案仍为 .light
,包括 TextField
。
这意味着当您在
TextField
中输入内容时,前景色为白色,因为深色模式下的文本颜色变为白色,您无法真正看到您正在输入的内容。
类似,如果系统的配色方案是
.dark
并且应用程序的配色方案是白色,则.alert
处于.dark
模式并且文本是黑色,因为应用程序中的文本是黑色的。
将
.background()
或 foregroundColor()
应用于 TextField
或 VStack
没有任何效果。
有没有办法控制
.alert()
的配色方案?或者我是否必须寻找.alert()
替代方案?
这里是一些重现该行为的代码。谢谢!
import SwiftUI
struct ContentView: View {
@State private var showAlert = false
@State private var addSomething: String = ""
@State private var isSystemMode = false
@State private var isDarkMode = false
var body: some View {
VStack {
VStack {
Toggle("Automatic (iOS Settings)", isOn: $isSystemMode)
if !isSystemMode {
Toggle("Dark Mode", isOn: $isDarkMode)
}
}
Button{
self.showAlert = true
} label: {
Text("Add something")
.frame(maxWidth: .infinity)
}
.alert("Add something", isPresented: $showAlert, actions: {
TextField("Something", text: $addSomething)
Button("Done") {
// Some action
}
Button("Cancel", role: .cancel, action: {})
}, message: {
Text("Type in something")
})
}
.padding()
.preferredColorScheme(isSystemMode ? .none : isDarkMode ? .dark : .light)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
我认为真正实现这项工作的唯一方法是制作您自己的自定义警报。以下是自定义警报的示例,但您可能需要根据您的需要对其进行修改:
struct CustomAlertView<Content: View>: View {
@Environment(\.colorScheme) var colorScheme
let title: String
let description: String
var cancelAction: (() -> Void)?
var cancelActionTitle: String?
var primaryAction: (() -> Void)?
var primaryActionTitle: String?
var customContent: Content?
init(title: String,
description: String,
cancelAction: (() -> Void)? = nil,
cancelActionTitle: String? = nil,
primaryAction: (() -> Void)? = nil,
primaryActionTitle: String? = nil,
customContent: Content? = EmptyView()) {
self.title = title
self.description = description
self.cancelAction = cancelAction
self.cancelActionTitle = cancelActionTitle
self.primaryAction = primaryAction
self.primaryActionTitle = primaryActionTitle
self.customContent = customContent
}
var body: some View {
HStack {
VStack(spacing: 0) {
Text(title)
.font(.system(size: 16, weight: .semibold, design: .default))
.padding(.top)
.padding(.bottom, 8)
Text(description)
.font(.system(size: 12, weight: .light, design: .default))
.multilineTextAlignment(.center)
.padding([.bottom, .trailing, .leading])
customContent
Divider()
HStack {
if let cancelAction, let cancelActionTitle {
Button { cancelAction() } label: {
Text(cancelActionTitle)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .center)
}
}
if cancelActionTitle != nil && primaryActionTitle != nil {
Divider()
}
if let primaryAction, let primaryActionTitle {
Button { primaryAction() } label: {
Text("**\(primaryActionTitle)**")
.frame(minWidth: 0, maxWidth: .infinity, alignment: .center)
}
}
}.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: 50, alignment: .center)
}
.frame(minWidth: 0, maxWidth: 400, alignment: .center)
.background(.ultraThickMaterial)
.cornerRadius(10)
.padding([.trailing, .leading], 50)
}
.zIndex(1)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
.background(
colorScheme == .dark
? Color(red: 0, green: 0, blue: 0, opacity: 0.4)
: Color(red: 1, green: 1, blue: 1, opacity: 0.4)
)
}
}
用途:
struct ContentView: View {
@State private var showAlert = false
var body: some View {
ZStack {
Button("Show alert") {
withAnimation {
showAlert.toggle()
}
}
if showAlert {
CustomAlertView(
title: "Alert title",
description: "Description here",
cancelAction: {
// Cancel action here
withAnimation {
showAlert.toggle()
}
},
cancelActionTitle: "Cancel",
primaryAction: {
// Primary action here
withAnimation {
showAlert.toggle()
}
},
primaryActionTitle: "Action",
customContent:
Text("Custom content here")
.padding([.trailing, .leading, .bottom])
)
}
}
}
}
如果您想包含文本字段,只需执行以下操作:
customContent:
TextField("Text here", text: $text)
.textFieldStyle(.roundedBorder)
.padding([.trailing, .leading, .bottom])
通过像这样设置外观来为我工作:
UIView.appearance(for: UITraitCollection(userInterfaceStyle: .light), whenContainedInInstancesOf: [UIAlertController.self]).tintColor = .red
UIView.appearance(for: UITraitCollection(userInterfaceStyle: .dark), whenContainedInInstancesOf: [UIAlertController.self]).tintColor = .blue