summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj8
-rw-r--r--ios/MullvadVPN/AppDelegate.swift2
-rw-r--r--ios/MullvadVPN/Base.lproj/Main.storyboard82
-rw-r--r--ios/MullvadVPN/HeaderBarView.swift40
-rw-r--r--ios/MullvadVPN/HeaderBarView.xib61
-rw-r--r--ios/MullvadVPN/RootContainerViewController.swift55
-rw-r--r--ios/MullvadVPN/ViewControllerIdentifier.swift1
7 files changed, 164 insertions, 85 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index 307a474a1b..98627ed500 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -168,6 +168,8 @@
58EC4E6C23915325003F5C5B /* Bundle+MullvadVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58EC4E6B23915325003F5C5B /* Bundle+MullvadVersion.swift */; };
58F19E35228C15BA00C7710B /* SpinnerActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F19E34228C15BA00C7710B /* SpinnerActivityIndicatorView.swift */; };
58F3C0962492617E003E76BE /* AsyncOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58E973DD24850EB600096F90 /* AsyncOperation.swift */; };
+ 58F3C0A2249CA1E0003E76BE /* HeaderBarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 58F3C0A1249CA1E0003E76BE /* HeaderBarView.xib */; };
+ 58F3C0A4249CB069003E76BE /* HeaderBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F3C0A3249CB069003E76BE /* HeaderBarView.swift */; };
58F840AF2464382C0044E708 /* KeychainItemRevision.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F840AE2464382C0044E708 /* KeychainItemRevision.swift */; };
58F840B02464382C0044E708 /* KeychainItemRevision.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F840AE2464382C0044E708 /* KeychainItemRevision.swift */; };
58F840B22464491D0044E708 /* ChainedError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58F840B12464491D0044E708 /* ChainedError.swift */; };
@@ -348,6 +350,8 @@
58EC4E6B23915325003F5C5B /* Bundle+MullvadVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+MullvadVersion.swift"; sourceTree = "<group>"; };
58ECD29123F178FD004298B6 /* Screenshots.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Screenshots.xcconfig; sourceTree = "<group>"; };
58F19E34228C15BA00C7710B /* SpinnerActivityIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpinnerActivityIndicatorView.swift; sourceTree = "<group>"; };
+ 58F3C0A1249CA1E0003E76BE /* HeaderBarView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HeaderBarView.xib; sourceTree = "<group>"; };
+ 58F3C0A3249CB069003E76BE /* HeaderBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeaderBarView.swift; sourceTree = "<group>"; };
58F840AE2464382C0044E708 /* KeychainItemRevision.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainItemRevision.swift; sourceTree = "<group>"; };
58F840B12464491D0044E708 /* ChainedError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChainedError.swift; sourceTree = "<group>"; };
58FAEDEB245059F000CB0F5B /* KeychainAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainAttributes.swift; sourceTree = "<group>"; };
@@ -498,6 +502,8 @@
58C6B35D22BBBFE3003C19AD /* Data+HexCoding.swift */,
58B9EB142489139B00095626 /* DisplayChainedError.swift */,
5873884C239E6D7E00E96C4E /* EmbeddedViewContainerView.swift */,
+ 58F3C0A3249CB069003E76BE /* HeaderBarView.swift */,
+ 58F3C0A1249CA1E0003E76BE /* HeaderBarView.xib */,
58FD5BF32428C67600112C88 /* InAppPurchaseButton.swift */,
58CE5E6F224146210008646E /* Info.plist */,
5840250022B1124600E4CFEC /* IpAddress+Codable.swift */,
@@ -775,6 +781,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 58F3C0A2249CA1E0003E76BE /* HeaderBarView.xib in Resources */,
58CE5E6E224146210008646E /* LaunchScreen.storyboard in Resources */,
58CE5E6B224146210008646E /* Assets.xcassets in Resources */,
58CE5E69224146200008646E /* Main.storyboard in Resources */,
@@ -922,6 +929,7 @@
582BB1AF229566420055B6EF /* SettingsCell.swift in Sources */,
5873884D239E6D7E00E96C4E /* EmbeddedViewContainerView.swift in Sources */,
582650862384116F00FA7A86 /* ReplaceNilWithError.swift in Sources */,
+ 58F3C0A4249CB069003E76BE /* HeaderBarView.swift in Sources */,
587A01FC23F1F0BE00B68763 /* SimulatorTunnelProviderHost.swift in Sources */,
5862805422428EF100F5A6E1 /* TranslucentButtonBlurView.swift in Sources */,
580EE20624B3222200F9D8A1 /* ExclusivityController.swift in Sources */,
diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift
index 907e731225..57ffac8c90 100644
--- a/ios/MullvadVPN/AppDelegate.swift
+++ b/ios/MullvadVPN/AppDelegate.swift
@@ -38,7 +38,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
fatalError("Failed to restore the account: \(error.localizedDescription)")
}
- let rootViewController = self.mainStoryboard.instantiateViewController(identifier: ViewControllerIdentifier.root.rawValue) as! RootContainerViewController
+ let rootViewController = RootContainerViewController()
let showMainController = { (_ animated: Bool) in
self.showMainController(in: rootViewController, animated: animated) {
diff --git a/ios/MullvadVPN/Base.lproj/Main.storyboard b/ios/MullvadVPN/Base.lproj/Main.storyboard
index b4c7fa178b..1477e2a02e 100644
--- a/ios/MullvadVPN/Base.lproj/Main.storyboard
+++ b/ios/MullvadVPN/Base.lproj/Main.storyboard
@@ -1,8 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="ZwP-1v-DUg">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="ZwP-1v-DUg">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
+ <deployment identifier="iOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -21,81 +22,7 @@
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="2sf-Y1-Ntj" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
- <point key="canvasLocation" x="-1962" y="27"/>
- </scene>
- <!--Root Container View Controller-->
- <scene sceneID="euw-TF-Dd7">
- <objects>
- <viewController storyboardIdentifier="Root" id="aW6-TO-kM3" customClass="RootContainerViewController" customModule="MullvadVPN" customModuleProvider="target" sceneMemberID="viewController">
- <view key="view" contentMode="scaleToFill" id="hQl-Sx-c1J">
- <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
- <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <subviews>
- <view contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LEj-gs-rBL">
- <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
- <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
- <viewLayoutGuide key="safeArea" id="Uo1-pA-GWn"/>
- </view>
- <view contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cw4-px-5hC">
- <rect key="frame" x="0.0" y="0.0" width="375" height="93"/>
- <subviews>
- <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="LogoIcon" translatesAutoresizingMaskIntoConstraints="NO" id="cKg-hE-JsS">
- <rect key="frame" x="12" y="34.5" width="44" height="44"/>
- <constraints>
- <constraint firstAttribute="width" secondItem="cKg-hE-JsS" secondAttribute="height" multiplier="1:1" id="jln-Ze-Hhl"/>
- <constraint firstAttribute="width" constant="44" id="u6D-kY-AyW"/>
- </constraints>
- </imageView>
- <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uXv-Tf-PET">
- <rect key="frame" x="311" y="32.5" width="48" height="48"/>
- <accessibility key="accessibilityConfiguration" identifier="SettingsButton"/>
- <state key="normal" image="IconSettings"/>
- <connections>
- <segue destination="Kqv-qu-mfF" kind="presentation" identifier="ShowSettings" id="cxu-NC-VeP"/>
- </connections>
- </button>
- <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="MULLVAD VPN" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dqy-A0-TdV">
- <rect key="frame" x="64" y="42" width="168" height="29"/>
- <fontDescription key="fontDescription" type="boldSystem" pointSize="24"/>
- <color key="textColor" white="1" alpha="0.80000000000000004" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
- <nil key="highlightedColor"/>
- </label>
- </subviews>
- <color key="backgroundColor" name="Primary"/>
- <constraints>
- <constraint firstAttribute="trailingMargin" secondItem="uXv-Tf-PET" secondAttribute="trailing" id="1LM-Tg-1Kr"/>
- <constraint firstItem="cKg-hE-JsS" firstAttribute="centerY" secondItem="dqy-A0-TdV" secondAttribute="centerY" id="IT0-VO-msz"/>
- <constraint firstAttribute="bottomMargin" secondItem="dqy-A0-TdV" secondAttribute="bottom" constant="22" id="YTk-xg-wIk"/>
- <constraint firstItem="uXv-Tf-PET" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="dqy-A0-TdV" secondAttribute="trailing" constant="8" symbolic="YES" id="ZEb-xZ-1ga"/>
- <constraint firstItem="uXv-Tf-PET" firstAttribute="centerY" secondItem="dqy-A0-TdV" secondAttribute="centerY" id="gCl-OS-ONw"/>
- <constraint firstItem="cKg-hE-JsS" firstAttribute="leading" secondItem="cw4-px-5hC" secondAttribute="leadingMargin" id="hGJ-yd-hnp"/>
- <constraint firstItem="dqy-A0-TdV" firstAttribute="top" secondItem="cw4-px-5hC" secondAttribute="topMargin" constant="22" id="mMF-ha-mRO"/>
- <constraint firstItem="dqy-A0-TdV" firstAttribute="leading" secondItem="cKg-hE-JsS" secondAttribute="trailing" constant="8" id="q8s-25-ASt"/>
- </constraints>
- <edgeInsets key="layoutMargins" top="20" left="12" bottom="0.0" right="16"/>
- </view>
- </subviews>
- <color key="backgroundColor" name="Primary"/>
- <constraints>
- <constraint firstItem="LEj-gs-rBL" firstAttribute="top" secondItem="hQl-Sx-c1J" secondAttribute="top" id="22p-PG-rk7"/>
- <constraint firstItem="LEj-gs-rBL" firstAttribute="leading" secondItem="hQl-Sx-c1J" secondAttribute="leading" id="Ehw-ts-TGl"/>
- <constraint firstAttribute="trailing" secondItem="cw4-px-5hC" secondAttribute="trailing" id="RE4-jS-w03"/>
- <constraint firstAttribute="bottom" secondItem="LEj-gs-rBL" secondAttribute="bottom" id="hXO-xN-pdV"/>
- <constraint firstItem="cw4-px-5hC" firstAttribute="top" secondItem="hQl-Sx-c1J" secondAttribute="top" id="k5T-fl-TkJ"/>
- <constraint firstAttribute="trailing" secondItem="LEj-gs-rBL" secondAttribute="trailing" id="o8y-zm-Y1o"/>
- <constraint firstItem="cw4-px-5hC" firstAttribute="leading" secondItem="hQl-Sx-c1J" secondAttribute="leading" id="u7B-kz-QQZ"/>
- </constraints>
- <viewLayoutGuide key="safeArea" id="gDr-jW-ZhR"/>
- </view>
- <connections>
- <outlet property="headerBarSettingsButton" destination="uXv-Tf-PET" id="psX-Ij-AXM"/>
- <outlet property="headerBarView" destination="cw4-px-5hC" id="lBM-gg-xZq"/>
- <outlet property="transitionContainer" destination="LEj-gs-rBL" id="WHt-LX-Uwu"/>
- </connections>
- </viewController>
- <placeholder placeholderIdentifier="IBFirstResponder" id="nyE-nN-nlq" userLabel="First Responder" sceneMemberID="firstResponder"/>
- </objects>
- <point key="canvasLocation" x="-431.19999999999999" y="26.53673163418291"/>
+ <point key="canvasLocation" x="-1306" y="27"/>
</scene>
<!--Login View Controller-->
<scene sceneID="tne-QT-ifu">
@@ -1455,7 +1382,6 @@
<image name="DefaultButton" width="9" height="9"/>
<image name="IconChevronDown" width="24" height="24"/>
<image name="IconExtlink" width="16" height="16"/>
- <image name="IconSettings" width="24" height="24"/>
<image name="IconSuccess" width="60" height="60"/>
<image name="IconTick" width="24" height="24"/>
<image name="LogoIcon" width="253" height="253"/>
diff --git a/ios/MullvadVPN/HeaderBarView.swift b/ios/MullvadVPN/HeaderBarView.swift
new file mode 100644
index 0000000000..be92076190
--- /dev/null
+++ b/ios/MullvadVPN/HeaderBarView.swift
@@ -0,0 +1,40 @@
+//
+// HeaderBarView.swift
+// MullvadVPN
+//
+// Created by pronebird on 19/06/2020.
+// Copyright © 2020 Mullvad VPN AB. All rights reserved.
+//
+
+import Foundation
+import UIKit
+
+class HeaderBarView: UIView {
+ @IBOutlet var contentView: UIView!
+ @IBOutlet var settingsButton: UIButton!
+
+ init(bundle: Bundle?) {
+ super.init(frame: .zero)
+
+ loadFromNib(bundle: bundle)
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ private func loadFromNib(bundle: Bundle?) {
+ let nib = UINib(nibName: "HeaderBarView", bundle: bundle)
+ _ = nib.instantiate(withOwner: self, options: nil)
+
+ let constraints = [contentView.leadingAnchor.constraint(equalTo: leadingAnchor),
+ contentView.trailingAnchor.constraint(equalTo: trailingAnchor),
+ contentView.topAnchor.constraint(equalTo: topAnchor),
+ contentView.bottomAnchor.constraint(equalTo: bottomAnchor)]
+
+ contentView.translatesAutoresizingMaskIntoConstraints = false
+ addSubview(contentView)
+
+ NSLayoutConstraint.activate(constraints)
+ }
+}
diff --git a/ios/MullvadVPN/HeaderBarView.xib b/ios/MullvadVPN/HeaderBarView.xib
new file mode 100644
index 0000000000..ab524ecbb1
--- /dev/null
+++ b/ios/MullvadVPN/HeaderBarView.xib
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+ <device id="retina6_1" orientation="portrait" appearance="light"/>
+ <dependencies>
+ <deployment identifier="iOS"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+ </dependencies>
+ <objects>
+ <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="HeaderBarView" customModule="MullvadVPN" customModuleProvider="target">
+ <connections>
+ <outlet property="contentView" destination="ov3-nw-UAQ" id="xIt-HC-BNQ"/>
+ <outlet property="settingsButton" destination="TCH-Bw-nMr" id="g2X-ry-UC8"/>
+ </connections>
+ </placeholder>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+ <view contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="ov3-nw-UAQ">
+ <rect key="frame" x="0.0" y="0.0" width="414" height="107"/>
+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+ <subviews>
+ <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="LogoIcon" translatesAutoresizingMaskIntoConstraints="NO" id="ZOX-0C-1fD">
+ <rect key="frame" x="20" y="41.5" width="44" height="44"/>
+ <constraints>
+ <constraint firstAttribute="width" secondItem="ZOX-0C-1fD" secondAttribute="height" multiplier="1:1" id="2q1-l2-vu7"/>
+ <constraint firstAttribute="width" constant="44" id="tDk-Mj-nnP"/>
+ </constraints>
+ </imageView>
+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TCH-Bw-nMr">
+ <rect key="frame" x="370" y="51.5" width="24" height="24"/>
+ <accessibility key="accessibilityConfiguration" identifier="SettingsButton"/>
+ <state key="normal" image="IconSettings"/>
+ </button>
+ <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="MULLVAD VPN" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qnt-qI-YIW">
+ <rect key="frame" x="72" y="42" width="168" height="43"/>
+ <fontDescription key="fontDescription" type="boldSystem" pointSize="24"/>
+ <color key="textColor" white="1" alpha="0.80000000000000004" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+ <nil key="highlightedColor"/>
+ </label>
+ </subviews>
+ <constraints>
+ <constraint firstAttribute="bottomMargin" secondItem="Qnt-qI-YIW" secondAttribute="bottom" constant="22" id="C4h-d6-8jh"/>
+ <constraint firstItem="TCH-Bw-nMr" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Qnt-qI-YIW" secondAttribute="trailing" constant="8" symbolic="YES" id="auJ-gc-6ue"/>
+ <constraint firstItem="Qnt-qI-YIW" firstAttribute="leading" secondItem="ZOX-0C-1fD" secondAttribute="trailing" constant="8" id="cD3-Tp-tkQ"/>
+ <constraint firstItem="TCH-Bw-nMr" firstAttribute="centerY" secondItem="Qnt-qI-YIW" secondAttribute="centerY" id="dAi-dp-MzM"/>
+ <constraint firstItem="ZOX-0C-1fD" firstAttribute="centerY" secondItem="Qnt-qI-YIW" secondAttribute="centerY" id="gut-cS-uB1"/>
+ <constraint firstAttribute="trailingMargin" secondItem="TCH-Bw-nMr" secondAttribute="trailing" id="qSf-ZX-xQs"/>
+ <constraint firstItem="Qnt-qI-YIW" firstAttribute="top" secondItem="ov3-nw-UAQ" secondAttribute="topMargin" constant="22" id="rTh-9P-ArN"/>
+ <constraint firstItem="ZOX-0C-1fD" firstAttribute="leading" secondItem="ov3-nw-UAQ" secondAttribute="leadingMargin" id="urJ-3h-lgX"/>
+ </constraints>
+ <nil key="simulatedTopBarMetrics"/>
+ <nil key="simulatedBottomBarMetrics"/>
+ <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+ <edgeInsets key="layoutMargins" top="20" left="12" bottom="0.0" right="16"/>
+ <point key="canvasLocation" x="84.057971014492765" y="-652.56696428571422"/>
+ </view>
+ </objects>
+ <resources>
+ <image name="IconSettings" width="24" height="24"/>
+ <image name="LogoIcon" width="253" height="253"/>
+ </resources>
+</document>
diff --git a/ios/MullvadVPN/RootContainerViewController.swift b/ios/MullvadVPN/RootContainerViewController.swift
index b66c75df4e..0c8ff7e40e 100644
--- a/ios/MullvadVPN/RootContainerViewController.swift
+++ b/ios/MullvadVPN/RootContainerViewController.swift
@@ -47,9 +47,8 @@ class RootContainerViewController: UIViewController {
return viewControllers.last
}
- @IBOutlet var headerBarView: UIView!
- @IBOutlet var headerBarSettingsButton: UIButton!
- @IBOutlet var transitionContainer: UIView!
+ private let headerBarView = HeaderBarView(bundle: nil)
+ private let transitionContainer = UIView(frame: UIScreen.main.bounds)
private(set) var headerBarStyle = HeaderBarStyle.default
private(set) var headerBarHidden = false
@@ -76,6 +75,8 @@ class RootContainerViewController: UIViewController {
margins.right = 24
view.layoutMargins = margins
+ addTransitionView()
+ addHeaderBarView()
updateHeaderBarBackground()
}
@@ -157,8 +158,10 @@ class RootContainerViewController: UIViewController {
/// Request to display settings controller
func showSettings(navigateTo route: SettingsNavigationRoute? = nil, animated: Bool) {
- guard let navController = self.storyboard?
- .instantiateViewController(identifier: ViewControllerIdentifier.settings.rawValue)
+ let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
+
+ guard let navController = mainStoryboard
+ .instantiateViewController(withIdentifier: ViewControllerIdentifier.settings.rawValue)
as? UINavigationController else { return }
if let route = route {
@@ -169,8 +172,50 @@ class RootContainerViewController: UIViewController {
present(navController, animated: animated)
}
+ /// Enable or disable the settings bar button displayed in the header bar
+ func setEnableSettingsButton(_ isEnabled: Bool) {
+ headerBarView.settingsButton.isEnabled = isEnabled
+ }
+
// MARK: - Private
+ private func addTransitionView() {
+ let constraints = [
+ transitionContainer.topAnchor.constraint(equalTo: view.topAnchor),
+ transitionContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor),
+ transitionContainer.trailingAnchor.constraint(equalTo: view.trailingAnchor),
+ transitionContainer.bottomAnchor.constraint(equalTo: view.bottomAnchor)
+ ]
+
+ transitionContainer.translatesAutoresizingMaskIntoConstraints = false
+ view.addSubview(transitionContainer)
+
+ NSLayoutConstraint.activate(constraints)
+ }
+
+ private func addHeaderBarView() {
+ let constraints = [
+ headerBarView.topAnchor.constraint(equalTo: view.topAnchor),
+ headerBarView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
+ headerBarView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
+ ]
+
+ headerBarView.translatesAutoresizingMaskIntoConstraints = false
+ headerBarView.settingsButton.addTarget(
+ self,
+ action: #selector(handleSettingsButtonTap),
+ for: .touchUpInside
+ )
+
+ view.addSubview(headerBarView)
+
+ NSLayoutConstraint.activate(constraints)
+ }
+
+ @objc private func handleSettingsButtonTap() {
+ showSettings(animated: true)
+ }
+
private func setViewControllersInternal(_ newViewControllers: [UIViewController], isUnwinding: Bool, animated: Bool, completion: CompletionHandler? = nil) {
// Dot not handle appearance events when the container itself is not visible
let shouldHandleAppearanceEvents = view.window != nil
diff --git a/ios/MullvadVPN/ViewControllerIdentifier.swift b/ios/MullvadVPN/ViewControllerIdentifier.swift
index 4d7b5fad12..dd4e8cbcff 100644
--- a/ios/MullvadVPN/ViewControllerIdentifier.swift
+++ b/ios/MullvadVPN/ViewControllerIdentifier.swift
@@ -10,7 +10,6 @@ import Foundation
enum ViewControllerIdentifier: String {
case consent = "Consent"
- case root = "Root"
case login = "Login"
case main = "Main"
case settings = "Settings"