浏览代码

Prevent button text wrapping or truncation (#121)

mdmathias 4 年之前
父节点
当前提交
b44618cc9e

+ 7 - 1
GoogleSignInSwift/Sources/GoogleSignInButton.swift

@@ -63,9 +63,15 @@ public struct GoogleSignInButton: View {
               )
             Image.signInButtonImage
           }
-            .padding(.leading, 1)
+          .padding(.leading, 1)
           Text(viewModel.style.buttonText)
+            .fixedSize()
             .padding(.trailing, textPadding)
+            .frame(
+              width: viewModel.style.widthForButtonText,
+              height: buttonHeight,
+              alignment: .leading
+            )
           Spacer()
         }
       }

+ 29 - 7
GoogleSignInSwift/Sources/GoogleSignInButtonStyling.swift

@@ -50,10 +50,6 @@ let googleImageName = "google"
 /// The layout styles supported by the sign-in button.
 ///
 /// The minimum size of the button depends on the language used for text.
-/// The following dimensions (in points) fit for all languages:
-/// - standard: 230 x 48
-/// - wide:     312 x 48
-/// - icon:     48 x 48 (no text, fixed size)
 @available(iOS 13.0, macOS 10.15, *)
 public enum GoogleSignInButtonStyle {
   case standard
@@ -205,9 +201,13 @@ fileprivate struct Width {
 extension GoogleSignInButtonStyle {
   fileprivate var width: Width {
     switch self {
-    case .icon: return Width(min: iconWidth, max: iconWidth)
-    case .standard: return Width(min: 90, max: .infinity)
-    case .wide: return Width(min: 170, max: .infinity)
+    case .icon:
+      return Width(min: iconWidth, max: iconWidth)
+    case .standard, .wide:
+      return Width(
+        min: iconWidth + widthForButtonText + iconPadding + textPadding,
+        max: .infinity
+      )
     }
   }
 
@@ -222,6 +222,28 @@ extension GoogleSignInButtonStyle {
     case .icon: return ""
     }
   }
+
+  var widthForButtonText: CGFloat {
+    let bt = buttonText as NSString
+    let size = CGSize(width: .max, height: .max)
+    let anyFont: Any
+#if os(iOS) || targetEnvironment(macCatalyst)
+    anyFont = UIFont(name: fontNameRobotoBold, size: fontSize) as Any
+#elseif os(macOS)
+    anyFont = NSFont(name: fontNameRobotoBold, size: fontSize) as Any
+#else
+    fatalError("Unrecognized platform to calculate minimum width")
+#endif
+
+    let rect = bt.boundingRect(
+      with: size,
+      options: [],
+      attributes: [.font: anyFont],
+      context: nil
+    )
+
+    return rect.width
+  }
 }
 
 // MARK: - Button Style