SwiftUI Position Google 和 Facebook 登录按钮

SwiftUI Position Google and Facebook login buttons

我正在使用 Firebase Auth,并且有两个按钮。一份用于 Google,一份用于 Facebook。 我正在尝试通过 .frame() 设置高度和宽度,但它们没有正确响应。 此外,Google登录按钮不会出现在屏幕中间,而是出现在屏幕右侧。

我试着把它们放在一个 VStack 里,但还是一样。

VStack(alignment: .center) {
    FacebookLoginButtonView()
        .frame(width: 100, height: 28) // duhet 28 fiks
        .border(Color.red)

    GoogleLoginButtonView()
        .frame(width: 100, height: 28)
        .border(Color.red)

}

知道如何将它们定位在中心并且可能给它们相同的高度吗? 为 FB 设置 .frame(width: 100, height: 28) 除了 28 之外的每个高度都会抛出错误。

FacebookLoginButtonView

struct FacebookLoginButtonView: UIViewRepresentable {
    @EnvironmentObject var userViewModel: UserViewModel
    func makeCoordinator() -> Coordinator {
        return Coordinator(userViewModel: userViewModel)
    }

    func makeUIView(context: UIViewRepresentableContext<FacebookLoginButtonView>) -> FBLoginButton {
        let button = FBLoginButton()
        button.permissions = ["public_profile", "email"]
        button.delegate = context.coordinator
        return button
    }

    func updateUIView(_ uiView: FBLoginButton, context: UIViewRepresentableContext<FacebookLoginButtonView>) {
        //
    }

    class Coordinator: NSObject, LoginButtonDelegate {
        var userViewModel: UserViewModel

        init(userViewModel: UserViewModel) {
            self.userViewModel = userViewModel
        }

        func loginButton(_ loginButton: FBLoginButton, didCompleteWith result: LoginManagerLoginResult?, error: Error?) {
            if error != nil {
                // print(error?.localizedDescription)
                return
            }

            if let currentAccessToken = AccessToken.current {
                let credential = FacebookAuthProvider.credential(withAccessToken: currentAccessToken.tokenString)
                Auth.auth().signIn(with: credential, completion: AuthService(userViewModel: userViewModel).registerHandler)
            }
        }

        func loginButtonDidLogOut(_ loginButton: FBLoginButton) {
            try? Auth.auth().signOut()
        }
    }
}

GoogleLoginButtonView

struct GoogleLoginButtonView: UIViewRepresentable {
    @EnvironmentObject var userViewModel: UserViewModel
    func makeCoordinator() -> Coordinator {
        return Coordinator(userViewModel: userViewModel)
    }

    func makeUIView(context: UIViewRepresentableContext<GoogleLoginButtonView>) -> GIDSignInButton {
        let button = GIDSignInButton()
        button.style = .wide
        GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
        GIDSignIn.sharedInstance().delegate = context.coordinator
        GIDSignIn.sharedInstance()?.presentingViewController = UIApplication.shared.windows.first?.rootViewController
        return button
    }

    func updateUIView(_ uiView: GIDSignInButton, context: UIViewRepresentableContext<GoogleLoginButtonView>) {

    }

    class Coordinator: NSObject, GIDSignInDelegate {
        var userViewModel: UserViewModel

        init(userViewModel: UserViewModel) {
            self.userViewModel = userViewModel
        }

        func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
            // ...
            if let error = error {
                print(error.localizedDescription)
                return
            }

            guard let authentication = user.authentication else { return }
            let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken, accessToken: authentication.accessToken)

            Auth.auth().signIn(with: credential, completion: AuthService(userViewModel: userViewModel).registerHandler)
        }

        func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
            // Perform any operations when the user disconnects from app here.
            // ...
        }
    }
}

您可能注意到您的框架太小并且那些按钮尺寸固定,您可以将它们变大或至少对于 Google 按钮尝试使用任何 other styles,您现在使用 button.style = .wide.

另一个解决方案是不使用它们,创建自己的视图来复制每个按钮并在幕后调用函数。

Google:

struct GoogleAuthButtonView: View {
    var body: some View {
        Button(action: {
        GIDSignIn.sharedInstance()?.presentingViewController = UIApplication.shared.windows.last?.rootViewController
        GIDSignIn.sharedInstance()?.signIn()
            //Any other function here
        }) {
            HStack {
                Image("icon-google").renderingMode(.original)
                    .accessibility(label: Text("Sign in with Google"))
                Spacer()
                Text("Sign in with Google")
                    .foregroundColor(.cGoogleAuthText).bold()
                Spacer()
            }
        }
        .padding()
        .cornerRadius(16)
        .background(Color.white)
        .shadow(color: Color.init(red: 0.0, green: 0.0, blue: 0.0, opacity: 0.06), radius: 8, x: 0, y: 4)
        .frame(width: 200, height: 28)
    }
}

Facebook 是同样的想法,但改变了行动:

Button(action: {
    LoginManager().logIn(permissions: ["public_profile", "email"], from: UIHostingController(rootView: self)) { (result, error) in
        //Do stuff here
    }
}) {
    Text("Continue with Facebook")
}

希望对您有所帮助!