summaryrefslogtreecommitdiffhomepage
path: root/ios
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2023-05-16 13:53:10 +0200
committerAndrej Mihajlov <and@mullvad.net>2023-05-24 10:35:34 +0200
commit95f71099f3b30982a920ddba658f8a4834f80b3a (patch)
treebd5401a4fe5b20e6ca2e61fd35112b14cf9100e9 /ios
parentc8167fddb0abfb0f847efebdc5d1715a75b65bb2 (diff)
downloadmullvadvpn-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.swift84
-rw-r--r--ios/MullvadVPN/UI appearance/UIMetrics.swift9
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
}