Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Listen for Environment Changes

Tags:

swift

swiftui

How do I detect environment changes in SwiftUI? For example, I store the current colour scheme as

@Environment(\.colorScheme) var colorScheme: ColorScheme

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) { }
}

And In my body property I instantiate the struct:

var body: some View {
    AppleSignInView(colorScheme: colorScheme)
}

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?

like image 266
Sudara Avatar asked Jan 26 '23 03:01

Sudara


1 Answers

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)

This saves you from returning 2 versions of the button in an if/else statement, like in kontiki's answer.

And my button, for good measure:

struct SignInWithAppleButton: UIViewRepresentable {
  var style: ASAuthorizationAppleIDButton.Style

  func makeUIView(context: Context) -> ASAuthorizationAppleIDButton {
    return ASAuthorizationAppleIDButton(type: .default, style: style)
  }

  func updateUIView(_ uiView: ASAuthorizationAppleIDButton, context: Context) {}
}
like image 76
Kevin Renskers Avatar answered Jan 30 '23 05:01

Kevin Renskers