聆听环境变化
如何检测 SwiftUI 中的环境变化?例如,我将当前的配色方案存储为
How do I detect environment changes in SwiftUI? For example, I store the current colour scheme as
@Environment(\.colorScheme) var colorScheme: ColorScheme
我根据环境值显示一个ASAuthorizationAppleIDButton
:
And I display an ASAuthorizationAppleIDButton
based on the environment value:
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
属性中,我实例化了结构:
And In my body
property I instantiate the struct:
var body: some View {
AppleSignInView(colorScheme: colorScheme)
}
这很好用,但是当我从 Xcode 更改配色方案时,新配色方案不会传播.
This works fine, but the new colour scheme isn't propagated when I change the colour scheme from the Xcode.
如何监听这个环境变量的变化?
How do I listen to this environment variable change?
我是这样做的:诀窍是添加 .id(self.colorScheme)
行.这会强制 SwiftUI 在每次 colorScheme 更改时重绘此按钮.
Here is how I do it: the trick is to add the .id(self.colorScheme)
line. This forces SwiftUI to redraw this button every time the colorScheme changes.
SignInWithAppleButton(style: self.colorScheme == .light ? .black : .white)
.frame(width: 280, height: 60)
.onTapGesture(perform: self.showAppleLogin)
.id(self.colorScheme)
这样可以避免在 if/else 语句中返回两个版本的按钮,就像在 kontiki 的回答中一样.
This saves you from returning 2 versions of the button in an if/else statement, like in kontiki's answer.
还有我的按钮,很好:
struct SignInWithAppleButton: UIViewRepresentable {
var style: ASAuthorizationAppleIDButton.Style
func makeUIView(context: Context) -> ASAuthorizationAppleIDButton {
return ASAuthorizationAppleIDButton(type: .default, style: style)
}
func updateUIView(_ uiView: ASAuthorizationAppleIDButton, context: Context) {}
}