diff --git a/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift b/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift index aaf35781a9b4..22ccd5bb3ff1 100644 --- a/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift +++ b/WordPress/Classes/ViewRelated/NUX/LoginEmailViewController.swift @@ -135,7 +135,7 @@ class LoginEmailViewController: LoginViewController, SigninKeyboardResponder { return } - let button = UIButton.googleLoginButton() + let button = WPStyleGuide.googleLoginButton() let buttonWrapper = UIView() buttonWrapper.addSubview(button) stackView.addArrangedSubview(buttonWrapper) @@ -143,7 +143,7 @@ class LoginEmailViewController: LoginViewController, SigninKeyboardResponder { buttonWrapper.addConstraints([ buttonWrapper.topAnchor.constraint(equalTo: button.topAnchor, constant: Constants.googleButtonOffset), - buttonWrapper.bottomAnchor.constraint(equalTo: button.bottomAnchor, constant: Constants.googleButtonOffset * -1.0), + buttonWrapper.bottomAnchor.constraint(equalTo: button.bottomAnchor), buttonWrapper.leadingAnchor.constraint(equalTo: button.leadingAnchor), buttonWrapper.trailingAnchor.constraint(equalTo: button.trailingAnchor) ]) diff --git a/WordPress/Classes/ViewRelated/NUX/LoginTextButton.swift b/WordPress/Classes/ViewRelated/NUX/LoginTextButton.swift deleted file mode 100644 index e2fe0190c040..000000000000 --- a/WordPress/Classes/ViewRelated/NUX/LoginTextButton.swift +++ /dev/null @@ -1,61 +0,0 @@ -extension UIButton { - private struct Constants { - static let labelMinHeight: CGFloat = 30.0 - static let googleIconOffset: CGFloat = -1.0 - static let verticalPadding: CGFloat = 5.0 - } - - class func googleLoginButton() -> UIButton { - let label = UILabel() - label.isUserInteractionEnabled = false - label.font = WPStyleGuide.mediumWeightFont(forStyle: .subheadline) - - let baseString = NSLocalizedString("Or you can {G} Log in with Google.", comment: "Label for button to log in using Google. The {G} will be replaced with the Google logo.") - setGoogleString(baseString, for: label) - - let button = UIButton() - setupLoginButtonLayout(button, label: label) - - return button - } - - class func setGoogleString(_ baseString: String, for label: UILabel) { - let labelParts = baseString.components(separatedBy: "{G}") - - let firstPart = labelParts[0] - // 👇 don't want to crash when a translation lacks "{G}" - let lastPart = labelParts.indices.contains(1) ? labelParts[1] : "" - - let labelString = NSMutableAttributedString(string: firstPart, attributes: [NSForegroundColorAttributeName: WPStyleGuide.greyDarken30()]) - - if let googleIcon = UIImage(named: "google"), lastPart != "" { - let googleAttachment = NSTextAttachment() - googleAttachment.image = googleIcon - googleAttachment.bounds = CGRect(x: 0.0, y: label.font.descender + Constants.googleIconOffset, width: googleIcon.size.width, height: googleIcon.size.height) - let iconString = NSAttributedString(attachment: googleAttachment) - labelString.append(iconString) - } - - labelString.append(NSAttributedString(string: lastPart, attributes: [NSForegroundColorAttributeName: WPStyleGuide.wordPressBlue()])) - - label.attributedText = labelString - } - - private class func setupLoginButtonLayout(_ button: UIButton, label: UILabel) { - button.translatesAutoresizingMaskIntoConstraints = false - label.translatesAutoresizingMaskIntoConstraints = false - label.numberOfLines = 0 - button.addSubview(label) - - button.addConstraints([ - button.topAnchor.constraint(equalTo: label.topAnchor, constant: Constants.verticalPadding * -1.0), - button.leftAnchor.constraint(equalTo: label.leftAnchor), - button.rightAnchor.constraint(equalTo: label.rightAnchor), - button.bottomAnchor.constraint(equalTo: label.bottomAnchor, constant: Constants.verticalPadding) - ]) - - label.addConstraints([ - label.heightAnchor.constraint(greaterThanOrEqualToConstant: Constants.labelMinHeight) - ]) - } -} diff --git a/WordPress/Classes/ViewRelated/NUX/WPStyleGuide+Login.swift b/WordPress/Classes/ViewRelated/NUX/WPStyleGuide+Login.swift new file mode 100644 index 000000000000..a1ba6860b2be --- /dev/null +++ b/WordPress/Classes/ViewRelated/NUX/WPStyleGuide+Login.swift @@ -0,0 +1,132 @@ +import WordPressShared + +extension WPStyleGuide { + + private struct Constants { + static let buttonMinHeight: CGFloat = 40.0 + static let googleIconOffset: CGFloat = -1.0 + static let verticalLabelSpacing: CGFloat = 10.0 + } + + /// Common view style for signin view controllers. + /// + /// - Parameters: + /// - view: The view to style. + /// + class func configureColorsForSigninView(_ view: UIView) { + view.backgroundColor = wordPressBlue() + } + + /// Adds a 1password button to a WPWalkthroughTextField, if available + /// + class func configureOnePasswordButtonForTextfield(_ textField: WPWalkthroughTextField, target: NSObject, selector: Selector) { + if !OnePasswordFacade().isOnePasswordEnabled() { + return + } + + let onePasswordButton = UIButton(type: .custom) + onePasswordButton.setImage(UIImage(named: "onepassword-wp-button"), for: UIControlState()) + onePasswordButton.sizeToFit() + + textField.rightView = onePasswordButton + textField.rightViewPadding = UIOffset(horizontal: 20.0, vertical: 0.0) + textField.rightViewMode = .always + + onePasswordButton.addTarget(target, action: selector, for: .touchUpInside) + } + + /// Adds a 1password button to a stack view, if available + /// + class func configureOnePasswordButtonForStackView(_ stack: UIStackView, target: NSObject, selector: Selector) { + if !OnePasswordFacade().isOnePasswordEnabled() { + return + } + + let onePasswordButton = UIButton(type: .custom) + onePasswordButton.setImage(UIImage(named: "onepassword-wp-button"), for: UIControlState()) + onePasswordButton.sizeToFit() + onePasswordButton.setContentHuggingPriority(UILayoutPriorityRequired, for: .horizontal) + onePasswordButton.setContentCompressionResistancePriority(UILayoutPriorityRequired, for: .horizontal) + + stack.addArrangedSubview(onePasswordButton) + + onePasswordButton.addTarget(target, action: selector, for: .touchUpInside) + } + + /// + /// + class func colorForErrorView(_ opaque: Bool) -> UIColor { + let alpha: CGFloat = opaque ? 1.0 : 0.95 + return UIColor(fromRGBAColorWithRed: 17.0, green: 17.0, blue: 17.0, alpha: alpha) + } + + /// + /// + class func edgeInsetForLoginTextFields() -> UIEdgeInsets { + return UIEdgeInsetsMake(7, 20, 7, 20) + } + + /// Return the system font in medium weight for the given style + /// + /// - note: iOS won't return UIFontWeightMedium for dynamic system font :( + /// So instead get the dynamic font size, then ask for the non-dynamic font at that size + /// + class func mediumWeightFont(forStyle style: UIFontTextStyle) -> UIFont { + let fontToGetSize = WPStyleGuide.fontForTextStyle(style) + return UIFont.systemFont(ofSize: fontToGetSize.pointSize, weight: UIFontWeightMedium) + } + + // MARK: - Google Signin Button Methods + + /// A factory method for getting a button for Google Sign-in + /// + /// - Returns: A properly styled UIButton + /// + class func googleLoginButton() -> UIButton { + let baseString = NSLocalizedString("Or you can {G} Log in with Google.", comment: "Label for button to log in using Google. The {G} will be replaced with the Google logo.") + + let font = WPStyleGuide.mediumWeightFont(forStyle: .subheadline) + let button = UIButton() + button.clipsToBounds = true + button.translatesAutoresizingMaskIntoConstraints = false + button.contentHorizontalAlignment = .left + button.titleLabel?.font = font + button.titleLabel?.numberOfLines = 0 + button.titleLabel?.lineBreakMode = .byWordWrapping + + // These constraints work around some issues with multiline buttons and + // vertical layout. Without them the button's height may not account + // for the titleLabel's height. + button.titleLabel?.topAnchor.constraint(equalTo: button.topAnchor, constant: Constants.verticalLabelSpacing).isActive = true + button.titleLabel?.bottomAnchor.constraint(equalTo: button.bottomAnchor, constant: -Constants.verticalLabelSpacing).isActive = true + button.heightAnchor.constraint(greaterThanOrEqualToConstant: Constants.buttonMinHeight).isActive = true + + let attrStrNormal = googleButtonString(baseString, for: font, linkColor: WPStyleGuide.wordPressBlue()) + let attrStrHiglight = googleButtonString(baseString, for: font, linkColor: WPStyleGuide.lightBlue()) + button.setAttributedTitle(attrStrNormal, for: .normal) + button.setAttributedTitle(attrStrHiglight, for: .highlighted) + return button + } + + private class func googleButtonString(_ baseString: String, for font: UIFont, linkColor: UIColor) -> NSAttributedString { + let labelParts = baseString.components(separatedBy: "{G}") + + let firstPart = labelParts[0] + // 👇 don't want to crash when a translation lacks "{G}" + let lastPart = labelParts.indices.contains(1) ? labelParts[1] : "" + + let labelString = NSMutableAttributedString(string: firstPart, attributes: [NSForegroundColorAttributeName: WPStyleGuide.greyDarken30()]) + + if let googleIcon = UIImage(named: "google"), lastPart != "" { + let googleAttachment = NSTextAttachment() + googleAttachment.image = googleIcon + googleAttachment.bounds = CGRect(x: 0.0, y: font.descender + Constants.googleIconOffset, width: googleIcon.size.width, height: googleIcon.size.height) + let iconString = NSAttributedString(attachment: googleAttachment) + labelString.append(iconString) + } + + labelString.append(NSAttributedString(string: lastPart, attributes: [NSForegroundColorAttributeName: linkColor])) + + return labelString + } +} diff --git a/WordPress/Classes/ViewRelated/NUX/WPStyleGuide+NUX.swift b/WordPress/Classes/ViewRelated/NUX/WPStyleGuide+NUX.swift deleted file mode 100644 index a92bb648ff81..000000000000 --- a/WordPress/Classes/ViewRelated/NUX/WPStyleGuide+NUX.swift +++ /dev/null @@ -1,72 +0,0 @@ -import WordPressShared - -extension WPStyleGuide { - - /// Common view style for signin view controllers. - /// - /// - Parameters: - /// - view: The view to style. - /// - class func configureColorsForSigninView(_ view: UIView) { - view.backgroundColor = wordPressBlue() - } - - /// Adds a 1password button to a WPWalkthroughTextField, if available - /// - class func configureOnePasswordButtonForTextfield(_ textField: WPWalkthroughTextField, target: NSObject, selector: Selector) { - if !OnePasswordFacade().isOnePasswordEnabled() { - return - } - - let onePasswordButton = UIButton(type: .custom) - onePasswordButton.setImage(UIImage(named: "onepassword-wp-button"), for: UIControlState()) - onePasswordButton.sizeToFit() - - textField.rightView = onePasswordButton - textField.rightViewPadding = UIOffset(horizontal: 20.0, vertical: 0.0) - textField.rightViewMode = .always - - onePasswordButton.addTarget(target, action: selector, for: .touchUpInside) - } - - /// Adds a 1password button to a stack view, if available - /// - class func configureOnePasswordButtonForStackView(_ stack: UIStackView, target: NSObject, selector: Selector) { - if !OnePasswordFacade().isOnePasswordEnabled() { - return - } - - let onePasswordButton = UIButton(type: .custom) - onePasswordButton.setImage(UIImage(named: "onepassword-wp-button"), for: UIControlState()) - onePasswordButton.sizeToFit() - onePasswordButton.setContentHuggingPriority(UILayoutPriorityRequired, for: .horizontal) - onePasswordButton.setContentCompressionResistancePriority(UILayoutPriorityRequired, for: .horizontal) - - stack.addArrangedSubview(onePasswordButton) - - onePasswordButton.addTarget(target, action: selector, for: .touchUpInside) - } - - /// - /// - class func colorForErrorView(_ opaque: Bool) -> UIColor { - let alpha: CGFloat = opaque ? 1.0 : 0.95 - return UIColor(fromRGBAColorWithRed: 17.0, green: 17.0, blue: 17.0, alpha: alpha) - } - - /// - /// - class func edgeInsetForLoginTextFields() -> UIEdgeInsets { - return UIEdgeInsetsMake(7, 20, 7, 20) - } - - /// Return the system font in medium weight for the given style - /// - /// - note: iOS won't return UIFontWeightMedium for dynamic system font :( - /// So instead get the dynamic font size, then ask for the non-dynamic font at that size - /// - class func mediumWeightFont(forStyle style: UIFontTextStyle) -> UIFont { - let fontToGetSize = WPStyleGuide.fontForTextStyle(style) - return UIFont.systemFont(ofSize: fontToGetSize.pointSize, weight: UIFontWeightMedium) - } -} diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj index 2743637244e5..663284fee420 100644 --- a/WordPress/WordPress.xcodeproj/project.pbxproj +++ b/WordPress/WordPress.xcodeproj/project.pbxproj @@ -204,7 +204,6 @@ 438A809E1EA5DC31005D4651 /* LoginWPComViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 438A809D1EA5DC31005D4651 /* LoginWPComViewController.swift */; }; 43A85B311E9E815B00FA990B /* Login.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 43A85B301E9E815B00FA990B /* Login.storyboard */; }; 43AB7C5E1D3E70510066CB6A /* PostListFilterSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43AB7C5D1D3E70510066CB6A /* PostListFilterSettings.swift */; }; - 43AD9F9C1F4F756C00565CE6 /* LoginTextButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43AD9F9B1F4F756C00565CE6 /* LoginTextButton.swift */; }; 43CC1EC01ED898E30097E334 /* LoginTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43CC1EBF1ED898E30097E334 /* LoginTextField.swift */; }; 43CE48B31F103C1F00768B87 /* FancyAlertViewController+LoginError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43CE48B21F103C1F00768B87 /* FancyAlertViewController+LoginError.swift */; }; 43D2436D1EAFCE3C00D0C77B /* LoginSegueHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43D2436C1EAFCE3C00D0C77B /* LoginSegueHandler.swift */; }; @@ -857,7 +856,7 @@ E63BBC961C5168BE00598BE8 /* SharingAuthorizationHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = E63BBC951C5168BE00598BE8 /* SharingAuthorizationHelper.m */; }; E63C89741CB99A8500649C8F /* SigninHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E63C89731CB99A8500649C8F /* SigninHelperTests.swift */; }; E63C897C1CB9A0D700649C8F /* UITextFieldTextHelperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E63C897B1CB9A0D700649C8F /* UITextFieldTextHelperTests.swift */; }; - E6417B991CA07B9C0084050A /* WPStyleGuide+NUX.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6417B981CA07B9C0084050A /* WPStyleGuide+NUX.swift */; }; + E6417B991CA07B9C0084050A /* WPStyleGuide+Login.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6417B981CA07B9C0084050A /* WPStyleGuide+Login.swift */; }; E6417B9C1CA07C3C0084050A /* NUXAbstractViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6417B9B1CA07C3C0084050A /* NUXAbstractViewController.swift */; }; E6417BAC1CA07F7F0084050A /* SigninHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6417BAB1CA07F7F0084050A /* SigninHelpers.swift */; }; E6431DE51C4E892900FD8D90 /* SharingConnectionsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E6431DE01C4E892900FD8D90 /* SharingConnectionsViewController.m */; }; @@ -1301,7 +1300,6 @@ 438A809D1EA5DC31005D4651 /* LoginWPComViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginWPComViewController.swift; sourceTree = ""; }; 43A85B301E9E815B00FA990B /* Login.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Login.storyboard; sourceTree = ""; }; 43AB7C5D1D3E70510066CB6A /* PostListFilterSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostListFilterSettings.swift; sourceTree = ""; }; - 43AD9F9B1F4F756C00565CE6 /* LoginTextButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginTextButton.swift; sourceTree = ""; }; 43C5A3E11F80AED50008BE81 /* LoginSocialErrorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginSocialErrorCell.swift; sourceTree = ""; }; 43CC1EBF1ED898E30097E334 /* LoginTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginTextField.swift; sourceTree = ""; }; 43CE48B21F103C1F00768B87 /* FancyAlertViewController+LoginError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FancyAlertViewController+LoginError.swift"; sourceTree = ""; }; @@ -2283,7 +2281,7 @@ E63C89731CB99A8500649C8F /* SigninHelperTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SigninHelperTests.swift; sourceTree = ""; }; E63C897B1CB9A0D700649C8F /* UITextFieldTextHelperTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextFieldTextHelperTests.swift; sourceTree = ""; }; E63FF0581C5C297500906C07 /* WordPress 46.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "WordPress 46.xcdatamodel"; sourceTree = ""; }; - E6417B981CA07B9C0084050A /* WPStyleGuide+NUX.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "WPStyleGuide+NUX.swift"; sourceTree = ""; }; + E6417B981CA07B9C0084050A /* WPStyleGuide+Login.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "WPStyleGuide+Login.swift"; sourceTree = ""; }; E6417B9B1CA07C3C0084050A /* NUXAbstractViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NUXAbstractViewController.swift; sourceTree = ""; }; E6417BAB1CA07F7F0084050A /* SigninHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SigninHelpers.swift; sourceTree = ""; }; E6431DDF1C4E892900FD8D90 /* SharingConnectionsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SharingConnectionsViewController.h; sourceTree = ""; }; @@ -5064,7 +5062,6 @@ A2DC5B181953451B009584C3 /* WPNUXHelpBadgeLabel.h */, A2DC5B191953451B009584C3 /* WPNUXHelpBadgeLabel.m */, E6B84DD41F01BDAA00B1B686 /* SiteInfoHeaderView.swift */, - 43AD9F9B1F4F756C00565CE6 /* LoginTextButton.swift */, ); name = Views; sourceTree = ""; @@ -5092,7 +5089,7 @@ E6417B971CA07B0D0084050A /* Style */ = { isa = PBXGroup; children = ( - E6417B981CA07B9C0084050A /* WPStyleGuide+NUX.swift */, + E6417B981CA07B9C0084050A /* WPStyleGuide+Login.swift */, ); name = Style; sourceTree = ""; @@ -6158,7 +6155,7 @@ F1D690171F82914200200E30 /* BuildConfiguration.swift in Sources */, 5D2FB2861AE98C6600F1D4ED /* RestorePostTableViewCell.m in Sources */, E1BEEC651C4E3978000B4FA0 /* PaddedLabel.swift in Sources */, - E6417B991CA07B9C0084050A /* WPStyleGuide+NUX.swift in Sources */, + E6417B991CA07B9C0084050A /* WPStyleGuide+Login.swift in Sources */, E1A6DBE519DC7D230071AC1E /* PostService.m in Sources */, E62AFB6E1DC8E593007484FC /* WPTextAttachmentManager.swift in Sources */, E68580F61E0D91470090EE63 /* WPHorizontalRuleAttachment.swift in Sources */, @@ -6172,7 +6169,6 @@ F128C31C1AFCC95B008C2404 /* WPNavigationMediaPickerViewController+StatusBarStyle.m in Sources */, E1B9128F1BB05B1D003C25B9 /* PeopleCell.swift in Sources */, 313AE4A019E3F20400AAFABE /* CommentViewController.m in Sources */, - 43AD9F9C1F4F756C00565CE6 /* LoginTextButton.swift in Sources */, B5015C581D4FDBB300C9449E /* NotificationActionsService.swift in Sources */, A0E293F10E21027E00C6919C /* WPAddPostCategoryViewController.m in Sources */, E6BDEA731CE4824300682885 /* ReaderSearchTopic.swift in Sources */,