summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj4
-rw-r--r--ios/MullvadVPN/Containers/Navigation/UINavigationBar+Appearance.swift35
-rw-r--r--ios/MullvadVPN/Coordinators/App/SelectLocationCoordinator.swift4
-rw-r--r--ios/MullvadVPN/UI appearance/UIColor+Palette.swift1
-rw-r--r--ios/MullvadVPN/View controllers/SelectLocation/SelectLocationHeaderView.swift54
-rw-r--r--ios/MullvadVPN/View controllers/SelectLocation/SelectLocationViewController.swift165
6 files changed, 58 insertions, 205 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index 595fa0907b..da36add3d1 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -112,7 +112,6 @@
584D26C6270C8741004EA533 /* SettingsDNSTextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584D26C5270C8741004EA533 /* SettingsDNSTextCell.swift */; };
584EBDBD2747C98F00A0C9FD /* NSAttributedString+Markdown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 584EBDBC2747C98F00A0C9FD /* NSAttributedString+Markdown.swift */; };
584F99202902CBDD001F858D /* libRelaySelector.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5898D29829017DAC00EB5EBA /* libRelaySelector.a */; };
- 5857F24324C8662600CF6F47 /* SelectLocationHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5857F24224C8662600CF6F47 /* SelectLocationHeaderView.swift */; };
5859A55329CD9B1300F66591 /* ChangeLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5859A55229CD9B1300F66591 /* ChangeLog.swift */; };
5859A55529CD9DD900F66591 /* changes.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5859A55429CD9DD800F66591 /* changes.txt */; };
585B4B8726D9098900555C4C /* TunnelStatusNotificationProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58A94AE326CFD945001CB97C /* TunnelStatusNotificationProvider.swift */; };
@@ -735,7 +734,6 @@
584D26C5270C8741004EA533 /* SettingsDNSTextCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsDNSTextCell.swift; sourceTree = "<group>"; };
584EBDBC2747C98F00A0C9FD /* NSAttributedString+Markdown.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+Markdown.swift"; sourceTree = "<group>"; };
58561C98239A5D1500BD6B5E /* IPv4Endpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPv4Endpoint.swift; sourceTree = "<group>"; };
- 5857F24224C8662600CF6F47 /* SelectLocationHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectLocationHeaderView.swift; sourceTree = "<group>"; };
5859A55229CD9B1300F66591 /* ChangeLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeLog.swift; sourceTree = "<group>"; };
5859A55429CD9DD800F66591 /* changes.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = changes.txt; sourceTree = "<group>"; };
585CA70E25F8C44600B47C62 /* UIMetrics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIMetrics.swift; sourceTree = "<group>"; };
@@ -1266,7 +1264,6 @@
58435AC129CB2A350099C71B /* LocationCellFactory.swift */,
583DA21325FA4B5C00318683 /* LocationDataSource.swift */,
5888AD82227B11080051EB06 /* SelectLocationCell.swift */,
- 5857F24224C8662600CF6F47 /* SelectLocationHeaderView.swift */,
5888AD86227B17950051EB06 /* SelectLocationViewController.swift */,
);
path = SelectLocation;
@@ -2726,7 +2723,6 @@
58E0A98827C8F46300FE6BDD /* Tunnel.swift in Sources */,
586891CD29D452E4002A8278 /* SafariCoordinator.swift in Sources */,
58ACF64F26567A7100ACE4B7 /* CustomSwitchContainer.swift in Sources */,
- 5857F24324C8662600CF6F47 /* SelectLocationHeaderView.swift in Sources */,
58EE2E3A272FF814003BFF93 /* SettingsDataSource.swift in Sources */,
58B26E1E2943514300D5980C /* InAppNotificationDescriptor.swift in Sources */,
58421032282E42B000F24E46 /* UpdateDeviceDataOperation.swift in Sources */,
diff --git a/ios/MullvadVPN/Containers/Navigation/UINavigationBar+Appearance.swift b/ios/MullvadVPN/Containers/Navigation/UINavigationBar+Appearance.swift
index f749f09e07..9a6d43da49 100644
--- a/ios/MullvadVPN/Containers/Navigation/UINavigationBar+Appearance.swift
+++ b/ios/MullvadVPN/Containers/Navigation/UINavigationBar+Appearance.swift
@@ -9,24 +9,6 @@
import UIKit
extension UINavigationBar {
- var titleLabelBottomInset: CGFloat {
- // Go two levels deep only
- let subviewsToExamine = subviews.flatMap { view -> [UIView] in
- return [view] + view.subviews
- }
-
- let titleLabel = subviewsToExamine.first { view -> Bool in
- return view is UILabel
- }
-
- if let titleLabel = titleLabel {
- let titleFrame = titleLabel.convert(titleLabel.bounds, to: self)
- return max(bounds.maxY - titleFrame.maxY, 0)
- } else {
- return 0
- }
- }
-
func configureCustomAppeareance() {
var margins = layoutMargins
margins.left = UIMetrics.contentLayoutMargins.left
@@ -34,14 +16,12 @@ extension UINavigationBar {
layoutMargins = margins
tintColor = UIColor.NavigationBar.titleColor
- backgroundColor = UIColor.NavigationBar.backgroundColor
- isTranslucent = false
- standardAppearance = makeNavigationBarAppearance()
- scrollEdgeAppearance = makeNavigationBarAppearance()
+ standardAppearance = makeNavigationBarAppearance(isTransparent: false)
+ scrollEdgeAppearance = makeNavigationBarAppearance(isTransparent: true)
}
- private func makeNavigationBarAppearance() -> UINavigationBarAppearance {
+ private func makeNavigationBarAppearance(isTransparent: Bool) -> UINavigationBarAppearance {
let backIndicatorImage = UIImage(named: "IconBack")?.withTintColor(
UIColor.NavigationBar.backButtonIndicatorColor,
renderingMode: .alwaysOriginal
@@ -57,7 +37,14 @@ extension UINavigationBar {
]
let navigationBarAppearance = UINavigationBarAppearance()
- navigationBarAppearance.configureWithTransparentBackground()
+
+ if isTransparent {
+ navigationBarAppearance.configureWithTransparentBackground()
+ } else {
+ navigationBarAppearance.configureWithDefaultBackground()
+ navigationBarAppearance.backgroundEffect = UIBlurEffect(style: .dark)
+ }
+
navigationBarAppearance.titleTextAttributes = titleTextAttributes
navigationBarAppearance.largeTitleTextAttributes = titleTextAttributes
diff --git a/ios/MullvadVPN/Coordinators/App/SelectLocationCoordinator.swift b/ios/MullvadVPN/Coordinators/App/SelectLocationCoordinator.swift
index 6571f01f70..ff7b4a7164 100644
--- a/ios/MullvadVPN/Coordinators/App/SelectLocationCoordinator.swift
+++ b/ios/MullvadVPN/Coordinators/App/SelectLocationCoordinator.swift
@@ -35,7 +35,7 @@ class SelectLocationCoordinator: Coordinator, Presentable, RelayCacheTrackerObse
func start() {
let controller = SelectLocationViewController()
- controller.didSelectRelay = { [weak self] _, relay in
+ controller.didSelectRelay = { [weak self] relay in
guard let self = self else { return }
let newConstraints = RelayConstraints(location: .only(relay))
@@ -47,7 +47,7 @@ class SelectLocationCoordinator: Coordinator, Presentable, RelayCacheTrackerObse
self.didFinish?(self, relay)
}
- controller.didFinish = { [weak self] _ in
+ controller.didFinish = { [weak self] in
guard let self = self else { return }
self.didFinish?(self, nil)
diff --git a/ios/MullvadVPN/UI appearance/UIColor+Palette.swift b/ios/MullvadVPN/UI appearance/UIColor+Palette.swift
index d7be5b728d..07522f6cf5 100644
--- a/ios/MullvadVPN/UI appearance/UIColor+Palette.swift
+++ b/ios/MullvadVPN/UI appearance/UIColor+Palette.swift
@@ -61,7 +61,6 @@ extension UIColor {
// Navigation bars
enum NavigationBar {
- static let backgroundColor = UIColor.secondaryColor
static let backButtonIndicatorColor = UIColor(white: 1.0, alpha: 0.4)
static let backButtonTitleColor = UIColor(white: 1.0, alpha: 0.6)
static let titleColor = UIColor.white
diff --git a/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationHeaderView.swift b/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationHeaderView.swift
deleted file mode 100644
index 9d39f73bad..0000000000
--- a/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationHeaderView.swift
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// SelectLocationHeaderView.swift
-// MullvadVPN
-//
-// Created by pronebird on 22/07/2020.
-// Copyright © 2020 Mullvad VPN AB. All rights reserved.
-//
-
-import UIKit
-
-class SelectLocationHeaderView: UIView {
- lazy var textContentLabel: UILabel = {
- let textLabel = UILabel()
- textLabel.translatesAutoresizingMaskIntoConstraints = false
- textLabel.font = UIFont.systemFont(ofSize: 17)
- textLabel.textColor = UIColor(white: 1, alpha: 0.6)
- textLabel.numberOfLines = 0
- textLabel.text = NSLocalizedString(
- "SUBHEAD_LABEL",
- tableName: "SelectLocation",
- value: "While connected, your real location is masked with a private and secure location in the selected region",
- comment: ""
- )
- return textLabel
- }()
-
- var topLayoutMarginAdjustmentForNavigationBarTitle: CGFloat = 0 {
- didSet {
- let value = UIMetrics.sectionSpacing - topLayoutMarginAdjustmentForNavigationBarTitle
- layoutMargins.top = max(value, 0)
- }
- }
-
- init() {
- super.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
-
- backgroundColor = .secondaryColor
- layoutMargins = UIMetrics.contentLayoutMargins
- insetsLayoutMarginsFromSafeArea = false
-
- addSubview(textContentLabel)
-
- NSLayoutConstraint.activate([
- textContentLabel.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor),
- textContentLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor),
- textContentLabel.trailingAnchor.constraint(equalTo: layoutMarginsGuide.trailingAnchor),
- textContentLabel.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor),
- ])
- }
-
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
-}
diff --git a/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationViewController.swift b/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationViewController.swift
index 777bb4ce80..e846213c03 100644
--- a/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationViewController.swift
+++ b/ios/MullvadVPN/View controllers/SelectLocation/SelectLocationViewController.swift
@@ -13,29 +13,18 @@ import UIKit
final class SelectLocationViewController: UIViewController, UITableViewDelegate {
private var tableView: UITableView?
-
- private let tableHeaderFooterView = SelectLocationHeaderView()
- private var tableHeaderFooterViewTopConstraints: [NSLayoutConstraint] = []
- private var tableHeaderFooterViewBottomConstraints: [NSLayoutConstraint] = []
-
private var dataSource: LocationDataSource?
- private var setCachedRelaysOnViewDidLoad: CachedRelays?
- private var setRelayLocationOnViewDidLoad: RelayLocation?
- private var setScrollPositionOnViewDidLoad: UITableView.ScrollPosition = .none
+ private var cachedRelays: CachedRelays?
+ private var relayLocation: RelayLocation?
+ private var scrollPosition: UITableView.ScrollPosition?
private var isViewAppeared = false
- private var showHeaderViewAtTheBottom = false {
- didSet {
- setTableHeaderFooterConstraints()
- }
- }
-
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
- var didSelectRelay: ((SelectLocationViewController, RelayLocation) -> Void)?
- var didFinish: ((SelectLocationViewController) -> Void)?
+ var didSelectRelay: ((RelayLocation) -> Void)?
+ var didFinish: (() -> Void)?
var scrollToSelectedRelayOnViewWillAppear = true
@@ -52,7 +41,6 @@ final class SelectLocationViewController: UIViewController, UITableViewDelegate
override func viewDidLoad() {
super.viewDidLoad()
- navigationItem.largeTitleDisplayMode = .never
navigationItem.title = NSLocalizedString(
"NAVIGATION_TITLE",
tableName: "SelectLocation",
@@ -65,73 +53,17 @@ final class SelectLocationViewController: UIViewController, UITableViewDelegate
action: #selector(handleDone)
)
- let tableView = UITableView(frame: view.bounds, style: .plain)
- tableView.translatesAutoresizingMaskIntoConstraints = false
- tableView.backgroundColor = .clear
- tableView.separatorColor = .secondaryColor
- tableView.separatorInset = .zero
- tableView.estimatedRowHeight = 53
- tableView.indicatorStyle = .white
-
- self.tableView = tableView
- dataSource = LocationDataSource(tableView: tableView)
- tableView.dataSource = dataSource
-
- dataSource?.didSelectRelayLocation = { [weak self] location in
- guard let self = self else { return }
-
- self.didSelectRelay?(self, location)
- }
-
- view.accessibilityElements = [tableHeaderFooterView, tableView]
- view.backgroundColor = .secondaryColor
- view.addSubview(tableView)
-
- tableHeaderFooterView.translatesAutoresizingMaskIntoConstraints = false
- view.addSubview(tableHeaderFooterView)
-
- tableHeaderFooterViewTopConstraints = [
- tableHeaderFooterView.topAnchor.constraint(equalTo: view.topAnchor),
- tableView.topAnchor.constraint(equalTo: tableHeaderFooterView.bottomAnchor),
- tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
- ]
- tableHeaderFooterViewBottomConstraints = [
- tableHeaderFooterView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
- tableView.topAnchor.constraint(equalTo: view.topAnchor),
- tableView.bottomAnchor.constraint(equalTo: tableHeaderFooterView.topAnchor),
- ]
-
- NSLayoutConstraint.activate([
- tableHeaderFooterView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
- tableHeaderFooterView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
- tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
- tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
- ])
- setTableHeaderFooterConstraints()
-
- if let setCachedRelaysOnViewDidLoad = setCachedRelaysOnViewDidLoad {
- dataSource?.setRelays(setCachedRelaysOnViewDidLoad.relays)
- }
-
- if let setRelayLocationOnViewDidLoad = setRelayLocationOnViewDidLoad {
- dataSource?.setSelectedRelayLocation(
- setRelayLocationOnViewDidLoad,
- animated: false
- )
- }
+ setupTableView()
+ setupDataSource()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
- // Show header view at the bottom when controller is presented inline and show header view
- // at the top of the view when controller is presented modally.
- showHeaderViewAtTheBottom = presentingViewController == nil
-
if let indexPath = dataSource?.indexPathForSelectedRelay(),
scrollToSelectedRelayOnViewWillAppear, !isViewAppeared
{
- tableView?.scrollToRow(at: indexPath, at: .middle, animated: false)
+ tableView?.scrollToRow(at: indexPath, at: scrollPosition ?? .middle, animated: false)
}
}
@@ -149,10 +81,7 @@ final class SelectLocationViewController: UIViewController, UITableViewDelegate
isViewAppeared = false
}
- override func viewWillTransition(
- to size: CGSize,
- with coordinator: UIViewControllerTransitionCoordinator
- ) {
+ override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate(alongsideTransition: nil) { context in
@@ -162,19 +91,11 @@ final class SelectLocationViewController: UIViewController, UITableViewDelegate
}
}
- override func viewDidLayoutSubviews() {
- super.viewDidLayoutSubviews()
-
- updateTableHeaderTopLayoutMargin()
- }
-
// MARK: - Public
func setCachedRelays(_ cachedRelays: CachedRelays) {
- guard isViewLoaded else {
- setCachedRelaysOnViewDidLoad = cachedRelays
- return
- }
+ self.cachedRelays = cachedRelays
+
dataSource?.setRelays(cachedRelays.relays)
}
@@ -183,47 +104,51 @@ final class SelectLocationViewController: UIViewController, UITableViewDelegate
animated: Bool,
scrollPosition: UITableView.ScrollPosition
) {
- guard isViewLoaded else {
- setRelayLocationOnViewDidLoad = relayLocation
- setScrollPositionOnViewDidLoad = scrollPosition
- return
- }
+ self.relayLocation = relayLocation
+ self.scrollPosition = scrollPosition
- dataSource?.setSelectedRelayLocation(
- relayLocation,
- animated: animated
- )
+ dataSource?.setSelectedRelayLocation(relayLocation, animated: animated)
}
// MARK: - Private
- private func updateTableHeaderTopLayoutMargin() {
- // When contained within the navigation controller, we want the distance between
- // the navigation title and the table header label to be exactly 24pt.
- if let navigationBar = navigationController?.navigationBar, !showHeaderViewAtTheBottom {
- tableHeaderFooterView.topLayoutMarginAdjustmentForNavigationBarTitle = navigationBar
- .titleLabelBottomInset
- } else {
- tableHeaderFooterView.topLayoutMarginAdjustmentForNavigationBarTitle = 0
+ private func setupTableView() {
+ let tableView = UITableView(frame: view.bounds, style: .plain)
+ tableView.backgroundColor = .clear
+ tableView.backgroundColor = .secondaryColor
+ tableView.separatorColor = .secondaryColor
+ tableView.separatorInset = .zero
+ tableView.estimatedRowHeight = 53
+ tableView.indicatorStyle = .white
+ tableView.delegate = self
+
+ view.backgroundColor = .secondaryColor
+
+ view.addConstrainedSubviews([tableView]) {
+ tableView.pinEdgesToSuperview()
}
+
+ self.tableView = tableView
}
- private func setTableHeaderFooterConstraints() {
- if showHeaderViewAtTheBottom {
- NSLayoutConstraint.deactivate(
- tableHeaderFooterViewTopConstraints
- )
- NSLayoutConstraint.activate(tableHeaderFooterViewBottomConstraints)
- } else {
- NSLayoutConstraint.deactivate(
- tableHeaderFooterViewBottomConstraints
- )
- NSLayoutConstraint.activate(tableHeaderFooterViewTopConstraints)
+ private func setupDataSource() {
+ guard let tableView = tableView else { return }
+
+ dataSource = LocationDataSource(tableView: tableView)
+ dataSource?.didSelectRelayLocation = { [weak self] location in
+ self?.didSelectRelay?(location)
+ }
+
+ if let cachedRelays = cachedRelays {
+ dataSource?.setRelays(cachedRelays.relays)
+ }
+
+ if let relayLocation = relayLocation {
+ dataSource?.setSelectedRelayLocation(relayLocation, animated: false)
}
- view.layoutIfNeeded()
}
@objc private func handleDone() {
- didFinish?(self)
+ didFinish?()
}
}