summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2023-05-30 11:18:02 +0200
committerAndrej Mihajlov <and@mullvad.net>2023-05-30 11:18:02 +0200
commit8ccf23e5029ad51d2d462b769d89b3c7da952636 (patch)
treeb9647f0f996b95c0feb9a0a64117bf387617cb08
parenta90f516f561b739016b33dc3b3832f34e6c7e951 (diff)
parente06aacee9366c0620243d34c4e92f68714240768 (diff)
downloadmullvadvpn-8ccf23e5029ad51d2d462b769d89b3c7da952636.tar.xz
mullvadvpn-8ccf23e5029ad51d2d462b769d89b3c7da952636.zip
Merge branch 'notification-hide-action-button-when-noaction'
-rw-r--r--ios/MullvadVPN/Extensions/NSLayoutConstraint+Helpers.swift1
-rw-r--r--ios/MullvadVPN/Notifications/UI/NotificationBannerView.swift115
-rw-r--r--ios/MullvadVPN/UI appearance/UIColor+Palette.swift2
-rw-r--r--ios/MullvadVPN/UI appearance/UIMetrics.swift29
4 files changed, 68 insertions, 79 deletions
diff --git a/ios/MullvadVPN/Extensions/NSLayoutConstraint+Helpers.swift b/ios/MullvadVPN/Extensions/NSLayoutConstraint+Helpers.swift
index 3a41101a96..7301c17aa4 100644
--- a/ios/MullvadVPN/Extensions/NSLayoutConstraint+Helpers.swift
+++ b/ios/MullvadVPN/Extensions/NSLayoutConstraint+Helpers.swift
@@ -9,6 +9,7 @@
import UIKit
extension NSLayoutConstraint {
+ /// Sets constraint priority and returns `self`
func withPriority(_ priority: UILayoutPriority) -> Self {
self.priority = priority
return self
diff --git a/ios/MullvadVPN/Notifications/UI/NotificationBannerView.swift b/ios/MullvadVPN/Notifications/UI/NotificationBannerView.swift
index 5562db43fd..dc2055765b 100644
--- a/ios/MullvadVPN/Notifications/UI/NotificationBannerView.swift
+++ b/ios/MullvadVPN/Notifications/UI/NotificationBannerView.swift
@@ -9,19 +9,10 @@
import UIKit
final class NotificationBannerView: UIView {
- private static let indicatorViewSize = CGSize(width: 12, height: 12)
- private static let buttonSize = CGSize(width: 18, height: 18)
-
- private let backgroundView: UIVisualEffectView = {
- let effect = UIBlurEffect(style: .dark)
- let visualEffectView = UIVisualEffectView(effect: effect)
- visualEffectView.translatesAutoresizingMaskIntoConstraints = false
- return visualEffectView
- }()
+ private let backgroundView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
private let titleLabel: UILabel = {
let textLabel = UILabel()
- textLabel.translatesAutoresizingMaskIntoConstraints = false
textLabel.font = UIFont.systemFont(ofSize: 17, weight: .bold)
textLabel.textColor = UIColor.InAppNotificationBanner.titleColor
textLabel.numberOfLines = 0
@@ -35,7 +26,6 @@ final class NotificationBannerView: UIView {
private let bodyLabel: UILabel = {
let textLabel = UILabel()
- textLabel.translatesAutoresizingMaskIntoConstraints = false
textLabel.font = UIFont.systemFont(ofSize: 17)
textLabel.textColor = UIColor.InAppNotificationBanner.bodyColor
textLabel.numberOfLines = 0
@@ -49,24 +39,29 @@ final class NotificationBannerView: UIView {
private let indicatorView: UIView = {
let view = UIView()
- view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .dangerColor
- view.layer.cornerRadius = NotificationBannerView.indicatorViewSize.width * 0.5
+ view.layer.cornerRadius = UIMetrics.InAppBannerNotification.indicatorSize.width * 0.5
view.layer.cornerCurve = .circular
return view
}()
private let wrapperView: UIView = {
let view = UIView()
- view.translatesAutoresizingMaskIntoConstraints = false
- view.directionalLayoutMargins = UIMetrics.inAppBannerNotificationLayoutMargins
+ view.directionalLayoutMargins = UIMetrics.InAppBannerNotification.layoutMargins
return view
}()
+ private lazy var bodyStackView: UIStackView = {
+ let stackView = UIStackView(arrangedSubviews: [bodyLabel, actionButton])
+ stackView.alignment = .top
+ stackView.distribution = .fill
+ stackView.spacing = UIStackView.spacingUseSystem
+ return stackView
+ }()
+
private let actionButton: IncreasedHitButton = {
- let button = IncreasedHitButton()
+ let button = IncreasedHitButton(type: .system)
button.tintColor = UIColor.InAppNotificationBanner.actionButtonColor
- button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
@@ -90,65 +85,67 @@ final class NotificationBannerView: UIView {
var action: InAppNotificationAction? {
didSet {
- actionButton.setImage(action?.image, for: .normal)
- actionButton.addTarget(self, action: #selector(didPress), for: .touchUpInside)
+ let image = action?.image
+ let showsAction = image != nil
+
+ actionButton.setImage(image, for: .normal)
+ actionButton.isHidden = !showsAction
}
}
override init(frame: CGRect) {
super.init(frame: frame)
- for subview in [titleLabel, bodyLabel, indicatorView, actionButton] {
- wrapperView.addSubview(subview)
- }
+ addActionHandlers()
+ addSubviews()
+ addConstraints()
+ }
- backgroundView.contentView.addSubview(wrapperView)
- addSubview(backgroundView)
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
- NSLayoutConstraint.activate([
- backgroundView.topAnchor.constraint(equalTo: topAnchor),
- backgroundView.leadingAnchor.constraint(equalTo: leadingAnchor),
- backgroundView.trailingAnchor.constraint(equalTo: trailingAnchor),
- backgroundView.bottomAnchor.constraint(equalTo: bottomAnchor),
+ private func addActionHandlers() {
+ actionButton.addTarget(self, action: #selector(handleActionTap), for: .touchUpInside)
+ }
+
+ private func addSubviews() {
+ wrapperView.addConstrainedSubviews([titleLabel, indicatorView, bodyStackView])
+ backgroundView.contentView.addConstrainedSubviews([wrapperView]) {
+ wrapperView.pinEdgesToSuperview()
+ }
+ addConstrainedSubviews([backgroundView]) {
+ backgroundView.pinEdgesToSuperview()
+ }
+ }
- wrapperView.topAnchor.constraint(equalTo: backgroundView.contentView.topAnchor),
- wrapperView.leadingAnchor.constraint(equalTo: backgroundView.contentView.leadingAnchor),
- wrapperView.trailingAnchor
- .constraint(equalTo: backgroundView.contentView.trailingAnchor),
- wrapperView.bottomAnchor.constraint(equalTo: backgroundView.contentView.bottomAnchor),
+ private func addConstraints() {
+ let actionButtonPriority: UILayoutPriority = .defaultHigh + 1
+ actionButton.setContentCompressionResistancePriority(actionButtonPriority, for: .horizontal)
+ actionButton.setContentCompressionResistancePriority(actionButtonPriority, for: .vertical)
+ actionButton.setContentHuggingPriority(actionButtonPriority, for: .horizontal)
+ actionButton.setContentHuggingPriority(actionButtonPriority, for: .vertical)
+ NSLayoutConstraint.activate([
indicatorView.bottomAnchor.constraint(equalTo: titleLabel.firstBaselineAnchor),
- indicatorView.leadingAnchor
- .constraint(equalTo: wrapperView.layoutMarginsGuide.leadingAnchor),
- indicatorView.widthAnchor.constraint(equalToConstant: Self.indicatorViewSize.width),
- indicatorView.heightAnchor.constraint(equalToConstant: Self.indicatorViewSize.height),
+ indicatorView.leadingAnchor.constraint(equalTo: wrapperView.layoutMarginsGuide.leadingAnchor),
+ indicatorView.widthAnchor
+ .constraint(equalToConstant: UIMetrics.InAppBannerNotification.indicatorSize.width),
+ indicatorView.heightAnchor
+ .constraint(equalToConstant: UIMetrics.InAppBannerNotification.indicatorSize.height),
titleLabel.topAnchor.constraint(equalTo: wrapperView.layoutMarginsGuide.topAnchor),
- titleLabel.leadingAnchor.constraint(
- equalToSystemSpacingAfter: indicatorView.trailingAnchor,
- multiplier: 1
- ),
+ titleLabel.leadingAnchor.constraint(equalToSystemSpacingAfter: indicatorView.trailingAnchor, multiplier: 1),
+ titleLabel.trailingAnchor.constraint(equalTo: wrapperView.layoutMarginsGuide.trailingAnchor),
- bodyLabel.topAnchor.constraint(
- equalToSystemSpacingBelow: titleLabel.bottomAnchor,
- multiplier: 1
- ),
- bodyLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
- bodyLabel.bottomAnchor.constraint(equalTo: wrapperView.layoutMarginsGuide.bottomAnchor),
-
- actionButton.leadingAnchor.constraint(equalTo: bodyLabel.trailingAnchor),
- actionButton.topAnchor.constraint(equalTo: bodyLabel.topAnchor),
- actionButton.trailingAnchor.constraint(equalTo: wrapperView.layoutMarginsGuide.trailingAnchor),
- actionButton.widthAnchor.constraint(equalToConstant: NotificationBannerView.buttonSize.width),
- actionButton.heightAnchor.constraint(equalToConstant: NotificationBannerView.buttonSize.height),
+ bodyStackView.topAnchor.constraint(equalToSystemSpacingBelow: titleLabel.bottomAnchor, multiplier: 1),
+ bodyStackView.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
+ bodyStackView.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor),
+ bodyStackView.bottomAnchor.constraint(equalTo: wrapperView.layoutMarginsGuide.bottomAnchor),
])
}
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
-
- @objc private func didPress() {
+ @objc private func handleActionTap() {
action?.handler?()
}
}
diff --git a/ios/MullvadVPN/UI appearance/UIColor+Palette.swift b/ios/MullvadVPN/UI appearance/UIColor+Palette.swift
index aff21edac2..3cf705cdc3 100644
--- a/ios/MullvadVPN/UI appearance/UIColor+Palette.swift
+++ b/ios/MullvadVPN/UI appearance/UIColor+Palette.swift
@@ -118,7 +118,7 @@ extension UIColor {
static let titleColor = UIColor.white
static let bodyColor = UIColor(white: 1.0, alpha: 0.6)
- static let actionButtonColor = UIColor(white: 1.0, alpha: 0.6)
+ static let actionButtonColor = UIColor(white: 1.0, alpha: 0.8)
}
// Common colors
diff --git a/ios/MullvadVPN/UI appearance/UIMetrics.swift b/ios/MullvadVPN/UI appearance/UIMetrics.swift
index 9f7d91153f..22359687ce 100644
--- a/ios/MullvadVPN/UI appearance/UIMetrics.swift
+++ b/ios/MullvadVPN/UI appearance/UIMetrics.swift
@@ -22,31 +22,22 @@ extension UIMetrics {
static let rowViewLayoutMargins = NSDirectionalEdgeInsets(top: 16, leading: 24, bottom: 16, trailing: 24)
/// Common layout margins for settings cell presentation
- static let settingsCellLayoutMargins = NSDirectionalEdgeInsets(
- top: 16,
- leading: 24,
- bottom: 16,
- trailing: 12
- )
+ static let settingsCellLayoutMargins = NSDirectionalEdgeInsets(top: 16, leading: 24, bottom: 16, trailing: 12)
/// Common layout margins for location cell presentation
- static let selectLocationCellLayoutMargins = NSDirectionalEdgeInsets(
- top: 16,
- leading: 28,
- bottom: 16,
- trailing: 12
- )
+ static let selectLocationCellLayoutMargins = NSDirectionalEdgeInsets(top: 16, leading: 28, bottom: 16, trailing: 12)
/// Common cell indentation width
static let cellIndentationWidth: CGFloat = 16
- /// Layout margins for in-app notification banner presentation
- static let inAppBannerNotificationLayoutMargins = NSDirectionalEdgeInsets(
- top: 16,
- leading: 24,
- bottom: 16,
- trailing: 24
- )
+ /// Group of constants related to in-app notifications banner.
+ enum InAppBannerNotification {
+ /// Layout margins for contents presented within the banner.
+ static let layoutMargins = NSDirectionalEdgeInsets(top: 16, leading: 24, bottom: 16, trailing: 24)
+
+ /// Size of little round severity indicator.
+ static let indicatorSize = CGSize(width: 12, height: 12)
+ }
/// Spacing used in stack views of buttons
static let interButtonSpacing: CGFloat = 16