diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2023-05-16 13:53:10 +0200 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2023-05-24 10:35:34 +0200 |
| commit | 95f71099f3b30982a920ddba658f8a4834f80b3a (patch) | |
| tree | bd5401a4fe5b20e6ca2e61fd35112b14cf9100e9 /ios | |
| parent | c8167fddb0abfb0f847efebdc5d1715a75b65bb2 (diff) | |
| download | mullvadvpn-95f71099f3b30982a920ddba658f8a4834f80b3a.tar.xz mullvadvpn-95f71099f3b30982a920ddba658f8a4834f80b3a.zip | |
HeaderBar: hide brand name when buttons overlap it
Diffstat (limited to 'ios')
| -rw-r--r-- | ios/MullvadVPN/Containers/Root/HeaderBarView.swift | 84 | ||||
| -rw-r--r-- | ios/MullvadVPN/UI appearance/UIMetrics.swift | 9 |
2 files changed, 49 insertions, 44 deletions
diff --git a/ios/MullvadVPN/Containers/Root/HeaderBarView.swift b/ios/MullvadVPN/Containers/Root/HeaderBarView.swift index 21a9e1ff93..aab9e39259 100644 --- a/ios/MullvadVPN/Containers/Root/HeaderBarView.swift +++ b/ios/MullvadVPN/Containers/Root/HeaderBarView.swift @@ -13,15 +13,10 @@ class HeaderBarView: UIView { private let brandNameImage = UIImage(named: "LogoText")? .withTintColor(UIColor.HeaderBar.brandNameColor, renderingMode: .alwaysOriginal) - let logoImageView: UIImageView = { - let imageView = UIImageView(image: UIImage(named: "LogoIcon")) - imageView.translatesAutoresizingMaskIntoConstraints = false - return imageView - }() + private let logoImageView = UIImageView(image: UIImage(named: "LogoIcon")) - lazy var brandNameImageView: UIImageView = { + private lazy var brandNameImageView: UIImageView = { let imageView = UIImageView(image: brandNameImage) - imageView.translatesAutoresizingMaskIntoConstraints = false imageView.contentMode = .scaleAspectFill return imageView }() @@ -30,13 +25,12 @@ class HeaderBarView: UIView { let stackView = UIStackView() stackView.axis = .horizontal stackView.distribution = .fill - stackView.translatesAutoresizingMaskIntoConstraints = false stackView.spacing = 16.0 return stackView }() private lazy var deviceName: UILabel = { - let label = UILabel(frame: .zero) + let label = UILabel() label.font = UIFont.systemFont(ofSize: 14) label.textColor = UIColor(white: 1.0, alpha: 0.8) label.setContentHuggingPriority(.defaultHigh, for: .horizontal) @@ -44,13 +38,25 @@ class HeaderBarView: UIView { }() private lazy var timeLeft: UILabel = { - let label = UILabel(frame: .zero) + let label = UILabel() label.font = UIFont.systemFont(ofSize: 14) label.textColor = UIColor(white: 1.0, alpha: 0.8) label.setContentHuggingPriority(.defaultLow, for: .horizontal) return label }() + private lazy var buttonContainer: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [accountButton, settingsButton]) + stackView.spacing = UIMetrics.headerBarButtonSpacing + return stackView + }() + + private let borderLayer: CALayer = { + let layer = CALayer() + layer.backgroundColor = UIColor.HeaderBar.dividerColor.cgColor + return layer + }() + let accountButton: IncreasedHitButton = { let button = makeHeaderBarButton(with: UIImage(named: "IconAccount")) button.accessibilityIdentifier = "AccountButton" @@ -85,17 +91,11 @@ class HeaderBarView: UIView { let barButton = IncreasedHitButton(type: .system) barButton.setImage(buttonImage, for: .normal) barButton.setImage(disabledButtonImage, for: .disabled) - barButton.translatesAutoresizingMaskIntoConstraints = false + barButton.configureForAutoLayout() return barButton } - private let borderLayer: CALayer = { - let layer = CALayer() - layer.backgroundColor = UIColor.HeaderBar.dividerColor.cgColor - return layer - }() - var showsDivider = false { didSet { if showsDivider { @@ -122,49 +122,36 @@ class HeaderBarView: UIView { [deviceName, timeLeft].forEach { deviceInfoHolder.addArrangedSubview($0) } - addConstrainedSubviews([logoImageView, brandNameImageView, accountButton, settingsButton, deviceInfoHolder]) { + addConstrainedSubviews([logoImageView, brandNameImageView, buttonContainer, deviceInfoHolder]) { logoImageView.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor) logoImageView.centerYAnchor.constraint(equalTo: brandNameImageView.centerYAnchor) - logoImageView.widthAnchor.constraint(equalToConstant: 44) - logoImageView.heightAnchor.constraint( - equalTo: logoImageView.widthAnchor, - multiplier: 1 - ) + logoImageView.widthAnchor.constraint(equalToConstant: UIMetrics.headerBarLogoSize) + logoImageView.heightAnchor.constraint(equalTo: logoImageView.widthAnchor, multiplier: 1) brandNameImageView.leadingAnchor.constraint( - equalTo: logoImageView.trailingAnchor, - constant: 9 + equalToSystemSpacingAfter: logoImageView.trailingAnchor, + multiplier: 1 ) brandNameImageView.topAnchor.constraint( equalTo: layoutMarginsGuide.topAnchor, - constant: 22 + constant: UIMetrics.headerBarLogoSize * 0.5 ) brandNameImageView.widthAnchor.constraint( equalTo: brandNameImageView.heightAnchor, multiplier: brandNameAspectRatio ) - brandNameImageView.heightAnchor.constraint(equalToConstant: 18) - layoutMarginsGuide.bottomAnchor.constraint( - equalTo: deviceInfoHolder.bottomAnchor, - constant: 8 - ) + brandNameImageView.heightAnchor.constraint(equalToConstant: UIMetrics.headerBarBrandNameHeight) - accountButton.leadingAnchor.constraint( - greaterThanOrEqualTo: brandNameImageView.trailingAnchor, - constant: 8 - ) - accountButton.centerYAnchor.constraint(equalTo: brandNameImageView.centerYAnchor) - - settingsButton.leadingAnchor.constraint( - equalTo: accountButton.trailingAnchor, - constant: 20 - ).withPriority(.defaultHigh) - settingsButton.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor) - settingsButton.centerYAnchor.constraint(equalTo: accountButton.centerYAnchor) + buttonContainer.centerYAnchor.constraint(equalTo: brandNameImageView.centerYAnchor) + buttonContainer.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor) deviceInfoHolder.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor) deviceInfoHolder.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor) - deviceInfoHolder.topAnchor.constraint(equalTo: logoImageView.bottomAnchor, constant: 7) + deviceInfoHolder.topAnchor.constraint(equalToSystemSpacingBelow: logoImageView.bottomAnchor, multiplier: 1) + layoutMarginsGuide.bottomAnchor.constraint( + equalToSystemSpacingBelow: deviceInfoHolder.bottomAnchor, + multiplier: 1 + ) } } @@ -176,6 +163,15 @@ class HeaderBarView: UIView { super.layoutSubviews() borderLayer.frame = CGRect(x: 0, y: frame.maxY - 1, width: frame.width, height: 1) + brandNameImageView.isHidden = shouldHideBrandName() + } + + /// Returns `true` if container holding buttons intersects brand name. + private func shouldHideBrandName() -> Bool { + let buttonContainerRect = buttonContainer.convert(buttonContainer.bounds, to: nil) + let brandNameRect = brandNameImageView.convert(brandNameImageView.bounds, to: nil) + + return brandNameRect.intersects(buttonContainerRect) } } diff --git a/ios/MullvadVPN/UI appearance/UIMetrics.swift b/ios/MullvadVPN/UI appearance/UIMetrics.swift index b44c5c1cea..9f7d91153f 100644 --- a/ios/MullvadVPN/UI appearance/UIMetrics.swift +++ b/ios/MullvadVPN/UI appearance/UIMetrics.swift @@ -68,4 +68,13 @@ extension UIMetrics { /// Maximum sidebar width in percentage points (0...1) static let maximumSplitViewSidebarWidthFraction: CGFloat = 0.3 + + /// Spacing between buttons in header bar. + static let headerBarButtonSpacing: CGFloat = 20 + + /// Size of a square logo image in header bar. + static let headerBarLogoSize: CGFloat = 44 + + /// Height of brand name. Width is automatically produced based on aspect ratio. + static let headerBarBrandNameHeight: CGFloat = 18 } |
