SwiftUI中Apple登录按钮出现LayoutConstraints约束冲突问题求助
问题描述
在SwiftUI中使用SignInWithAppleButton实现Apple登录时,控制台输出多条[LayoutConstraints]约束冲突日志,按钮代码及冲突日志如下:
按钮实现代码
SignInWithAppleButton(.signIn, onRequest: { request in isLoggingIn = true request.requestedScopes = [.email] }, onCompletion: { result in switch result { case .success(let authResults): guard let credentials = authResults.credential as? ASAuthorizationAppleIDCredential, let identityToken = credentials.identityToken, let identityTokenString = String(data: identityToken, encoding: .utf8) else { return } print("success") repo.loginwithApple(appleTokenIDString: identityTokenString) { user, error in } case .failure(let error): isLoggingIn = false } }) .signInWithAppleButtonStyle(colorScheme != .light ? .black : .white) .disabled(isLoggingIn)
控制台约束冲突日志
2023-03-20 11:33:12.844732+0200 iosApp[56085:5272326] [LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSAutoresizingMaskLayoutConstraint:0x281f697c0 h=-&- v=-&- ASAuthorizationAppleIDButton:0x106c2d9a0.minX == 0 (active, names: '|':_TtGC7SwiftUI16PlatformViewHostGVS_P10$1b5309f8832PlatformViewRepresentableAdaptorV31_AuthenticationServices_SwiftUIP10$22c416d5817ViewRepresentable__:0x106c2e3f0 )>", "<NSAutoresizingMaskLayoutConstraint:0x281f698b0 h=-&- v=-&- H:[ASAuthorizationAppleIDButton:0x106c2d9a0]-(0)-| (active, names: '|':_TtGC7SwiftUI16PlatformViewHostGVS_P10$1b5309f8832PlatformViewRepresentableAdaptorV31_AuthenticationServices_SwiftUIP10$22c416d5817ViewRepresentable__:0x106c2e3f0 )>", "<NSAutoresizingMaskLayoutConstraint:0x281f69a40 h=--& v=--& _TtGC7SwiftUI16PlatformViewHostGVS_P10$1b5309f8832PlatformViewRepresentableAdaptorV31_AuthenticationServices_SwiftUIP10$22c416d5817ViewRepresentable__:0x106c2e3f0.width == 414 (active)>", "<NSLayoutConstraint:0x281f62f80 ASAuthorizationAppleIDButton:0x106c2d9a0.width <= 375 (active)>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x281f62f80 ASAuthorizationAppleIDButton:0x106c2d9a0.width <= 375 (active)> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful. 2023-03-20 11:33:12.845148+0200 iosApp[56085:5272326] [LayoutConstraints] Unable to simultaneously satisfy constraints. Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) ( "<NSAutoresizingMaskLayoutConstraint:0x281f69900 h=-&- v=-&- ASAuthorizationAppleIDButton:0x106c2d9a0.minY == 0 (active, names: '|':_TtGC7SwiftUI16PlatformViewHostGVS_P10$1b5309f8832PlatformViewRepresentableAdaptorV31_AuthenticationServices_SwiftUIP10$22c416d5817ViewRepresentable__:0x106c2e3f0 )>", "<NSAutoresizingMaskLayoutConstraint:0x281f69950 h=-&- v=-&- V:[ASAuthorizationAppleIDButton:0x106c2d9a0]-(0)-| (active, names: '|':_TtGC7SwiftUI16PlatformViewHostGVS_P10$1b5309f8832PlatformViewRepresentableAdaptorV31_AuthenticationServices_SwiftUIP10$22c416d5817ViewRepresentable__:0x106c2e3f0 )>", "<NSAutoresizingMaskLayoutConstraint:0x281f69ae0 h=--& v=--& _TtGC7SwiftUI16PlatformViewHostGVS_P10$1b5309f8832PlatformViewRepresentableAdaptorV31_AuthenticationServices_SwiftUIP10$22c416d5817ViewRepresentable__:0x106c2e3f0.height == 445 (active)>", "<NSLayoutConstraint:0x281f63020 ASAuthorizationAppleIDButton:0x106c2d9a0.height <= 64 (active)>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0x281f63020 ASAuthorizationAppleIDButton:0x106c2d9a0.height <= 64 (active)> Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
问题原因
从日志可以明确:
SignInWithAppleButton内置约束限制自身宽度≤375、高度≤64- SwiftUI容器给按钮的宿主视图设置了更大的尺寸(宽度414、高度445)
- 按钮的
NSAutoresizingMaskLayoutConstraint强制其填满宿主视图,与自身最大尺寸约束产生冲突
解决方案
给按钮添加尺寸限制,让它保持在自身允许的范围内,同时在容器中居中显示,两种常用方式:
方式一:显式设置最大尺寸并居中
SignInWithAppleButton(.signIn, onRequest: { request in isLoggingIn = true request.requestedScopes = [.email] }, onCompletion: { result in switch result { case .success(let authResults): guard let credentials = authResults.credential as? ASAuthorizationAppleIDCredential, let identityToken = credentials.identityToken, let identityTokenString = String(data: identityToken, encoding: .utf8) else { return } print("success") repo.loginwithApple(appleTokenIDString: identityTokenString) { user, error in } case .failure(let error): isLoggingIn = false } }) .signInWithAppleButtonStyle(colorScheme != .light ? .black : .white) .disabled(isLoggingIn) // 限制最大尺寸不超过按钮自身允许范围 .frame(maxWidth: 375, maxHeight: 64) // 在父容器中居中显示 .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
方式二:使用fixedSize保持固有尺寸
SignInWithAppleButton(.signIn, onRequest: { request in isLoggingIn = true request.requestedScopes = [.email] }, onCompletion: { result in switch result { case .success(let authResults): guard let credentials = authResults.credential as? ASAuthorizationAppleIDCredential, let identityToken = credentials.identityToken, let identityTokenString = String(data: identityToken, encoding: .utf8) else { return } print("success") repo.loginwithApple(appleTokenIDString: identityTokenString) { user, error in } case .failure(let error): isLoggingIn = false } }) .signInWithAppleButtonStyle(colorScheme != .light ? .black : .white) .disabled(isLoggingIn) // 保持按钮自身固有尺寸,避免被过度拉伸 .fixedSize() // 在父容器中居中显示 .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
两种方式均可解决约束冲突,控制台的警告会消失。
内容的提问来源于stack exchange,提问作者user20810748
相关产品推荐
相关产品推荐

