summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBug Magnet <marco.nikic@mullvad.net>2025-06-09 16:08:24 +0200
committerJon Petersson <jon.petersson@mullvad.net>2025-06-23 11:53:36 +0200
commit90cd5b179b19c27215dbbcc85993c9957ba10411 (patch)
tree4f2f2e3cc7fbd34900aa0d5ecdb158503bfe1d82
parent75d3d8c4c5283da940d0194f89d6b3ab9b38e151 (diff)
downloadmullvadvpn-90cd5b179b19c27215dbbcc85993c9957ba10411.tar.xz
mullvadvpn-90cd5b179b19c27215dbbcc85993c9957ba10411.zip
Enable more use of dynamic fonts
-rw-r--r--ios/CHANGELOG.md1
-rw-r--r--ios/MullvadVPN/Containers/Root/HeaderBarView.swift2
-rw-r--r--ios/MullvadVPN/Coordinators/Settings/APIAccess/AboutViewController.swift9
-rw-r--r--ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/ListCellContentConfiguration.swift9
-rw-r--r--ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/ListCellContentView.swift3
-rw-r--r--ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/SwitchCellContentConfiguration.swift2
-rw-r--r--ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/SwitchCellContentView.swift1
-rw-r--r--ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/TextCellContentConfiguration.swift8
-rw-r--r--ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/TextCellContentView.swift2
-rw-r--r--ios/MullvadVPN/Coordinators/Settings/APIAccess/Edit/EditAccessMethodViewController.swift3
-rw-r--r--ios/MullvadVPN/Coordinators/Settings/APIAccess/Edit/MethodSettings/MethodSettingsViewController.swift2
-rw-r--r--ios/MullvadVPN/Coordinators/Settings/IPOverride/IPOverrideStatusView.swift6
-rw-r--r--ios/MullvadVPN/Coordinators/Settings/Views/SwitchRowView.swift2
-rw-r--r--ios/MullvadVPN/Extensions/UIListContentConfiguration+Extensions.swift17
-rw-r--r--ios/MullvadVPN/Notifications/UI/NotificationBannerView.swift2
-rw-r--r--ios/MullvadVPN/View controllers/Account/AccountDeviceRow.swift7
-rw-r--r--ios/MullvadVPN/View controllers/Account/AccountExpiryRow.swift6
-rw-r--r--ios/MullvadVPN/View controllers/Account/AccountNumberRow.swift8
-rw-r--r--ios/MullvadVPN/View controllers/Account/RestorePurchasesView.swift3
-rw-r--r--ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionContentView.swift13
-rw-r--r--ios/MullvadVPN/View controllers/CreationAccount/Welcome/WelcomeContentView.swift12
-rw-r--r--ios/MullvadVPN/View controllers/DeviceList/DeviceManagementContentView.swift321
-rw-r--r--ios/MullvadVPN/View controllers/DeviceList/DeviceRowView.swift137
-rw-r--r--ios/MullvadVPN/View controllers/Login/AccountInputGroupView.swift9
-rw-r--r--ios/MullvadVPN/View controllers/Login/LoginContentView.swift10
-rw-r--r--ios/MullvadVPN/View controllers/OutOfTime/OutOfTimeContentView.swift6
-rw-r--r--ios/MullvadVPN/View controllers/ProblemReport/ProblemReportReviewViewController.swift6
-rw-r--r--ios/MullvadVPN/View controllers/ProblemReport/ProblemReportSubmissionOverlayView.swift6
-rw-r--r--ios/MullvadVPN/View controllers/ProblemReport/ProblemReportViewController+ViewManagement.swift8
-rw-r--r--ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherContentView.swift13
-rw-r--r--ios/MullvadVPN/View controllers/RevokedDevice/RevokedDeviceViewController.swift9
-rw-r--r--ios/MullvadVPN/View controllers/SelectLocation/LocationCell.swift10
-rw-r--r--ios/MullvadVPN/View controllers/SelectLocation/LocationSectionHeaderFooterView.swift1
-rw-r--r--ios/MullvadVPN/View controllers/Settings/SettingsCell.swift8
-rw-r--r--ios/MullvadVPN/View controllers/Settings/SettingsDNSInfoCell.swift1
-rw-r--r--ios/MullvadVPN/View controllers/Settings/SettingsDNSTextCell.swift3
-rw-r--r--ios/MullvadVPN/View controllers/Settings/SettingsHeaderView.swift5
-rw-r--r--ios/MullvadVPN/View controllers/VPNSettings/CustomDNSCellFactory.swift2
-rw-r--r--ios/MullvadVPN/Views/AppButton.swift2
-rw-r--r--ios/MullvadVPN/Views/CheckboxView.swift2
-rw-r--r--ios/MullvadVPN/Views/CustomTextView.swift3
-rw-r--r--ios/MullvadVPN/Views/InfoHeaderView.swift5
-rw-r--r--ios/MullvadVPN/Views/StatusImageView.swift5
43 files changed, 611 insertions, 79 deletions
diff --git a/ios/CHANGELOG.md b/ios/CHANGELOG.md
index 1b681ad1ac..23cf7a809a 100644
--- a/ios/CHANGELOG.md
+++ b/ios/CHANGELOG.md
@@ -26,6 +26,7 @@ Line wrap the file at 100 chars. Th
- Make feature indicators clickable shortcuts to their corresponding settings.
- Let users cancel sending a problem report.
- Add possibility to manage devices from account view.
+- Add support for Dynamic Type to allow fonts to scale according to user's system settings.
### Changed
- Replace Classic McEliece with HQC as one of the post-quantum safe key exchange
diff --git a/ios/MullvadVPN/Containers/Root/HeaderBarView.swift b/ios/MullvadVPN/Containers/Root/HeaderBarView.swift
index 977296c532..9188a9cd50 100644
--- a/ios/MullvadVPN/Containers/Root/HeaderBarView.swift
+++ b/ios/MullvadVPN/Containers/Root/HeaderBarView.swift
@@ -31,6 +31,7 @@ class HeaderBarView: UIView {
private lazy var deviceNameLabel: UILabel = {
let label = UILabel()
label.font = .mullvadMiniSemiBold
+ label.adjustsFontForContentSizeCategory = true
label.textColor = UIColor(white: 1.0, alpha: 0.8)
label.setContentHuggingPriority(.defaultHigh, for: .horizontal)
label.setAccessibilityIdentifier(.headerDeviceNameLabel)
@@ -40,6 +41,7 @@ class HeaderBarView: UIView {
private lazy var timeLeftLabel: UILabel = {
let label = UILabel()
label.font = .mullvadMiniSemiBold
+ label.adjustsFontForContentSizeCategory = true
label.textColor = UIColor(white: 1.0, alpha: 0.8)
label.setContentHuggingPriority(.defaultLow, for: .horizontal)
return label
diff --git a/ios/MullvadVPN/Coordinators/Settings/APIAccess/AboutViewController.swift b/ios/MullvadVPN/Coordinators/Settings/APIAccess/AboutViewController.swift
index 0752fee599..27c790bd89 100644
--- a/ios/MullvadVPN/Coordinators/Settings/APIAccess/AboutViewController.swift
+++ b/ios/MullvadVPN/Coordinators/Settings/APIAccess/AboutViewController.swift
@@ -56,7 +56,8 @@ class AboutViewController: UIViewController {
let label = UILabel()
label.text = header
- label.font = .systemFont(ofSize: 28, weight: .bold)
+ label.font = .mullvadLarge
+ label.adjustsFontForContentSizeCategory = true
label.textColor = .primaryTextColor
label.numberOfLines = 0
label.textAlignment = .center
@@ -69,7 +70,8 @@ class AboutViewController: UIViewController {
let label = UILabel()
label.text = preamble
- label.font = .systemFont(ofSize: 18)
+ label.font = .mullvadSmall
+ label.adjustsFontForContentSizeCategory = true
label.textColor = .primaryTextColor
label.numberOfLines = 0
label.textAlignment = .center
@@ -82,7 +84,8 @@ class AboutViewController: UIViewController {
let label = UILabel()
label.text = text
- label.font = .systemFont(ofSize: 15)
+ label.font = .mullvadTiny
+ label.adjustsFontForContentSizeCategory = true
label.textColor = .secondaryTextColor
label.numberOfLines = 0
diff --git a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/ListCellContentConfiguration.swift b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/ListCellContentConfiguration.swift
index fbae59d0fe..c1d9621f38 100644
--- a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/ListCellContentConfiguration.swift
+++ b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/ListCellContentConfiguration.swift
@@ -11,17 +11,20 @@ import UIKit
/// Content configuration presenting a label and switch control.
struct ListCellContentConfiguration: UIContentConfiguration, Equatable {
struct TextProperties: Equatable {
- var font = UIFont.systemFont(ofSize: 17)
+ var font = UIFont.mullvadSmall
+ var adjustsFontForContentSizeCategory = true
var color = UIColor.Cell.titleTextColor
}
struct SecondaryTextProperties: Equatable {
- var font = UIFont.systemFont(ofSize: 17)
+ var font = UIFont.mullvadSmall
+ var adjustsFontForContentSizeCategory = true
var color = UIColor.Cell.detailTextColor.withAlphaComponent(0.8)
}
struct TertiaryTextProperties: Equatable {
- var font = UIFont.systemFont(ofSize: 15)
+ var font = UIFont.mullvadTiny
+ var adjustsFontForContentSizeCategory = true
var color = UIColor.Cell.titleTextColor.withAlphaComponent(0.6)
}
diff --git a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/ListCellContentView.swift b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/ListCellContentView.swift
index 57264e88d5..6f40b6b8ad 100644
--- a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/ListCellContentView.swift
+++ b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/ListCellContentView.swift
@@ -59,6 +59,7 @@ class ListCellContentView: UIView, UIContentView, UITextFieldDelegate {
let textProperties = actualConfiguration.textProperties
textLabel.font = textProperties.font
+ textLabel.adjustsFontForContentSizeCategory = textProperties.adjustsFontForContentSizeCategory
textLabel.textColor = textProperties.color
textLabel.text = actualConfiguration.text
@@ -68,6 +69,7 @@ class ListCellContentView: UIView, UIContentView, UITextFieldDelegate {
let textProperties = actualConfiguration.secondaryTextProperties
secondaryTextLabel.font = textProperties.font
+ secondaryTextLabel.adjustsFontForContentSizeCategory = textProperties.adjustsFontForContentSizeCategory
secondaryTextLabel.textColor = textProperties.color
secondaryTextLabel.text = actualConfiguration.secondaryText
@@ -77,6 +79,7 @@ class ListCellContentView: UIView, UIContentView, UITextFieldDelegate {
let textProperties = actualConfiguration.tertiaryTextProperties
tertiaryTextLabel.font = textProperties.font
+ tertiaryTextLabel.adjustsFontForContentSizeCategory = textProperties.adjustsFontForContentSizeCategory
tertiaryTextLabel.textColor = textProperties.color
tertiaryTextLabel.text = actualConfiguration.tertiaryText
diff --git a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/SwitchCellContentConfiguration.swift b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/SwitchCellContentConfiguration.swift
index 8a68a72164..3a98733ca2 100644
--- a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/SwitchCellContentConfiguration.swift
+++ b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/SwitchCellContentConfiguration.swift
@@ -11,7 +11,7 @@ import UIKit
/// Content configuration presenting a label and switch control.
struct SwitchCellContentConfiguration: UIContentConfiguration, Equatable {
struct TextProperties: Equatable {
- var font = UIFont.systemFont(ofSize: 17)
+ var font = UIFont.mullvadSmall
var color = UIColor.Cell.titleTextColor
}
diff --git a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/SwitchCellContentView.swift b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/SwitchCellContentView.swift
index cbf50170aa..a4e2239768 100644
--- a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/SwitchCellContentView.swift
+++ b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/SwitchCellContentView.swift
@@ -68,6 +68,7 @@ class SwitchCellContentView: UIView, UIContentView, UITextFieldDelegate {
let textProperties = actualConfiguration.textProperties
textLabel.font = textProperties.font
+ textLabel.adjustsFontForContentSizeCategory = true
textLabel.textColor = textProperties.color
textLabel.text = actualConfiguration.text
diff --git a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/TextCellContentConfiguration.swift b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/TextCellContentConfiguration.swift
index 97d7bba9d0..f011975517 100644
--- a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/TextCellContentConfiguration.swift
+++ b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/TextCellContentConfiguration.swift
@@ -49,7 +49,8 @@ struct TextCellContentConfiguration: UIContentConfiguration, Equatable {
extension TextCellContentConfiguration {
/// The text label properties.
struct TextProperties: Equatable {
- var font = UIFont.systemFont(ofSize: 17)
+ var font = UIFont.mullvadSmall
+ var adjustsFontForContentSizeCategory = true
var color = UIColor.Cell.titleTextColor
}
@@ -77,7 +78,10 @@ extension TextCellContentConfiguration {
/// Text field configuration.
struct TextFieldProperties: Equatable {
/// Text font.
- var font = UIFont.systemFont(ofSize: 17)
+ var font = UIFont.mullvadSmall
+
+ var adjustsFontForContentSizeCategory = true
+
/// Text color.
var textColor = UIColor.Cell.textFieldTextColor
diff --git a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/TextCellContentView.swift b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/TextCellContentView.swift
index 46f52ac996..43ac40bbd3 100644
--- a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/TextCellContentView.swift
+++ b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Cells/TextCellContentView.swift
@@ -71,6 +71,7 @@ class TextCellContentView: UIView, UIContentView, UIGestureRecognizerDelegate, S
textLabel.font = textProperties.font
textLabel.textColor = textProperties.color
+ textLabel.adjustsFontForContentSizeCategory = true
textLabel.text = actualConfiguration.text
}
@@ -178,6 +179,7 @@ extension TextCellContentConfiguration.TextFieldProperties {
@MainActor
func apply(to textField: CustomTextField) {
textField.font = font
+ textField.adjustsFontForContentSizeCategory = adjustsFontForContentSizeCategory
textField.backgroundColor = .clear
textField.textColor = textColor
textField.placeholderTextColor = placeholderColor
diff --git a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Edit/EditAccessMethodViewController.swift b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Edit/EditAccessMethodViewController.swift
index 1f1742c1bd..97afabdce1 100644
--- a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Edit/EditAccessMethodViewController.swift
+++ b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Edit/EditAccessMethodViewController.swift
@@ -74,7 +74,8 @@ class EditAccessMethodViewController: UIViewController {
private func createTitle() -> UIView {
let label = UILabel()
- label.font = UIFont.preferredFont(forTextStyle: .largeTitle, weight: .bold)
+ label.font = .mullvadBig
+ label.adjustsFontForContentSizeCategory = true
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
label.lineBreakStrategy = []
diff --git a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Edit/MethodSettings/MethodSettingsViewController.swift b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Edit/MethodSettings/MethodSettingsViewController.swift
index 9b5a09d4cd..ce3efe478b 100644
--- a/ios/MullvadVPN/Coordinators/Settings/APIAccess/Edit/MethodSettings/MethodSettingsViewController.swift
+++ b/ios/MullvadVPN/Coordinators/Settings/APIAccess/Edit/MethodSettings/MethodSettingsViewController.swift
@@ -267,7 +267,7 @@ class MethodSettingsViewController: UITableViewController {
let validationResult = Result { try subject.value.validate() }
let validationError = validationResult.error as? AccessMethodValidationError
- // Only look for format errors for test(save validation.
+ // Only look for format errors for test (save validation).
contentValidationErrors = validationError?.fieldErrors.filter { error in
error.kind != .emptyValue
} ?? []
diff --git a/ios/MullvadVPN/Coordinators/Settings/IPOverride/IPOverrideStatusView.swift b/ios/MullvadVPN/Coordinators/Settings/IPOverride/IPOverrideStatusView.swift
index fbb1ef2102..1618f9079f 100644
--- a/ios/MullvadVPN/Coordinators/Settings/IPOverride/IPOverrideStatusView.swift
+++ b/ios/MullvadVPN/Coordinators/Settings/IPOverride/IPOverrideStatusView.swift
@@ -11,7 +11,8 @@ import UIKit
class IPOverrideStatusView: UIView {
private lazy var titleLabel: UILabel = {
let label = UILabel()
- label.font = .systemFont(ofSize: 15, weight: .bold)
+ label.font = .mullvadTinySemiBold
+ label.adjustsFontForContentSizeCategory = true
label.textColor = .white
return label
}()
@@ -22,7 +23,8 @@ class IPOverrideStatusView: UIView {
private lazy var descriptionLabel: UILabel = {
let label = UILabel()
- label.font = .systemFont(ofSize: 12, weight: .semibold)
+ label.font = .mullvadMiniSemiBold
+ label.adjustsFontForContentSizeCategory = true
label.textColor = .white.withAlphaComponent(0.6)
label.numberOfLines = 0
return label
diff --git a/ios/MullvadVPN/Coordinators/Settings/Views/SwitchRowView.swift b/ios/MullvadVPN/Coordinators/Settings/Views/SwitchRowView.swift
index 392be7934f..e4540c0ccc 100644
--- a/ios/MullvadVPN/Coordinators/Settings/Views/SwitchRowView.swift
+++ b/ios/MullvadVPN/Coordinators/Settings/Views/SwitchRowView.swift
@@ -27,7 +27,7 @@ struct SwitchRowView: View {
infoButtonAction: didTapInfoButton
))
.disabled(disabled)
- .font(.headline)
+ .font(.mullvadSmall)
.frame(height: UIMetrics.SettingsRowView.height)
.padding(UIMetrics.SettingsRowView.layoutMargins)
.background(Color(.primaryColor))
diff --git a/ios/MullvadVPN/Extensions/UIListContentConfiguration+Extensions.swift b/ios/MullvadVPN/Extensions/UIListContentConfiguration+Extensions.swift
index a68406908f..2247f826c2 100644
--- a/ios/MullvadVPN/Extensions/UIListContentConfiguration+Extensions.swift
+++ b/ios/MullvadVPN/Extensions/UIListContentConfiguration+Extensions.swift
@@ -12,8 +12,11 @@ extension UIListContentConfiguration {
/// Returns cell configured with default text attribute used in Mullvad UI.
static func mullvadCell(tableStyle: UITableView.Style, isEnabled: Bool = true) -> UIListContentConfiguration {
var configuration = cell()
- configuration.textProperties.font = .systemFont(ofSize: 17)
+ configuration.textProperties.font = .mullvadSmall
+ configuration.textProperties.adjustsFontForContentSizeCategory = true
configuration.textProperties.color = .Cell.titleTextColor.withAlphaComponent(isEnabled ? 1 : 0.8)
+ configuration.secondaryTextProperties.font = .mullvadSmall
+ configuration.secondaryTextProperties.adjustsFontForContentSizeCategory = true
applyMargins(to: &configuration, tableStyle: tableStyle)
@@ -23,10 +26,12 @@ extension UIListContentConfiguration {
/// Returns value cell configured with default text attribute used in Mullvad UI.
static func mullvadValueCell(tableStyle: UITableView.Style, isEnabled: Bool = true) -> UIListContentConfiguration {
var configuration = valueCell()
- configuration.textProperties.font = .systemFont(ofSize: 17)
+ configuration.textProperties.font = .mullvadSmall
+ configuration.textProperties.adjustsFontForContentSizeCategory = true
configuration.textProperties.color = .Cell.titleTextColor.withAlphaComponent(isEnabled ? 1 : 0.8)
configuration.secondaryTextProperties.color = .Cell.detailTextColor.withAlphaComponent(0.8)
- configuration.secondaryTextProperties.font = .systemFont(ofSize: 17)
+ configuration.secondaryTextProperties.font = .mullvadSmall
+ configuration.secondaryTextProperties.adjustsFontForContentSizeCategory = true
applyMargins(to: &configuration, tableStyle: tableStyle)
@@ -37,7 +42,8 @@ extension UIListContentConfiguration {
static func mullvadGroupedHeader(tableStyle: UITableView.Style) -> UIListContentConfiguration {
var configuration = groupedHeader()
configuration.textProperties.color = .TableSection.headerTextColor
- configuration.textProperties.font = .systemFont(ofSize: 13)
+ configuration.textProperties.font = .mullvadTiny
+ configuration.textProperties.adjustsFontForContentSizeCategory = true
applyMargins(to: &configuration, tableStyle: tableStyle)
@@ -48,7 +54,8 @@ extension UIListContentConfiguration {
static func mullvadGroupedFooter(tableStyle: UITableView.Style) -> UIListContentConfiguration {
var configuration = groupedFooter()
configuration.textProperties.color = .TableSection.footerTextColor
- configuration.textProperties.font = .systemFont(ofSize: 13)
+ configuration.textProperties.font = .mullvadMini
+ configuration.textProperties.adjustsFontForContentSizeCategory = true
applyMargins(to: &configuration, tableStyle: tableStyle)
diff --git a/ios/MullvadVPN/Notifications/UI/NotificationBannerView.swift b/ios/MullvadVPN/Notifications/UI/NotificationBannerView.swift
index 54b2695b3e..ff7f5f016b 100644
--- a/ios/MullvadVPN/Notifications/UI/NotificationBannerView.swift
+++ b/ios/MullvadVPN/Notifications/UI/NotificationBannerView.swift
@@ -14,6 +14,7 @@ final class NotificationBannerView: UIView {
private let titleLabel: UILabel = {
let textLabel = UILabel()
textLabel.font = .mullvadTinySemiBold
+ textLabel.adjustsFontForContentSizeCategory = true
textLabel.textColor = UIColor.InAppNotificationBanner.titleColor
textLabel.numberOfLines = 0
textLabel.lineBreakMode = .byWordWrapping
@@ -24,6 +25,7 @@ final class NotificationBannerView: UIView {
private let bodyLabel: UILabel = {
let textLabel = UILabel()
textLabel.font = .mullvadTiny
+ textLabel.adjustsFontForContentSizeCategory = true
textLabel.textColor = UIColor.InAppNotificationBanner.bodyColor
textLabel.numberOfLines = 0
textLabel.lineBreakMode = .byWordWrapping
diff --git a/ios/MullvadVPN/View controllers/Account/AccountDeviceRow.swift b/ios/MullvadVPN/View controllers/Account/AccountDeviceRow.swift
index 54b9188a1d..399358c82a 100644
--- a/ios/MullvadVPN/View controllers/Account/AccountDeviceRow.swift
+++ b/ios/MullvadVPN/View controllers/Account/AccountDeviceRow.swift
@@ -27,14 +27,16 @@ class AccountDeviceRow: UIView {
value: "Device name",
comment: ""
)
- label.font = UIFont.systemFont(ofSize: 14)
+ label.font = .mullvadTiny
+ label.adjustsFontForContentSizeCategory = true
label.textColor = UIColor(white: 1.0, alpha: 0.6)
return label
}()
private let deviceLabel: UILabel = {
let label = UILabel()
- label.font = UIFont.systemFont(ofSize: 17)
+ label.font = .mullvadSmall
+ label.adjustsFontForContentSizeCategory = true
label.textColor = .white
return label
}()
@@ -42,6 +44,7 @@ class AccountDeviceRow: UIView {
private let deviceManagementButton: UIButton = {
let button = IncreasedHitButton(type: .system)
button.isExclusiveTouch = true
+ button.adjustsImageSizeForAccessibilityContentSizeCategory = true
button.setAccessibilityIdentifier(.deviceManagementButton)
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont.mullvadSmallSemiBold,
diff --git a/ios/MullvadVPN/View controllers/Account/AccountExpiryRow.swift b/ios/MullvadVPN/View controllers/Account/AccountExpiryRow.swift
index 4f39673bea..00ebb6b16e 100644
--- a/ios/MullvadVPN/View controllers/Account/AccountExpiryRow.swift
+++ b/ios/MullvadVPN/View controllers/Account/AccountExpiryRow.swift
@@ -52,7 +52,8 @@ class AccountExpiryRow: UIView {
value: "Paid until",
comment: ""
)
- textLabel.font = UIFont.systemFont(ofSize: 14)
+ textLabel.font = .mullvadTiny
+ textLabel.adjustsFontForContentSizeCategory = true
textLabel.textColor = UIColor(white: 1.0, alpha: 0.6)
return textLabel
}()
@@ -60,7 +61,8 @@ class AccountExpiryRow: UIView {
private let valueLabel: UILabel = {
let valueLabel = UILabel()
valueLabel.translatesAutoresizingMaskIntoConstraints = false
- valueLabel.font = UIFont.systemFont(ofSize: 17)
+ valueLabel.font = .mullvadSmall
+ valueLabel.adjustsFontForContentSizeCategory = true
valueLabel.textColor = .white
valueLabel.setAccessibilityIdentifier(.accountPagePaidUntilLabel)
return valueLabel
diff --git a/ios/MullvadVPN/View controllers/Account/AccountNumberRow.swift b/ios/MullvadVPN/View controllers/Account/AccountNumberRow.swift
index c14197f32b..6dbc787f58 100644
--- a/ios/MullvadVPN/View controllers/Account/AccountNumberRow.swift
+++ b/ios/MullvadVPN/View controllers/Account/AccountNumberRow.swift
@@ -32,14 +32,16 @@ class AccountNumberRow: UIView {
value: "Account number",
comment: ""
)
- textLabel.font = UIFont.systemFont(ofSize: 14)
+ textLabel.font = .mullvadTiny
+ textLabel.adjustsFontForContentSizeCategory = true
textLabel.textColor = UIColor(white: 1.0, alpha: 0.6)
return textLabel
}()
private let accountNumberLabel: UILabel = {
let textLabel = UILabel()
- textLabel.font = UIFont.monospacedSystemFont(ofSize: 17, weight: .regular)
+ textLabel.font = .mullvadMiniSemiBold
+ textLabel.adjustsFontForContentSizeCategory = true
textLabel.textColor = .white
return textLabel
}()
@@ -47,12 +49,14 @@ class AccountNumberRow: UIView {
private let showHideButton: UIButton = {
let button = UIButton(type: .system)
button.tintColor = .white
+ button.adjustsImageSizeForAccessibilityContentSizeCategory = true
button.setContentHuggingPriority(.defaultHigh, for: .horizontal)
return button
}()
private let copyButton: UIButton = {
let button = UIButton(type: .system)
+ button.adjustsImageSizeForAccessibilityContentSizeCategory = true
button.tintColor = .white
button.setContentHuggingPriority(.defaultHigh, for: .horizontal)
return button
diff --git a/ios/MullvadVPN/View controllers/Account/RestorePurchasesView.swift b/ios/MullvadVPN/View controllers/Account/RestorePurchasesView.swift
index 3de7d1376a..87c85913bb 100644
--- a/ios/MullvadVPN/View controllers/Account/RestorePurchasesView.swift
+++ b/ios/MullvadVPN/View controllers/Account/RestorePurchasesView.swift
@@ -26,6 +26,7 @@ class RestorePurchasesView: UIView {
let label = UILabel()
label.setAccessibilityIdentifier(.restorePurchasesButton)
label.attributedText = makeAttributedString()
+ label.adjustsFontForContentSizeCategory = true
label.isUserInteractionEnabled = true
label.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(didTapRestoreButton)))
return label
@@ -69,7 +70,7 @@ class RestorePurchasesView: UIView {
)
return NSAttributedString(string: text, attributes: [
- .font: UIFont.systemFont(ofSize: 13, weight: .semibold),
+ .font: UIFont.mullvadMini,
.foregroundColor: UIColor.white,
.underlineStyle: NSUnderlineStyle.single.rawValue,
])
diff --git a/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionContentView.swift b/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionContentView.swift
index 521b5bc95f..6772016fba 100644
--- a/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionContentView.swift
+++ b/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionContentView.swift
@@ -34,8 +34,9 @@ class AccountDeletionContentView: UIView {
private let titleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
- label.font = .preferredFont(forTextStyle: .title2, weight: .bold)
+ label.font = .mullvadLarge
label.numberOfLines = .zero
+ label.adjustsFontForContentSizeCategory = true
label.lineBreakMode = .byWordWrapping
label.textColor = .white
label.text = NSLocalizedString(
@@ -50,8 +51,9 @@ class AccountDeletionContentView: UIView {
private let messageLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
- label.font = .preferredFont(forTextStyle: .body, weight: .bold)
+ label.font = .mullvadSmallSemiBold
label.numberOfLines = .zero
+ label.adjustsFontForContentSizeCategory = true
label.lineBreakMode = .byWordWrapping
label.textColor = .white
return label
@@ -60,8 +62,9 @@ class AccountDeletionContentView: UIView {
private let tipLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
- label.font = .preferredFont(forTextStyle: .footnote, weight: .bold)
+ label.font = .mullvadMiniSemiBold
label.numberOfLines = .zero
+ label.adjustsFontForContentSizeCategory = true
label.lineBreakMode = .byWordWrapping
label.textColor = .white
label.text = NSLocalizedString(
@@ -82,7 +85,7 @@ class AccountDeletionContentView: UIView {
let groupingStyle = AccountTextField.GroupingStyle.lastPart
let textField = AccountTextField(groupingStyle: groupingStyle)
textField.setAccessibilityIdentifier(.deleteAccountTextField)
- textField.font = .preferredFont(forTextStyle: .body, weight: .bold)
+ textField.font = .mullvadSmallSemiBold
textField.placeholder = Array(repeating: "X", count: 4).joined()
textField.placeholderTextColor = .lightGray
textField.textContentType = .username
@@ -94,6 +97,7 @@ class AccountDeletionContentView: UIView {
textField.keyboardType = .numberPad
textField.returnKeyType = .done
textField.enablesReturnKeyAutomatically = false
+ textField.adjustsFontForContentSizeCategory = true
textField.backgroundColor = .white
textField.borderStyle = .line
return textField
@@ -161,6 +165,7 @@ class AccountDeletionContentView: UIView {
let label = UILabel()
label.font = .preferredFont(forTextStyle: .body)
label.numberOfLines = 2
+ label.adjustsFontForContentSizeCategory = true
label.lineBreakMode = .byWordWrapping
label.textColor = .red
label.setContentHuggingPriority(.defaultLow, for: .horizontal)
diff --git a/ios/MullvadVPN/View controllers/CreationAccount/Welcome/WelcomeContentView.swift b/ios/MullvadVPN/View controllers/CreationAccount/Welcome/WelcomeContentView.swift
index ec5db174a9..3bc8e317bc 100644
--- a/ios/MullvadVPN/View controllers/CreationAccount/Welcome/WelcomeContentView.swift
+++ b/ios/MullvadVPN/View controllers/CreationAccount/Welcome/WelcomeContentView.swift
@@ -24,7 +24,7 @@ final class WelcomeContentView: UIView, Sendable {
private let titleLabel: UILabel = {
let label = UILabel()
- label.font = .preferredFont(forTextStyle: .largeTitle, weight: .bold)
+ label.font = .mullvadLarge
label.textColor = .white
label.adjustsFontForContentSizeCategory = true
label.lineBreakMode = .byWordWrapping
@@ -40,7 +40,7 @@ final class WelcomeContentView: UIView, Sendable {
private let subtitleLabel: UILabel = {
let label = UILabel()
- label.font = .preferredFont(forTextStyle: .body)
+ label.font = .mullvadSmall
label.textColor = .white
label.adjustsFontForContentSizeCategory = true
label.lineBreakMode = .byWordWrapping
@@ -60,7 +60,7 @@ final class WelcomeContentView: UIView, Sendable {
label.adjustsFontForContentSizeCategory = true
label.lineBreakMode = .byWordWrapping
label.numberOfLines = .zero
- label.font = .preferredFont(forTextStyle: .title2, weight: .bold)
+ label.font = .mullvadMedium
label.textColor = .white
return label
}()
@@ -68,6 +68,7 @@ final class WelcomeContentView: UIView, Sendable {
private let copyButton: UIButton = {
let button = UIButton(type: .system)
button.setAccessibilityIdentifier(.copyButton)
+ button.adjustsImageSizeForAccessibilityContentSizeCategory = true
button.tintColor = .white
button.setContentHuggingPriority(.defaultHigh, for: .horizontal)
return button
@@ -77,7 +78,7 @@ final class WelcomeContentView: UIView, Sendable {
let label = UILabel()
label.adjustsFontForContentSizeCategory = true
label.translatesAutoresizingMaskIntoConstraints = false
- label.font = .preferredFont(forTextStyle: .body)
+ label.font = .mullvadSmall
label.textColor = .white
label.setContentHuggingPriority(.defaultLow, for: .horizontal)
label.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
@@ -87,6 +88,7 @@ final class WelcomeContentView: UIView, Sendable {
private let infoButton: UIButton = {
let button = IncreasedHitButton(type: .system)
button.setAccessibilityIdentifier(.infoButton)
+ button.adjustsImageSizeForAccessibilityContentSizeCategory = true
button.tintColor = .white
button.translatesAutoresizingMaskIntoConstraints = false
button.setImage(UIImage.Buttons.info, for: .normal)
@@ -97,7 +99,7 @@ final class WelcomeContentView: UIView, Sendable {
private let descriptionLabel: UILabel = {
let label = UILabel()
- label.font = .preferredFont(forTextStyle: .body)
+ label.font = .mullvadSmall
label.adjustsFontForContentSizeCategory = true
label.textColor = .white
label.numberOfLines = .zero
diff --git a/ios/MullvadVPN/View controllers/DeviceList/DeviceManagementContentView.swift b/ios/MullvadVPN/View controllers/DeviceList/DeviceManagementContentView.swift
new file mode 100644
index 0000000000..7e98cd8f9e
--- /dev/null
+++ b/ios/MullvadVPN/View controllers/DeviceList/DeviceManagementContentView.swift
@@ -0,0 +1,321 @@
+//
+// DeviceManagementContentView.swift
+// MullvadVPN
+//
+// Created by pronebird on 19/07/2022.
+// Copyright © 2025 Mullvad VPN AB. All rights reserved.
+//
+
+import UIKit
+
+class DeviceManagementContentView: UIView {
+ private let scrollView: UIScrollView = {
+ let scrollView = UIScrollView()
+ scrollView.translatesAutoresizingMaskIntoConstraints = false
+ return scrollView
+ }()
+
+ let scrollContentView: UIView = {
+ let view = UIView()
+ view.directionalLayoutMargins = UIMetrics.contentLayoutMargins
+ view.translatesAutoresizingMaskIntoConstraints = false
+ return view
+ }()
+
+ let statusImageView: StatusImageView = {
+ let imageView = StatusImageView(style: .failure)
+ imageView.translatesAutoresizingMaskIntoConstraints = false
+ return imageView
+ }()
+
+ let titleLabel: UILabel = {
+ let textLabel = UILabel()
+ textLabel.font = .mullvadLarge
+ textLabel.adjustsFontForContentSizeCategory = true
+ textLabel.textColor = .white
+ textLabel.translatesAutoresizingMaskIntoConstraints = false
+ return textLabel
+ }()
+
+ let messageLabel: UILabel = {
+ let textLabel = UILabel()
+ textLabel.font = .mullvadSmall
+ textLabel.adjustsFontForContentSizeCategory = true
+ textLabel.textColor = .white
+ textLabel.translatesAutoresizingMaskIntoConstraints = false
+ textLabel.numberOfLines = 0
+ textLabel.lineBreakStrategy = []
+ return textLabel
+ }()
+
+ let deviceStackView: UIStackView = {
+ let stackView = UIStackView(arrangedSubviews: [])
+ stackView.translatesAutoresizingMaskIntoConstraints = false
+ stackView.axis = .vertical
+ stackView.spacing = 1
+ stackView.clipsToBounds = true
+ stackView.distribution = .fillEqually
+ return stackView
+ }()
+
+ let continueButton: AppButton = {
+ let button = AppButton(style: .success)
+ button.translatesAutoresizingMaskIntoConstraints = false
+ button.setTitle(
+ NSLocalizedString(
+ "CONTINUE_BUTTON",
+ tableName: "DeviceManagement",
+ value: "Continue with login",
+ comment: ""
+ ),
+ for: .normal
+ )
+ button.isEnabled = false
+ button.setAccessibilityIdentifier(.continueWithLoginButton)
+ return button
+ }()
+
+ let cancelButton: AppButton = {
+ let button = AppButton(style: .default)
+ button.translatesAutoresizingMaskIntoConstraints = false
+ button.setTitle(
+ NSLocalizedString(
+ "CANCEL_BUTTON",
+ tableName: "DeviceManagement",
+ value: "Cancel",
+ comment: ""
+ ),
+ for: .normal
+ )
+ return button
+ }()
+
+ private lazy var buttonStackView: UIStackView = {
+ let stackView = UIStackView(arrangedSubviews: [continueButton, cancelButton])
+ stackView.translatesAutoresizingMaskIntoConstraints = false
+ stackView.axis = .vertical
+ stackView.distribution = .fillEqually
+ stackView.spacing = UIMetrics.interButtonSpacing
+ return stackView
+ }()
+
+ var handleDeviceDeletion: (@Sendable (DeviceViewModel, @escaping @Sendable () -> Void) -> Void)?
+
+ private var currentDeviceModels = [DeviceViewModel]()
+
+ var canContinue = false {
+ didSet {
+ updateView()
+ }
+ }
+
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+
+ addViews()
+ constraintViews()
+ updateView()
+
+ setAccessibilityIdentifier(.deviceManagementView)
+ }
+
+ private func addViews() {
+ try? [scrollView, buttonStackView].forEach(addSubview)
+
+ scrollView.addSubview(scrollContentView)
+
+ try? [statusImageView, titleLabel, messageLabel, deviceStackView]
+ .forEach(scrollContentView.addSubview)
+ }
+
+ private func constraintViews() {
+ NSLayoutConstraint.activate([
+ scrollView.topAnchor.constraint(equalTo: topAnchor, constant: 16),
+ scrollView.leadingAnchor.constraint(equalTo: leadingAnchor),
+ scrollView.trailingAnchor.constraint(equalTo: trailingAnchor),
+
+ buttonStackView.topAnchor.constraint(
+ equalTo: scrollView.bottomAnchor,
+ constant: UIMetrics.contentLayoutMargins.top
+ ),
+ buttonStackView.leadingAnchor.constraint(
+ equalTo: leadingAnchor,
+ constant: UIMetrics.contentLayoutMargins.leading
+ ),
+ buttonStackView.trailingAnchor.constraint(
+ equalTo: trailingAnchor,
+ constant: -UIMetrics.contentLayoutMargins.trailing
+ ),
+ buttonStackView.bottomAnchor.constraint(
+ equalTo: safeAreaLayoutGuide.bottomAnchor,
+ constant: -UIMetrics.contentLayoutMargins.bottom
+ ),
+
+ scrollContentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
+ scrollContentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
+ scrollContentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
+ scrollContentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
+ scrollContentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor),
+
+ statusImageView.topAnchor
+ .constraint(equalTo: scrollContentView.topAnchor),
+ statusImageView.centerXAnchor.constraint(equalTo: scrollContentView.centerXAnchor),
+
+ titleLabel.topAnchor.constraint(equalTo: statusImageView.bottomAnchor, constant: 22),
+ titleLabel.leadingAnchor
+ .constraint(equalTo: scrollContentView.layoutMarginsGuide.leadingAnchor),
+ titleLabel.trailingAnchor
+ .constraint(equalTo: scrollContentView.layoutMarginsGuide.trailingAnchor),
+
+ messageLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 8),
+ messageLabel.leadingAnchor
+ .constraint(equalTo: scrollContentView.layoutMarginsGuide.leadingAnchor),
+ messageLabel.trailingAnchor
+ .constraint(equalTo: scrollContentView.layoutMarginsGuide.trailingAnchor),
+
+ deviceStackView.topAnchor.constraint(
+ equalTo: messageLabel.bottomAnchor,
+ constant: UIMetrics.TableView.sectionSpacing
+ ),
+ deviceStackView.leadingAnchor.constraint(equalTo: scrollContentView.leadingAnchor),
+ deviceStackView.trailingAnchor.constraint(equalTo: scrollContentView.trailingAnchor),
+ deviceStackView.bottomAnchor.constraint(equalTo: scrollContentView.bottomAnchor),
+ ])
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ func setDeviceViewModels(_ newModels: [DeviceViewModel], animated: Bool) {
+ let difference = newModels.difference(from: currentDeviceModels) { newModel, model in
+ newModel.id == model.id
+ }
+
+ currentDeviceModels = newModels
+
+ var viewsToAdd: [(view: UIView, offset: Int)] = []
+ var viewsToRemove: [UIView] = []
+
+ difference.forEach { change in
+ switch change {
+ case let .insert(offset, model, _):
+ viewsToAdd.append((createDeviceRowView(from: model), offset))
+ case let .remove(offset, _, _):
+ viewsToRemove.append(deviceStackView.arrangedSubviews[offset])
+ }
+ }
+
+ viewsToAdd.forEach { item in
+ deviceStackView.insertArrangedSubview(item.view, at: item.offset)
+ }
+
+ // Layout inserted subviews before running animations to achieve a folding effect.
+ if animated {
+ UIView.performWithoutAnimation {
+ deviceStackView.layoutIfNeeded()
+ }
+ }
+
+ if animated {
+ UIView.animate(
+ withDuration: 0.25,
+ delay: 0,
+ options: [.curveEaseInOut],
+ animations: { [weak self] in
+ self?.showHideViews(viewsToAdd: viewsToAdd, viewsToRemove: viewsToRemove)
+ self?.deviceStackView.layoutIfNeeded()
+ },
+ completion: { [weak self] _ in
+ self?.removeViews(viewsToRemove: viewsToRemove)
+ }
+ )
+ } else {
+ showHideViews(viewsToAdd: viewsToAdd, viewsToRemove: viewsToRemove)
+ removeViews(viewsToRemove: viewsToRemove)
+ }
+ }
+
+ private func showHideViews(viewsToAdd: [(view: UIView, offset: Int)], viewsToRemove: [UIView]) {
+ viewsToRemove.forEach { view in
+ view.alpha = 0
+ view.isHidden = true
+ }
+
+ viewsToAdd.forEach { item in
+ item.view.alpha = 1
+ item.view.isHidden = false
+ }
+ }
+
+ private func removeViews(viewsToRemove: [UIView]) {
+ viewsToRemove.forEach { view in
+ view.removeFromSuperview()
+ }
+ }
+
+ private func createDeviceRowView(from model: DeviceViewModel) -> DeviceRowView {
+ let view = DeviceRowView(viewModel: model)
+
+ view.isHidden = true
+ view.alpha = 0
+
+ view.deleteHandler = { [weak self] _ in
+ view.showsActivityIndicator = true
+
+ self?.handleDeviceDeletion?(view.viewModel) {
+ Task { @MainActor in
+ view.showsActivityIndicator = false
+ }
+ }
+ }
+
+ return view
+ }
+
+ private func updateView() {
+ titleLabel.text = titleText
+ messageLabel.text = messageText
+ continueButton.isEnabled = canContinue
+ statusImageView.style = canContinue ? .success : .failure
+ }
+
+ private var titleText: String {
+ if canContinue {
+ return NSLocalizedString(
+ "CONTINUE_LOGIN_TITLE",
+ tableName: "DeviceManagement",
+ value: "Super!",
+ comment: ""
+ )
+ } else {
+ return NSLocalizedString(
+ "LOGOUT_DEVICES_TITLE",
+ tableName: "DeviceManagement",
+ value: "Too many devices",
+ comment: ""
+ )
+ }
+ }
+
+ private var messageText: String {
+ if canContinue {
+ return NSLocalizedString(
+ "CONTINUE_LOGIN_MESSAGE",
+ tableName: "DeviceManagement",
+ value: "You can now continue logging in on this device.",
+ comment: ""
+ )
+ } else {
+ return NSLocalizedString(
+ "LOGOUT_DEVICES_MESSAGE",
+ tableName: "DeviceManagement",
+ value: """
+ Please log out of at least one by removing it from the list below. You can find \
+ the corresponding device name under the device’s Account settings.
+ """,
+ comment: ""
+ )
+ }
+ }
+}
diff --git a/ios/MullvadVPN/View controllers/DeviceList/DeviceRowView.swift b/ios/MullvadVPN/View controllers/DeviceList/DeviceRowView.swift
new file mode 100644
index 0000000000..0e3fcea273
--- /dev/null
+++ b/ios/MullvadVPN/View controllers/DeviceList/DeviceRowView.swift
@@ -0,0 +1,137 @@
+//
+// DeviceRowView.swift
+// MullvadVPN
+//
+// Created by pronebird on 26/07/2022.
+// Copyright © 2025 Mullvad VPN AB. All rights reserved.
+//
+
+import UIKit
+
+class DeviceRowView: UIView {
+ let viewModel: DeviceViewModel
+ var deleteHandler: ((DeviceRowView) -> Void)?
+
+ let textLabel: UILabel = {
+ let textLabel = UILabel()
+ textLabel.translatesAutoresizingMaskIntoConstraints = false
+ textLabel.font = .mullvadSmallSemiBold
+ textLabel.adjustsFontForContentSizeCategory = true
+ textLabel.textColor = .white
+ return textLabel
+ }()
+
+ let activityIndicator: SpinnerActivityIndicatorView = {
+ let activityIndicator = SpinnerActivityIndicatorView(style: .custom)
+ activityIndicator.translatesAutoresizingMaskIntoConstraints = false
+ return activityIndicator
+ }()
+
+ let creationDateLabel: UILabel = {
+ let creationDateLabel = UILabel()
+ creationDateLabel.translatesAutoresizingMaskIntoConstraints = false
+ creationDateLabel.font = .mullvadMiniSemiBold
+ creationDateLabel.adjustsFontForContentSizeCategory = true
+ creationDateLabel.textColor = .white.withAlphaComponent(0.6)
+ return creationDateLabel
+ }()
+
+ let removeButton: UIButton = {
+ let image = UIImage.Buttons.close
+ .withTintColor(
+ .white.withAlphaComponent(0.4),
+ renderingMode: .alwaysOriginal
+ )
+
+ let button = IncreasedHitButton(type: .custom)
+ button.translatesAutoresizingMaskIntoConstraints = false
+ button.setImage(image, for: .normal)
+ button.accessibilityLabel = NSLocalizedString(
+ "REMOVE_DEVICE_ACCESSIBILITY_LABEL",
+ tableName: "DeviceManagement",
+ value: "Remove device",
+ comment: ""
+ )
+ return button
+ }()
+
+ var showsActivityIndicator = false {
+ didSet {
+ removeButton.isHidden = showsActivityIndicator
+
+ if showsActivityIndicator {
+ activityIndicator.startAnimating()
+ } else {
+ activityIndicator.stopAnimating()
+ }
+ }
+ }
+
+ init(viewModel: DeviceViewModel) {
+ self.viewModel = viewModel
+
+ super.init(frame: .zero)
+
+ setAccessibilityIdentifier(.deviceCell)
+ backgroundColor = .primaryColor
+ directionalLayoutMargins = UIMetrics.TableView.rowViewLayoutMargins
+
+ for subview in [textLabel, removeButton, activityIndicator, creationDateLabel] {
+ addSubview(subview)
+ }
+
+ textLabel.text = viewModel.name
+ creationDateLabel.text = .init(
+ format:
+ NSLocalizedString(
+ "CREATED_DEVICE_LABEL",
+ tableName: "DeviceManagement",
+ value: "Created: %@",
+ comment: ""
+ ),
+ viewModel.creationDate
+ )
+
+ removeButton.addTarget(self, action: #selector(handleButtonTap(_:)), for: .touchUpInside)
+ removeButton.setAccessibilityIdentifier(.deviceCellRemoveButton)
+
+ NSLayoutConstraint.activate([
+ textLabel.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor),
+ textLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
+
+ creationDateLabel.leadingAnchor.constraint(equalTo: textLabel.leadingAnchor),
+ creationDateLabel.topAnchor.constraint(equalTo: textLabel.bottomAnchor, constant: 4.0),
+ creationDateLabel.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
+ .withPriority(.defaultLow),
+ creationDateLabel.trailingAnchor.constraint(equalTo: textLabel.trailingAnchor),
+
+ removeButton.centerYAnchor.constraint(equalTo: layoutMarginsGuide.centerYAnchor),
+ removeButton.leadingAnchor.constraint(
+ greaterThanOrEqualTo: textLabel.trailingAnchor,
+ constant: 8
+ ),
+ removeButton.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
+
+ activityIndicator.centerXAnchor.constraint(equalTo: removeButton.centerXAnchor),
+ activityIndicator.centerYAnchor.constraint(equalTo: removeButton.centerYAnchor),
+
+ // Bump dimensions by 6pt to account for transparent pixels around spinner image.
+ activityIndicator.widthAnchor.constraint(
+ equalTo: removeButton.widthAnchor,
+ constant: 6
+ ),
+ activityIndicator.heightAnchor.constraint(
+ equalTo: removeButton.heightAnchor,
+ constant: 6
+ ),
+ ])
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ @objc private func handleButtonTap(_ sender: Any?) {
+ deleteHandler?(self)
+ }
+}
diff --git a/ios/MullvadVPN/View controllers/Login/AccountInputGroupView.swift b/ios/MullvadVPN/View controllers/Login/AccountInputGroupView.swift
index d3a2cc142d..13c6a8d684 100644
--- a/ios/MullvadVPN/View controllers/Login/AccountInputGroupView.swift
+++ b/ios/MullvadVPN/View controllers/Login/AccountInputGroupView.swift
@@ -51,8 +51,9 @@ final class AccountInputGroupView: UIView {
private let privateTextField: AccountTextField = {
let textField = AccountTextField()
- textField.font = accountNumberFont()
+ textField.font = .mullvadMedium
textField.translatesAutoresizingMaskIntoConstraints = false
+ textField.adjustsFontForContentSizeCategory = true
textField.placeholder = "0000 0000 0000 0000"
textField.placeholderTextColor = .lightGray
textField.textContentType = .username
@@ -107,7 +108,7 @@ final class AccountInputGroupView: UIView {
button.configuration?
.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { attributeContainer in
var updatedAttributeContainer = attributeContainer
- updatedAttributeContainer.font = AccountInputGroupView.accountNumberFont()
+ updatedAttributeContainer.font = .mullvadMedium
updatedAttributeContainer.foregroundColor = .AccountTextField.NormalState.textColor
return updatedAttributeContainer
}
@@ -375,10 +376,6 @@ final class AccountInputGroupView: UIView {
// MARK: - Private
- private static func accountNumberFont() -> UIFont {
- UIFont.monospacedSystemFont(ofSize: 20, weight: .regular)
- }
-
private func addTextFieldNotificationObservers() {
let notificationCenter = NotificationCenter.default
diff --git a/ios/MullvadVPN/View controllers/Login/LoginContentView.swift b/ios/MullvadVPN/View controllers/Login/LoginContentView.swift
index 542571fe69..23e02d6a41 100644
--- a/ios/MullvadVPN/View controllers/Login/LoginContentView.swift
+++ b/ios/MullvadVPN/View controllers/Login/LoginContentView.swift
@@ -13,17 +13,19 @@ class LoginContentView: UIView {
let titleLabel: UILabel = {
let textLabel = UILabel()
- textLabel.font = UIFont.systemFont(ofSize: 32)
+ textLabel.font = .mullvadBig
textLabel.textColor = .white
textLabel.translatesAutoresizingMaskIntoConstraints = false
+ textLabel.adjustsFontForContentSizeCategory = true
return textLabel
}()
let messageLabel: UILabel = {
let textLabel = UILabel()
- textLabel.font = UIFont.systemFont(ofSize: 17)
+ textLabel.font = .mullvadTinySemiBold
textLabel.textColor = UIColor.white.withAlphaComponent(0.6)
textLabel.translatesAutoresizingMaskIntoConstraints = false
+ textLabel.adjustsFontForContentSizeCategory = true
textLabel.numberOfLines = 0
return textLabel
}()
@@ -71,9 +73,11 @@ class LoginContentView: UIView {
let footerLabel: UILabel = {
let textLabel = UILabel()
- textLabel.font = UIFont.systemFont(ofSize: 17)
+ textLabel.font = .mullvadSmall
textLabel.textColor = UIColor.white.withAlphaComponent(0.6)
textLabel.translatesAutoresizingMaskIntoConstraints = false
+ textLabel.adjustsFontForContentSizeCategory = true
+ textLabel.numberOfLines = 0
textLabel.text = NSLocalizedString(
"CREATE_BUTTON_HEADER_LABEL",
tableName: "Login",
diff --git a/ios/MullvadVPN/View controllers/OutOfTime/OutOfTimeContentView.swift b/ios/MullvadVPN/View controllers/OutOfTime/OutOfTimeContentView.swift
index 11cb3bcbbf..33d4f8d10b 100644
--- a/ios/MullvadVPN/View controllers/OutOfTime/OutOfTimeContentView.swift
+++ b/ios/MullvadVPN/View controllers/OutOfTime/OutOfTimeContentView.swift
@@ -24,7 +24,8 @@ class OutOfTimeContentView: UIView {
value: "Out of time",
comment: ""
)
- label.font = UIFont.systemFont(ofSize: 32)
+ label.font = .mullvadLarge
+ label.adjustsFontForContentSizeCategory = true
label.textColor = .white
return label
}()
@@ -33,6 +34,7 @@ class OutOfTimeContentView: UIView {
let label = UILabel()
label.textColor = .white
label.numberOfLines = 0
+ label.adjustsFontForContentSizeCategory = true
return label
}()
@@ -151,7 +153,7 @@ class OutOfTimeContentView: UIView {
func setBodyLabelText(_ text: String) {
bodyLabel.attributedText = NSAttributedString(
markdownString: text,
- options: MarkdownStylingOptions(font: .preferredFont(forTextStyle: .body))
+ options: MarkdownStylingOptions(font: .mullvadSmall)
)
}
}
diff --git a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportReviewViewController.swift b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportReviewViewController.swift
index 01d7afb09c..a41bdd2187 100644
--- a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportReviewViewController.swift
+++ b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportReviewViewController.swift
@@ -60,10 +60,8 @@ class ProblemReportReviewViewController: UIViewController {
textView.setAccessibilityIdentifier(.problemReportAppLogsTextView)
textView.translatesAutoresizingMaskIntoConstraints = false
textView.isEditable = false
- textView.font = UIFont.monospacedSystemFont(
- ofSize: UIFont.systemFontSize,
- weight: .regular
- )
+ textView.font = .mullvadSmall
+ textView.adjustsFontForContentSizeCategory = true
textView.backgroundColor = .systemBackground
view.addConstrainedSubviews([textView]) {
diff --git a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportSubmissionOverlayView.swift b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportSubmissionOverlayView.swift
index 005a81bd64..2c341f0557 100644
--- a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportSubmissionOverlayView.swift
+++ b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportSubmissionOverlayView.swift
@@ -156,7 +156,8 @@ class ProblemReportSubmissionOverlayView: UIView {
let titleLabel: UILabel = {
let textLabel = UILabel()
- textLabel.font = UIFont.systemFont(ofSize: 32)
+ textLabel.font = .mullvadLarge
+ textLabel.adjustsFontForContentSizeCategory = true
textLabel.textColor = .white
textLabel.numberOfLines = 0
return textLabel
@@ -300,7 +301,8 @@ class ProblemReportSubmissionOverlayView: UIView {
bodyLabelContainer.subviews.forEach { $0.removeFromSuperview() }
state.body?.forEach { attributedString in
let textLabel = UILabel()
- textLabel.font = UIFont.systemFont(ofSize: 17)
+ textLabel.font = .mullvadSmall
+ textLabel.adjustsFontForContentSizeCategory = true
textLabel.textColor = .white.withAlphaComponent(0.6)
textLabel.numberOfLines = 0
textLabel.attributedText = attributedString
diff --git a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportViewController+ViewManagement.swift b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportViewController+ViewManagement.swift
index c5370188eb..d5434412b0 100644
--- a/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportViewController+ViewManagement.swift
+++ b/ios/MullvadVPN/View controllers/ProblemReport/ProblemReportViewController+ViewManagement.swift
@@ -28,6 +28,8 @@ extension ProblemReportViewController {
func makeSubheaderLabel() -> UILabel {
let textLabel = UILabel()
textLabel.translatesAutoresizingMaskIntoConstraints = false
+ textLabel.font = .mullvadTinySemiBold
+ textLabel.adjustsFontForContentSizeCategory = true
textLabel.numberOfLines = 0
textLabel.textColor = .white
textLabel.text = ProblemReportViewModel.subheadLabelText
@@ -47,7 +49,8 @@ extension ProblemReportViewController {
textField.borderStyle = .none
textField.backgroundColor = .white
textField.inputAccessoryView = emailAccessoryToolbar
- textField.font = UIFont.systemFont(ofSize: 17)
+ textField.font = .mullvadSmall
+ textField.adjustsFontForContentSizeCategory = true
textField.placeholder = ProblemReportViewModel.emailPlaceholderText
return textField
}
@@ -57,7 +60,8 @@ extension ProblemReportViewController {
textView.translatesAutoresizingMaskIntoConstraints = false
textView.backgroundColor = .white
textView.inputAccessoryView = messageAccessoryToolbar
- textView.font = UIFont.systemFont(ofSize: 17)
+ textView.font = .mullvadSmall
+ textView.adjustsFontForContentSizeCategory = true
textView.placeholder = ProblemReportViewModel.messageTextViewPlaceholder
textView.contentInsetAdjustmentBehavior = .never
diff --git a/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherContentView.swift b/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherContentView.swift
index 1399276784..16dceaf257 100644
--- a/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherContentView.swift
+++ b/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherContentView.swift
@@ -34,7 +34,7 @@ final class RedeemVoucherContentView: UIView {
private let title: UILabel = {
let label = UILabel()
- label.font = .preferredFont(forTextStyle: .title1, weight: .bold).withSize(32)
+ label.font = .mullvadLarge
label.text = NSLocalizedString(
"REDEEM_VOUCHER_TITLE",
tableName: "RedeemVoucher",
@@ -43,12 +43,13 @@ final class RedeemVoucherContentView: UIView {
)
label.textColor = .white
label.numberOfLines = 0
+ label.adjustsFontForContentSizeCategory = true
return label
}()
private let enterVoucherLabel: UILabel = {
let label = UILabel()
- label.font = .preferredFont(forTextStyle: .body, weight: .semibold).withSize(15)
+ label.font = .mullvadTinySemiBold
label.text = NSLocalizedString(
"REDEEM_VOUCHER_INSTRUCTION",
@@ -58,12 +59,14 @@ final class RedeemVoucherContentView: UIView {
)
label.textColor = .white
label.numberOfLines = 0
+ label.adjustsFontForContentSizeCategory = true
return label
}()
private let textField: VoucherTextField = {
let textField = VoucherTextField()
- textField.font = UIFont.monospacedSystemFont(ofSize: 15, weight: .regular)
+ textField.font = UIFontMetrics(forTextStyle: .subheadline)
+ .scaledFont(for: .monospacedSystemFont(ofSize: 15, weight: .regular))
textField.placeholder = Array(repeating: "XXXX", count: 4).joined(separator: "-")
textField.placeholderTextColor = .lightGray
textField.backgroundColor = .white
@@ -72,6 +75,7 @@ final class RedeemVoucherContentView: UIView {
textField.autocapitalizationType = .allCharacters
textField.returnKeyType = .done
textField.autocorrectionType = .no
+ textField.adjustsFontForContentSizeCategory = true
return textField
}()
@@ -85,8 +89,9 @@ final class RedeemVoucherContentView: UIView {
private let statusLabel: UILabel = {
let label = UILabel()
- label.font = .systemFont(ofSize: 13, weight: .semibold)
+ label.font = .mullvadMiniSemiBold
label.numberOfLines = 2
+ label.adjustsFontForContentSizeCategory = true
label.lineBreakMode = .byWordWrapping
label.textColor = .red
label.setContentHuggingPriority(.defaultLow, for: .horizontal)
diff --git a/ios/MullvadVPN/View controllers/RevokedDevice/RevokedDeviceViewController.swift b/ios/MullvadVPN/View controllers/RevokedDevice/RevokedDeviceViewController.swift
index 81160dd1cf..01fdc7900b 100644
--- a/ios/MullvadVPN/View controllers/RevokedDevice/RevokedDeviceViewController.swift
+++ b/ios/MullvadVPN/View controllers/RevokedDevice/RevokedDeviceViewController.swift
@@ -18,7 +18,8 @@ class RevokedDeviceViewController: UIViewController, RootContainment {
private lazy var titleLabel: UILabel = {
let titleLabel = UILabel()
titleLabel.translatesAutoresizingMaskIntoConstraints = false
- titleLabel.font = UIFont.systemFont(ofSize: 24, weight: .bold)
+ titleLabel.font = .mullvadLarge
+ titleLabel.adjustsFontForContentSizeCategory = true
titleLabel.numberOfLines = 0
titleLabel.textColor = .white
titleLabel.text = NSLocalizedString(
@@ -33,7 +34,8 @@ class RevokedDeviceViewController: UIViewController, RootContainment {
private lazy var bodyLabel: UILabel = {
let bodyLabel = UILabel()
bodyLabel.translatesAutoresizingMaskIntoConstraints = false
- bodyLabel.font = UIFont.systemFont(ofSize: 17, weight: .semibold)
+ bodyLabel.adjustsFontForContentSizeCategory = true
+ bodyLabel.font = .mullvadSmall
bodyLabel.numberOfLines = 0
bodyLabel.textColor = .white
bodyLabel.text = NSLocalizedString(
@@ -48,7 +50,8 @@ class RevokedDeviceViewController: UIViewController, RootContainment {
private lazy var footerLabel: UILabel = {
let bodyLabel = UILabel()
bodyLabel.translatesAutoresizingMaskIntoConstraints = false
- bodyLabel.font = UIFont.systemFont(ofSize: 17, weight: .semibold)
+ bodyLabel.font = .mullvadSmall
+ bodyLabel.adjustsFontForContentSizeCategory = true
bodyLabel.numberOfLines = 0
bodyLabel.textColor = .white
bodyLabel.text = NSLocalizedString(
diff --git a/ios/MullvadVPN/View controllers/SelectLocation/LocationCell.swift b/ios/MullvadVPN/View controllers/SelectLocation/LocationCell.swift
index ba1958998c..a8e1d03cb9 100644
--- a/ios/MullvadVPN/View controllers/SelectLocation/LocationCell.swift
+++ b/ios/MullvadVPN/View controllers/SelectLocation/LocationCell.swift
@@ -18,7 +18,8 @@ class LocationCell: UITableViewCell {
private let locationLabel: UILabel = {
let label = UILabel()
- label.font = UIFont.systemFont(ofSize: 16)
+ label.font = .mullvadSmall
+ label.adjustsFontForContentSizeCategory = true
label.textColor = .white
label.lineBreakMode = .byTruncatingTail
label.numberOfLines = 1
@@ -34,6 +35,7 @@ class LocationCell: UITableViewCell {
private let tickImageView: UIImageView = {
let imageView = UIImageView(image: UIImage.tick)
+ imageView.adjustsImageSizeForAccessibilityContentSizeCategory = true
imageView.tintColor = .white
return imageView
}()
@@ -54,6 +56,7 @@ class LocationCell: UITableViewCell {
private let collapseButton: UIButton = {
let button = UIButton(type: .custom)
button.isAccessibilityElement = false
+ button.adjustsImageSizeForAccessibilityContentSizeCategory = true
button.tintColor = .white
return button
}()
@@ -165,11 +168,8 @@ class LocationCell: UITableViewCell {
statusIndicator.centerXAnchor.constraint(equalTo: tickImageView.centerXAnchor)
statusIndicator.centerYAnchor.constraint(equalTo: tickImageView.centerYAnchor)
- checkboxButton.pinEdgesToSuperview(PinnableEdges([.top(0), .bottom(0)]))
+ checkboxButton.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
checkboxButton.trailingAnchor.constraint(equalTo: locationLabel.leadingAnchor, constant: 14)
- checkboxButton.widthAnchor.constraint(
- equalToConstant: UIMetrics.contentLayoutMargins.leading + UIMetrics.contentLayoutMargins.trailing + 24
- )
locationLabel.pinEdgesToSuperviewMargins(PinnableEdges([.top(0), .bottom(0)]))
locationLabel.leadingAnchor.constraint(
diff --git a/ios/MullvadVPN/View controllers/SelectLocation/LocationSectionHeaderFooterView.swift b/ios/MullvadVPN/View controllers/SelectLocation/LocationSectionHeaderFooterView.swift
index ec379ea7e6..dcce16c689 100644
--- a/ios/MullvadVPN/View controllers/SelectLocation/LocationSectionHeaderFooterView.swift
+++ b/ios/MullvadVPN/View controllers/SelectLocation/LocationSectionHeaderFooterView.swift
@@ -73,6 +73,7 @@ class LocationSectionHeaderFooterView: UIView, UIContentView {
nameLabel.textColor = configuration.style.textColor
nameLabel.text = configuration.name
nameLabel.font = configuration.style.font
+ nameLabel.adjustsFontForContentSizeCategory = true
nameLabel.textAlignment = configuration.style.textAlignment
actionButton.isHidden = isActionHidden
actionButton.accessibilityIdentifier = nil
diff --git a/ios/MullvadVPN/View controllers/Settings/SettingsCell.swift b/ios/MullvadVPN/View controllers/Settings/SettingsCell.swift
index 569e01be0d..b2cb09788f 100644
--- a/ios/MullvadVPN/View controllers/Settings/SettingsCell.swift
+++ b/ios/MullvadVPN/View controllers/Settings/SettingsCell.swift
@@ -50,6 +50,7 @@ class SettingsCell: UITableViewCell, CustomCellDisclosureHandling {
if let image {
disclosureImageView.image = image
+ disclosureImageView.adjustsImageSizeForAccessibilityContentSizeCategory = true
disclosureImageView.sizeToFit()
accessoryView = disclosureImageView
} else {
@@ -60,7 +61,8 @@ class SettingsCell: UITableViewCell, CustomCellDisclosureHandling {
let titleLabel: UILabel = {
let label = UILabel()
- label.font = UIFont.systemFont(ofSize: 17)
+ label.font = .mullvadSmallSemiBold
+ label.adjustsFontForContentSizeCategory = true
label.textColor = UIColor.Cell.titleTextColor
label.setContentHuggingPriority(.defaultHigh, for: .horizontal)
label.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
@@ -69,7 +71,8 @@ class SettingsCell: UITableViewCell, CustomCellDisclosureHandling {
let detailTitleLabel: UILabel = {
let label = UILabel()
- label.font = UIFont.systemFont(ofSize: 13)
+ label.font = .mullvadTiny
+ label.adjustsFontForContentSizeCategory = true
label.textColor = UIColor.Cell.detailTextColor
label.setContentHuggingPriority(.defaultLow, for: .horizontal)
label.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
@@ -84,6 +87,7 @@ class SettingsCell: UITableViewCell, CustomCellDisclosureHandling {
button.setAccessibilityIdentifier(.infoButton)
button.tintColor = .white
button.setImage(UIImage.Buttons.info, for: .normal)
+ button.adjustsImageSizeForAccessibilityContentSizeCategory = true
button.isHidden = true
return button
}()
diff --git a/ios/MullvadVPN/View controllers/Settings/SettingsDNSInfoCell.swift b/ios/MullvadVPN/View controllers/Settings/SettingsDNSInfoCell.swift
index 7294528dea..a8b85961f8 100644
--- a/ios/MullvadVPN/View controllers/Settings/SettingsDNSInfoCell.swift
+++ b/ios/MullvadVPN/View controllers/Settings/SettingsDNSInfoCell.swift
@@ -17,6 +17,7 @@ class SettingsDNSInfoCell: UITableViewCell {
backgroundColor = .secondaryColor
contentView.directionalLayoutMargins = UIMetrics.SettingsCell.layoutMargins
+ titleLabel.adjustsFontForContentSizeCategory = true
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.textColor = UIColor.Cell.titleTextColor
titleLabel.numberOfLines = 0
diff --git a/ios/MullvadVPN/View controllers/Settings/SettingsDNSTextCell.swift b/ios/MullvadVPN/View controllers/Settings/SettingsDNSTextCell.swift
index b335d686d7..3a4c1c3ae5 100644
--- a/ios/MullvadVPN/View controllers/Settings/SettingsDNSTextCell.swift
+++ b/ios/MullvadVPN/View controllers/Settings/SettingsDNSTextCell.swift
@@ -24,7 +24,8 @@ class SettingsDNSTextCell: SettingsCell, UITextFieldDelegate {
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
- textField.font = UIFont.systemFont(ofSize: 17)
+ textField.font = .mullvadSmall
+ textField.adjustsFontForContentSizeCategory = true
textField.backgroundColor = .clear
textField.textColor = UIColor.TextField.textColor
textField.textMargins = UIMetrics.SettingsCell.textFieldContentInsets
diff --git a/ios/MullvadVPN/View controllers/Settings/SettingsHeaderView.swift b/ios/MullvadVPN/View controllers/Settings/SettingsHeaderView.swift
index fe2a1e0a55..4ad7da0ee1 100644
--- a/ios/MullvadVPN/View controllers/Settings/SettingsHeaderView.swift
+++ b/ios/MullvadVPN/View controllers/Settings/SettingsHeaderView.swift
@@ -15,7 +15,8 @@ class SettingsHeaderView: UITableViewHeaderFooterView {
let titleLabel: UILabel = {
let titleLabel = UILabel()
titleLabel.translatesAutoresizingMaskIntoConstraints = false
- titleLabel.font = .systemFont(ofSize: 17)
+ titleLabel.font = .mullvadSmallSemiBold
+ titleLabel.adjustsFontForContentSizeCategory = true
titleLabel.textColor = UIColor.Cell.titleTextColor
titleLabel.numberOfLines = 0
return titleLabel
@@ -24,6 +25,7 @@ class SettingsHeaderView: UITableViewHeaderFooterView {
let infoButton: UIButton = {
let button = UIButton(type: .custom)
button.setAccessibilityIdentifier(.infoButton)
+ button.adjustsImageSizeForAccessibilityContentSizeCategory = true
button.tintColor = .white
button.setImage(UIImage.Buttons.info, for: .normal)
return button
@@ -31,6 +33,7 @@ class SettingsHeaderView: UITableViewHeaderFooterView {
let collapseButton: UIButton = {
let button = UIButton(type: .custom)
+ button.adjustsImageSizeForAccessibilityContentSizeCategory = true
button.setAccessibilityIdentifier(.expandButton)
button.tintColor = .white
return button
diff --git a/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSCellFactory.swift b/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSCellFactory.swift
index c83b9cae05..8150e2ef8a 100644
--- a/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSCellFactory.swift
+++ b/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSCellFactory.swift
@@ -219,7 +219,7 @@ final class CustomDNSCellFactory: @preconcurrency CellFactoryProtocol {
cell.titleLabel.attributedText = viewModel.customDNSPrecondition.attributedLocalizedDescription(
isEditing: isEditing,
- preferredFont: .systemFont(ofSize: 14)
+ preferredFont: .mullvadSmallSemiBold
)
}
}
diff --git a/ios/MullvadVPN/Views/AppButton.swift b/ios/MullvadVPN/Views/AppButton.swift
index 73ea4cdc4f..b1a4957de2 100644
--- a/ios/MullvadVPN/Views/AppButton.swift
+++ b/ios/MullvadVPN/Views/AppButton.swift
@@ -115,7 +115,7 @@ class AppButton: CustomButton {
config.titleTextAttributesTransformer =
UIConfigurationTextAttributesTransformer { [weak self] attributeContainer in
var updatedAttributeContainer = attributeContainer
- updatedAttributeContainer.font = UIFont.systemFont(ofSize: 18, weight: .semibold)
+ updatedAttributeContainer.font = .mullvadSmallSemiBold
updatedAttributeContainer.foregroundColor = self?.state.customButtonTitleColor
return updatedAttributeContainer
}
diff --git a/ios/MullvadVPN/Views/CheckboxView.swift b/ios/MullvadVPN/Views/CheckboxView.swift
index 5152c98fc5..e4f3667865 100644
--- a/ios/MullvadVPN/Views/CheckboxView.swift
+++ b/ios/MullvadVPN/Views/CheckboxView.swift
@@ -30,6 +30,8 @@ class CheckboxView: UIView {
checkboxSelectedView.pinEdgesToSuperview()
checkboxUnselectedView.pinEdgesToSuperview()
}
+ checkboxSelectedView.adjustsImageSizeForAccessibilityContentSizeCategory = true
+ checkboxUnselectedView.adjustsImageSizeForAccessibilityContentSizeCategory = true
}
required init?(coder aDecoder: NSCoder) {
diff --git a/ios/MullvadVPN/Views/CustomTextView.swift b/ios/MullvadVPN/Views/CustomTextView.swift
index bc6df60504..61fddcbee4 100644
--- a/ios/MullvadVPN/Views/CustomTextView.swift
+++ b/ios/MullvadVPN/Views/CustomTextView.swift
@@ -41,7 +41,7 @@ class CustomTextView: UITextView {
override var font: UIFont? {
didSet {
- placeholderTextLabel.font = font ?? UIFont.preferredFont(forTextStyle: .body)
+ placeholderTextLabel.font = font ?? .mullvadSmall
}
}
@@ -94,6 +94,7 @@ class CustomTextView: UITextView {
placeholderTextLabel.textColor = UIColor.TextField.placeholderTextColor
placeholderTextLabel.highlightedTextColor = UIColor.TextField.placeholderTextColor
placeholderTextLabel.translatesAutoresizingMaskIntoConstraints = false
+ placeholderTextLabel.adjustsFontForContentSizeCategory = true
placeholderTextLabel.numberOfLines = 0
addSubview(placeholderTextLabel)
diff --git a/ios/MullvadVPN/Views/InfoHeaderView.swift b/ios/MullvadVPN/Views/InfoHeaderView.swift
index 48db0465bb..403ba7bb27 100644
--- a/ios/MullvadVPN/Views/InfoHeaderView.swift
+++ b/ios/MullvadVPN/Views/InfoHeaderView.swift
@@ -24,6 +24,7 @@ class InfoHeaderView: UIView, UITextViewDelegate {
infoLabel.backgroundColor = .clear
infoLabel.attributedText = makeAttributedString()
+ infoLabel.adjustsFontForContentSizeCategory = true
infoLabel.numberOfLines = 0
infoLabel.accessibilityTraits = .link
@@ -38,12 +39,12 @@ class InfoHeaderView: UIView, UITextViewDelegate {
}
private let defaultTextAttributes: [NSAttributedString.Key: Any] = [
- .font: UIFont.systemFont(ofSize: 13),
+ .font: UIFont.mullvadTiny,
.foregroundColor: UIColor.ContentHeading.textColor,
]
private let defaultLinkAttributes: [NSAttributedString.Key: Any] = [
- .font: UIFont.boldSystemFont(ofSize: 13),
+ .font: UIFont.mullvadTiny,
.foregroundColor: UIColor.ContentHeading.linkColor,
.attachment: "#",
]
diff --git a/ios/MullvadVPN/Views/StatusImageView.swift b/ios/MullvadVPN/Views/StatusImageView.swift
index e7a19fc15c..752156b0ea 100644
--- a/ios/MullvadVPN/Views/StatusImageView.swift
+++ b/ios/MullvadVPN/Views/StatusImageView.swift
@@ -45,10 +45,6 @@ class StatusImageView: UIImageView {
}
}
- override var intrinsicContentSize: CGSize {
- CGSize(width: 60, height: 60)
- }
-
override init(frame: CGRect) {
super.init(frame: frame)
image = style.image
@@ -58,6 +54,7 @@ class StatusImageView: UIImageView {
self.style = style
super.init(image: style.image)
image = style.image
+ self.adjustsImageSizeForAccessibilityContentSizeCategory = true
setAccessibilityIdentifier(.statusImageView)
}