如何在SwiftUI中检测环境变化? 例如,我将当前的配色方案存储为
@Environment(\.colorScheme) var colorScheme: ColorScheme
然后根据环境值显示一个ASAuthorizationAppleIDButton
:
fileprivate struct AppleSignInView : UIViewRepresentable {
var colorScheme: ColorScheme
func makeUIView(context: Context) -> ASAuthorizationAppleIDButton {
switch colorScheme {
case .light:
return ASAuthorizationAppleIDButton(type: .continue, style: .black)
case .dark:
return ASAuthorizationAppleIDButton(type: .continue, style: .white)
@unknown default:
return ASAuthorizationAppleIDButton(type: .continue, style: .black)
}
}
func updateUIView(_ uiView: ASAuthorizationAppleIDButton, context: Context) { }
}
然后在我的body
属性中实例化该结构:
var body: some View {
AppleSignInView(colorScheme: colorScheme)
}
这很好用,但是当我从Xcode更改颜色方案时,不会传播新的颜色方案。
如何聆听此环境变量的更改?
答案 0 :(得分:3)
这就是我的方法:诀窍是添加.id(self.colorScheme)
行。每当colorScheme更改时,这将迫使SwiftUI重绘此按钮。
SignInWithAppleButton(style: self.colorScheme == .light ? .black : .white)
.frame(width: 280, height: 60)
.onTapGesture(perform: self.showAppleLogin)
.id(self.colorScheme)
这样可以避免您在if / else语句中返回两个版本的按钮,就像在kontiki的答案中一样。
还有我的按钮,很好:
struct SignInWithAppleButton: UIViewRepresentable {
var style: ASAuthorizationAppleIDButton.Style
func makeUIView(context: Context) -> ASAuthorizationAppleIDButton {
return ASAuthorizationAppleIDButton(type: .default, style: style)
}
func updateUIView(_ uiView: ASAuthorizationAppleIDButton, context: Context) {}
}
答案 1 :(得分:0)
我最近回答了一个类似的问题,OP正在寻找一种使自定义字体对.sizeCategory的环境变化做出反应的方法。
看看:https://stackoverflow.com/a/56730649/7786555
这是一个可行的实现。请注意, AppleSignInView 放在if语句内。这是为了强制SwiftUI重新创建您的 UIViewRepresantable 。理想情况下,您只需通过colorScheme,但是在这种情况下,您需要在 updateUIView()中更改 ASAuthorizationAppleIDButton.style 。但是,.style不可修改。要解决此问题,可以使用if语句强制重新创建SignIn按钮。
import SwiftUI
import AuthenticationServices
struct ContentView: View {
@Environment(\.colorScheme) var colorScheme: ColorScheme
var body: some View {
Group {
if colorScheme == .light {
AppleSignInView(colorScheme: .light).frame(width: 200, height: 50)
} else {
AppleSignInView(colorScheme: .dark).frame(width: 200, height: 50)
}
}
}
}
fileprivate struct AppleSignInView : UIViewRepresentable {
var colorScheme: ColorScheme
func makeUIView(context: Context) -> ASAuthorizationAppleIDButton {
switch colorScheme {
case .light:
return ASAuthorizationAppleIDButton(type: .continue, style: .black)
case .dark:
return ASAuthorizationAppleIDButton(type: .continue, style: .white)
@unknown default:
return ASAuthorizationAppleIDButton(type: .continue, style: .black)
}
}
func updateUIView(_ uiView: ASAuthorizationAppleIDButton, context: Context) {
}
}