如何检测 SwiftUI 中的环境变化?例如,我将当前的配色方案存储为
@Environment(\.colorScheme) var colorScheme: ColorScheme
Run Code Online (Sandbox Code Playgroud)
我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) { }
}
Run Code Online (Sandbox Code Playgroud)
在我的body财产中,我实例化了结构:
var body: some View {
AppleSignInView(colorScheme: colorScheme)
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但是当我从 Xcode 更改配色方案时,新配色方案不会传播。
我如何听取这个环境变量的变化?
这是我的做法:诀窍是添加.id(self.colorScheme)行。这会强制 SwiftUI 每次 colorScheme 更改时重新绘制此按钮。
SignInWithAppleButton(style: self.colorScheme == .light ? .black : .white)
.frame(width: 280, height: 60)
.onTapGesture(perform: self.showAppleLogin)
.id(self.colorScheme)
Run Code Online (Sandbox Code Playgroud)
这可以避免在 if/else 语句中返回按钮的 2 个版本,就像在 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) {}
}
Run Code Online (Sandbox Code Playgroud)
我最近回答了一个类似的问题,OP正在寻找一种使自定义字体对.sizeCategory的环境变化做出反应的方法。
这是一个有效的实现。请注意,AppleSignInView被放置在 if 语句内。这是为了强制 SwiftUI 重新创建您的UIViewRepresantable。理想情况下,您只需传递 colorScheme,但在这种情况下,您需要更改updateUIView()中的ASAuthorizationAppleIDButton.style。但是,.style 是不可修改的。要解决此问题,您可以使用 if 语句强制重新登录“登录”按钮。
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) {
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1637 次 |
| 最近记录: |