summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ios/MullvadVPN/SelectLocationViewController.swift101
1 files changed, 74 insertions, 27 deletions
diff --git a/ios/MullvadVPN/SelectLocationViewController.swift b/ios/MullvadVPN/SelectLocationViewController.swift
index e308f0d26b..969335454f 100644
--- a/ios/MullvadVPN/SelectLocationViewController.swift
+++ b/ios/MullvadVPN/SelectLocationViewController.swift
@@ -20,22 +20,7 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
case header
}
- private lazy var tableView: UITableView = {
- let tableView = UITableView(frame: view.bounds, style: .plain)
- tableView.translatesAutoresizingMaskIntoConstraints = true
- tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
- tableView.backgroundColor = .clear
- tableView.separatorColor = .secondaryColor
- tableView.separatorInset = .zero
- tableView.estimatedRowHeight = 53
- tableView.estimatedSectionHeaderHeight = 109
- tableView.indicatorStyle = .white
-
- tableView.register(SelectLocationHeaderView.self, forHeaderFooterViewReuseIdentifier: ReuseIdentifiers.header.rawValue)
- tableView.register(SelectLocationCell.self, forCellReuseIdentifier: ReuseIdentifiers.cell.rawValue)
-
- return tableView
- }()
+ private var tableView: UITableView?
private let logger = Logger(label: "SelectLocationController")
private var dataSource: LocationDataSource?
@@ -44,6 +29,12 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
private var setScrollPositionOnViewDidLoad: UITableView.ScrollPosition = .none
private var isViewAppeared = false
+ private var showHeaderViewAtTheBottom = false {
+ didSet {
+ setTableHeaderFooterDimensions()
+ }
+ }
+
weak var delegate: SelectLocationViewControllerDelegate?
var scrollToSelectedRelayOnViewWillAppear = true
@@ -60,11 +51,27 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
+ let tableView = UITableView(frame: view.bounds, style: .plain)
+ tableView.translatesAutoresizingMaskIntoConstraints = true
+ tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ tableView.backgroundColor = .clear
+ tableView.separatorColor = .secondaryColor
+ tableView.separatorInset = .zero
+ tableView.estimatedRowHeight = 53
+ tableView.indicatorStyle = .white
+
+ tableView.register(SelectLocationHeaderView.self, forHeaderFooterViewReuseIdentifier: ReuseIdentifiers.header.rawValue)
+ tableView.register(SelectLocationCell.self, forCellReuseIdentifier: ReuseIdentifiers.cell.rawValue)
+
+ self.tableView = tableView
+
+ setTableHeaderFooterDimensions()
+
view.backgroundColor = .secondaryColor
view.addSubview(tableView)
dataSource = LocationDataSource(
- tableView: self.tableView,
+ tableView: tableView,
cellProvider: { [weak self] (tableView, indexPath, item) -> UITableViewCell? in
guard let self = self else { return nil }
@@ -104,8 +111,12 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
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 = self.presentingViewController == nil
+
if let indexPath = dataSource?.indexPathForSelectedRelay(), scrollToSelectedRelayOnViewWillAppear, !isViewAppeared {
- self.tableView.scrollToRow(at: indexPath, at: .middle, animated: false)
+ self.tableView?.scrollToRow(at: indexPath, at: .middle, animated: false)
}
}
@@ -114,7 +125,7 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
isViewAppeared = true
- tableView.flashScrollIndicators()
+ tableView?.flashScrollIndicators()
}
override func viewDidDisappear(_ animated: Bool) {
@@ -128,7 +139,7 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
coordinator.animate { (context) in
if let indexPath = self.dataSource?.indexPathForSelectedRelay() {
- self.tableView.scrollToRow(at: indexPath, at: .middle, animated: false)
+ self.tableView?.scrollToRow(at: indexPath, at: .middle, animated: false)
}
}
}
@@ -165,15 +176,27 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
assert(section == 0)
- let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: ReuseIdentifiers.header.rawValue) as! SelectLocationHeaderView
+ if showHeaderViewAtTheBottom {
+ return nil
+ } else {
+ let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: ReuseIdentifiers.header.rawValue) as! SelectLocationHeaderView
+ updateTopLayoutMargin(forHeaderView: view)
- // 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 as? CustomNavigationBar {
- view.topLayoutMarginAdjustmentForNavigationBarTitle = navigationBar.titleLabelBottomInset
+ return view
}
+ }
+
+ func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
+ assert(section == 0)
+
+ if showHeaderViewAtTheBottom {
+ let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: ReuseIdentifiers.header.rawValue) as! SelectLocationHeaderView
+ view.topLayoutMarginAdjustmentForNavigationBarTitle = 0
- return view
+ return view
+ } else {
+ return nil
+ }
}
// MARK: - Public
@@ -204,11 +227,35 @@ class SelectLocationViewController: UIViewController, UITableViewDelegate {
// MARK: - Collapsible cells
private func collapseCell(_ cell: SelectLocationCell) {
- guard let cellIndexPath = tableView.indexPath(for: cell),
+ guard let cellIndexPath = tableView?.indexPath(for: cell),
let dataSource = dataSource, let location = dataSource.relayLocation(for: cellIndexPath) else {
return
}
dataSource.toggleChildren(location, animated: true)
}
+
+ // MARK: - Private
+
+ private func updateTopLayoutMargin(forHeaderView view: SelectLocationHeaderView) {
+ // 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 as? CustomNavigationBar {
+ view.topLayoutMarginAdjustmentForNavigationBarTitle = navigationBar.titleLabelBottomInset
+ } else {
+ view.topLayoutMarginAdjustmentForNavigationBarTitle = 0
+ }
+ }
+
+ private func setTableHeaderFooterDimensions() {
+ let headerFooterHeight: CGFloat = 109
+
+ if showHeaderViewAtTheBottom {
+ self.tableView?.estimatedSectionHeaderHeight = 0
+ self.tableView?.estimatedSectionFooterHeight = headerFooterHeight
+ } else {
+ self.tableView?.estimatedSectionHeaderHeight = headerFooterHeight
+ self.tableView?.estimatedSectionFooterHeight = 0
+ }
+ }
}