summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ios/MullvadVPN.xcodeproj/project.pbxproj12
-rw-r--r--ios/MullvadVPN/AppDelegate.swift11
-rw-r--r--ios/MullvadVPN/Base.lproj/Main.storyboard183
-rw-r--r--ios/MullvadVPN/BasicTableViewCell.swift8
-rw-r--r--ios/MullvadVPN/RootContainerViewController.swift2
-rw-r--r--ios/MullvadVPN/SettingsAccountCell.swift17
-rw-r--r--ios/MullvadVPN/SettingsAppVersionCell.swift13
-rw-r--r--ios/MullvadVPN/SettingsBasicCell.swift13
-rw-r--r--ios/MullvadVPN/SettingsCell.swift59
-rw-r--r--ios/MullvadVPN/SettingsNavigationController.swift6
-rw-r--r--ios/MullvadVPN/SettingsViewController.swift47
-rw-r--r--ios/MullvadVPN/ViewControllerIdentifier.swift13
12 files changed, 111 insertions, 273 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj
index a6fea6eb98..acb84d969c 100644
--- a/ios/MullvadVPN.xcodeproj/project.pbxproj
+++ b/ios/MullvadVPN.xcodeproj/project.pbxproj
@@ -50,8 +50,6 @@
581503A424D6F1EC00C9C50E /* ChainedError+Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581503A224D6F1EC00C9C50E /* ChainedError+Logger.swift */; };
581503A624D6F4AE00C9C50E /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581503A524D6F4AE00C9C50E /* Logging.swift */; };
581503A724D6F4AE00C9C50E /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581503A524D6F4AE00C9C50E /* Logging.swift */; };
- 581CBCE62296B97300727D7F /* ViewControllerIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581CBCE52296B97300727D7F /* ViewControllerIdentifier.swift */; };
- 581CBCEC2298041B00727D7F /* SettingsAppVersionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581CBCEB2298041B00727D7F /* SettingsAppVersionCell.swift */; };
581CBCEE229826FD00727D7F /* StaticTableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581CBCED229826FD00727D7F /* StaticTableViewDataSource.swift */; };
582AE3102440A6CA00E6733A /* AccountTokenInput.swift in Sources */ = {isa = PBXBuildFile; fileRef = 582AE30F2440A6CA00E6733A /* AccountTokenInput.swift */; };
582AE3122440CA0D00E6733A /* AccountTokenInputTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 582AE3112440CA0D00E6733A /* AccountTokenInputTests.swift */; };
@@ -103,7 +101,6 @@
58723E7522A54CB2009837F5 /* libwg-go.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58723E7422A54C63009837F5 /* libwg-go.a */; };
5873884D239E6D7E00E96C4E /* EmbeddedViewContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5873884C239E6D7E00E96C4E /* EmbeddedViewContainerView.swift */; };
587425C12299833500CA2045 /* RootContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 587425C02299833500CA2045 /* RootContainerViewController.swift */; };
- 5877152E23981C5B001F8237 /* SettingsBasicCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5877152D23981C5B001F8237 /* SettingsBasicCell.swift */; };
5877153023981F7B001F8237 /* WireguardKeysViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5877152F23981F7B001F8237 /* WireguardKeysViewController.swift */; };
58781CC922AE7CA8009B9D8E /* RelayConstraints.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58781CC822AE7CA8009B9D8E /* RelayConstraints.swift */; };
58781CCE22AE8918009B9D8E /* RelayConstraints.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58781CC822AE7CA8009B9D8E /* RelayConstraints.swift */; };
@@ -284,8 +281,6 @@
5815039C24D6ECE600C9C50E /* TextFileOutputStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFileOutputStream.swift; sourceTree = "<group>"; };
581503A224D6F1EC00C9C50E /* ChainedError+Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ChainedError+Logger.swift"; sourceTree = "<group>"; };
581503A524D6F4AE00C9C50E /* Logging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logging.swift; sourceTree = "<group>"; };
- 581CBCE52296B97300727D7F /* ViewControllerIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControllerIdentifier.swift; sourceTree = "<group>"; };
- 581CBCEB2298041B00727D7F /* SettingsAppVersionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsAppVersionCell.swift; sourceTree = "<group>"; };
581CBCED229826FD00727D7F /* StaticTableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticTableViewDataSource.swift; sourceTree = "<group>"; };
582AE30F2440A6CA00E6733A /* AccountTokenInput.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountTokenInput.swift; sourceTree = "<group>"; };
582AE3112440CA0D00E6733A /* AccountTokenInputTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountTokenInputTests.swift; sourceTree = "<group>"; };
@@ -312,7 +307,6 @@
58723E7422A54C63009837F5 /* libwg-go.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libwg-go.a"; sourceTree = BUILT_PRODUCTS_DIR; };
5873884C239E6D7E00E96C4E /* EmbeddedViewContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmbeddedViewContainerView.swift; sourceTree = "<group>"; };
587425C02299833500CA2045 /* RootContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootContainerViewController.swift; sourceTree = "<group>"; };
- 5877152D23981C5B001F8237 /* SettingsBasicCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsBasicCell.swift; sourceTree = "<group>"; };
5877152F23981F7B001F8237 /* WireguardKeysViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WireguardKeysViewController.swift; sourceTree = "<group>"; };
58781CC822AE7CA8009B9D8E /* RelayConstraints.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayConstraints.swift; sourceTree = "<group>"; };
58781CD422AFBA39009B9D8E /* RelaySelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelaySelector.swift; sourceTree = "<group>"; };
@@ -601,8 +595,6 @@
5857F24224C8662600CF6F47 /* SelectLocationHeaderView.swift */,
5857F24624C882D700CF6F47 /* SelectLocationNavigationController.swift */,
582BB1B2229574F40055B6EF /* SettingsAccountCell.swift */,
- 581CBCEB2298041B00727D7F /* SettingsAppVersionCell.swift */,
- 5877152D23981C5B001F8237 /* SettingsBasicCell.swift */,
582BB1AE229566420055B6EF /* SettingsCell.swift */,
58E6771E24ADFE7800AA26E7 /* SettingsNavigationController.swift */,
58CCA01122424D11004F3011 /* SettingsViewController.swift */,
@@ -619,7 +611,6 @@
587CBFE222807F530028DED3 /* UIColor+Helpers.swift */,
58CCA0152242560B004F3011 /* UIColor+Palette.swift */,
58FD5BF12424F7D700112C88 /* UserInterfaceInteractionRestriction.swift */,
- 581CBCE52296B97300727D7F /* ViewControllerIdentifier.swift */,
58B8743122B25A7600015324 /* WireguardAssociatedAddresses.swift */,
5877152F23981F7B001F8237 /* WireguardKeysViewController.swift */,
58B9814D24FEA70D00C0D59E /* WireguardKeysViewController.xib */,
@@ -983,7 +974,6 @@
582BB1B52295780F0055B6EF /* AccountExpiry.swift in Sources */,
582BB1B3229574F40055B6EF /* SettingsAccountCell.swift in Sources */,
58CCA010224249A1004F3011 /* ConnectViewController.swift in Sources */,
- 581CBCE62296B97300727D7F /* ViewControllerIdentifier.swift in Sources */,
580EE21524B3231200F9D8A1 /* OperationBlockObserver.swift in Sources */,
58BFA5C622A7C97F00A6173D /* RelayCache.swift in Sources */,
582BB1B1229569620055B6EF /* CustomNavigationBar.swift in Sources */,
@@ -1004,7 +994,6 @@
58CCA0162242560B004F3011 /* UIColor+Palette.swift in Sources */,
58AEEF6B2344A46200C9BBD5 /* TunnelSettingsManager.swift in Sources */,
587CBFE322807F530028DED3 /* UIColor+Helpers.swift in Sources */,
- 581CBCEC2298041B00727D7F /* SettingsAppVersionCell.swift in Sources */,
58FAEDFD24533A5500CB0F5B /* KeychainMatchLimit.swift in Sources */,
5840250422B11AB700E4CFEC /* MullvadEndpoint.swift in Sources */,
58CC40EF24A601900019D96E /* ObserverList.swift in Sources */,
@@ -1034,7 +1023,6 @@
5807E2C02432038B00F5FF30 /* String+Split.swift in Sources */,
58CE5E66224146200008646E /* LoginViewController.swift in Sources */,
580EE21B24B3236900F9D8A1 /* InputOperation.swift in Sources */,
- 5877152E23981C5B001F8237 /* SettingsBasicCell.swift in Sources */,
58FD5BE724192A2C00112C88 /* AppStoreReceipt.swift in Sources */,
5835B7CC233B76CB0096D79F /* TunnelManager.swift in Sources */,
5815039724D6ECAE00C9C50E /* CustomFormatLogHandler.swift in Sources */,
diff --git a/ios/MullvadVPN/AppDelegate.swift b/ios/MullvadVPN/AppDelegate.swift
index 4db1ade720..2b106a2ff1 100644
--- a/ios/MullvadVPN/AppDelegate.swift
+++ b/ios/MullvadVPN/AppDelegate.swift
@@ -14,8 +14,6 @@ import Logging
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
-
- let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
var rootContainer: RootContainerViewController?
#if targetEnvironment(simulator)
@@ -118,13 +116,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
extension AppDelegate: RootContainerViewControllerDelegate {
func rootContainerViewControllerShouldShowSettings(_ controller: RootContainerViewController, navigateTo route: SettingsNavigationRoute?, animated: Bool) {
- guard let navController = mainStoryboard
- .instantiateViewController(withIdentifier: ViewControllerIdentifier.settings.rawValue)
- as? UINavigationController else { return }
-
- guard let settingsController = navController.topViewController as? SettingsViewController else { return }
+ let settingsController = SettingsViewController(style: .grouped)
settingsController.settingsDelegate = self
+ let navController = SettingsNavigationController(navigationBarClass: CustomNavigationBar.self, toolbarClass: nil)
+ navController.pushViewController(settingsController, animated: false)
+
if let route = route {
settingsController.navigate(to: route)
}
diff --git a/ios/MullvadVPN/Base.lproj/Main.storyboard b/ios/MullvadVPN/Base.lproj/Main.storyboard
index 7f4ea612e6..4503b4021e 100644
--- a/ios/MullvadVPN/Base.lproj/Main.storyboard
+++ b/ios/MullvadVPN/Base.lproj/Main.storyboard
@@ -24,193 +24,10 @@
</objects>
<point key="canvasLocation" x="670" y="-57"/>
</scene>
- <!--Settings-->
- <scene sceneID="3oF-uu-3Bk">
- <objects>
- <tableViewController id="SHd-a4-ewi" customClass="SettingsViewController" customModule="MullvadVPN" customModuleProvider="target" sceneMemberID="viewController">
- <tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="6Gz-UM-orK">
- <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
- <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
- <color key="backgroundColor" name="Secondary"/>
- <color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
- <color key="separatorColor" name="Secondary"/>
- <prototypes>
- <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="Account" id="ghE-jC-RWf" customClass="SettingsAccountCell" customModule="MullvadVPN" customModuleProvider="target">
- <rect key="frame" x="0.0" y="55.5" width="375" height="43"/>
- <autoresizingMask key="autoresizingMask"/>
- <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="ghE-jC-RWf" id="sTl-gI-g2a">
- <rect key="frame" x="0.0" y="0.0" width="348" height="43"/>
- <autoresizingMask key="autoresizingMask"/>
- <subviews>
- <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Account" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Lve-Kd-qTr">
- <rect key="frame" x="16" y="11" width="63.5" height="21"/>
- <fontDescription key="fontDescription" type="system" pointSize="17"/>
- <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
- <nil key="highlightedColor"/>
- </label>
- <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" text="A YEAR LEFT" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QeD-EQ-Ruo">
- <rect key="frame" x="259" y="11" width="81" height="21"/>
- <fontDescription key="fontDescription" type="system" weight="medium" pointSize="13"/>
- <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
- <nil key="highlightedColor"/>
- </label>
- </subviews>
- <constraints>
- <constraint firstItem="Lve-Kd-qTr" firstAttribute="bottom" secondItem="sTl-gI-g2a" secondAttribute="bottomMargin" id="2nF-fr-JAQ"/>
- <constraint firstItem="Lve-Kd-qTr" firstAttribute="top" secondItem="sTl-gI-g2a" secondAttribute="topMargin" id="2se-fh-l9F"/>
- <constraint firstItem="QeD-EQ-Ruo" firstAttribute="top" secondItem="sTl-gI-g2a" secondAttribute="topMargin" id="6Cf-jR-RQ2"/>
- <constraint firstItem="QeD-EQ-Ruo" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Lve-Kd-qTr" secondAttribute="trailing" id="Axr-Q2-gFq"/>
- <constraint firstAttribute="bottomMargin" secondItem="QeD-EQ-Ruo" secondAttribute="bottom" id="VES-Yv-Ull"/>
- <constraint firstItem="QeD-EQ-Ruo" firstAttribute="trailing" secondItem="sTl-gI-g2a" secondAttribute="trailingMargin" id="bMl-dk-MoO"/>
- <constraint firstItem="Lve-Kd-qTr" firstAttribute="leading" secondItem="sTl-gI-g2a" secondAttribute="leadingMargin" id="yrm-Np-m0P"/>
- </constraints>
- </tableViewCellContentView>
- <color key="backgroundColor" name="Primary"/>
- <accessibility key="accessibilityConfiguration" identifier="AccountCell"/>
- <connections>
- <outlet property="expiryLabel" destination="QeD-EQ-Ruo" id="sr0-cQ-JV1"/>
- <outlet property="titleLabel" destination="Lve-Kd-qTr" id="psd-kM-u1u"/>
- </connections>
- </tableViewCell>
- <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="AppVersion" id="pbd-iC-Emm" customClass="SettingsAppVersionCell" customModule="MullvadVPN" customModuleProvider="target">
- <rect key="frame" x="0.0" y="98.5" width="375" height="43"/>
- <autoresizingMask key="autoresizingMask"/>
- <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="pbd-iC-Emm" id="lYp-Z8-1sN">
- <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
- <autoresizingMask key="autoresizingMask"/>
- <subviews>
- <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="App version" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pYC-Zb-8N9">
- <rect key="frame" x="16" y="11" width="91" height="21"/>
- <fontDescription key="fontDescription" type="system" pointSize="17"/>
- <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
- <nil key="highlightedColor"/>
- </label>
- <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" text="2018.3" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sOr-vj-cg7">
- <rect key="frame" x="316.5" y="11" width="42.5" height="21"/>
- <fontDescription key="fontDescription" type="system" weight="medium" pointSize="13"/>
- <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
- <nil key="highlightedColor"/>
- </label>
- </subviews>
- <constraints>
- <constraint firstItem="pYC-Zb-8N9" firstAttribute="top" secondItem="lYp-Z8-1sN" secondAttribute="topMargin" id="6Ih-SA-8o0"/>
- <constraint firstAttribute="bottomMargin" secondItem="sOr-vj-cg7" secondAttribute="bottom" id="8Gv-HC-Rxo"/>
- <constraint firstItem="sOr-vj-cg7" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="pYC-Zb-8N9" secondAttribute="trailing" constant="8" symbolic="YES" id="IYX-rX-a2Q"/>
- <constraint firstAttribute="trailingMargin" secondItem="sOr-vj-cg7" secondAttribute="trailing" id="Is4-dU-mbu"/>
- <constraint firstAttribute="bottomMargin" secondItem="pYC-Zb-8N9" secondAttribute="bottom" id="NpP-d6-M0T"/>
- <constraint firstItem="pYC-Zb-8N9" firstAttribute="leading" secondItem="lYp-Z8-1sN" secondAttribute="leadingMargin" id="Ove-uA-2Fw"/>
- <constraint firstItem="sOr-vj-cg7" firstAttribute="top" secondItem="lYp-Z8-1sN" secondAttribute="topMargin" id="qeA-c2-OxT"/>
- </constraints>
- </tableViewCellContentView>
- <color key="backgroundColor" name="Primary"/>
- <connections>
- <outlet property="versionLabel" destination="sOr-vj-cg7" id="xgH-No-26f"/>
- </connections>
- </tableViewCell>
- <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="BasicDisclosure" id="Ahs-gu-nTM" customClass="SettingsBasicCell" customModule="MullvadVPN" customModuleProvider="target">
- <rect key="frame" x="0.0" y="141.5" width="375" height="43"/>
- <autoresizingMask key="autoresizingMask"/>
- <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Ahs-gu-nTM" id="Drq-vk-8F2">
- <rect key="frame" x="0.0" y="0.0" width="348" height="43"/>
- <autoresizingMask key="autoresizingMask"/>
- <subviews>
- <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Amw-A3-ePS">
- <rect key="frame" x="16" y="11" width="324" height="21"/>
- <fontDescription key="fontDescription" type="system" pointSize="17"/>
- <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
- <nil key="highlightedColor"/>
- </label>
- </subviews>
- <constraints>
- <constraint firstItem="Amw-A3-ePS" firstAttribute="leading" secondItem="Drq-vk-8F2" secondAttribute="leadingMargin" id="4Ug-US-l8D"/>
- <constraint firstItem="Amw-A3-ePS" firstAttribute="top" secondItem="Drq-vk-8F2" secondAttribute="topMargin" id="6ID-BF-Jsp"/>
- <constraint firstAttribute="bottomMargin" secondItem="Amw-A3-ePS" secondAttribute="bottom" id="JPQ-S7-zHO"/>
- <constraint firstAttribute="trailingMargin" secondItem="Amw-A3-ePS" secondAttribute="trailing" id="lhc-g5-1mb"/>
- </constraints>
- </tableViewCellContentView>
- <color key="backgroundColor" name="Primary"/>
- <connections>
- <outlet property="titleLabel" destination="Amw-A3-ePS" id="cGS-cX-LXr"/>
- </connections>
- </tableViewCell>
- <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="Basic" id="kzz-4X-xg1" customClass="SettingsBasicCell" customModule="MullvadVPN" customModuleProvider="target">
- <rect key="frame" x="0.0" y="184.5" width="375" height="43"/>
- <autoresizingMask key="autoresizingMask"/>
- <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="kzz-4X-xg1" id="KpJ-UC-PyV">
- <rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
- <autoresizingMask key="autoresizingMask"/>
- <subviews>
- <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PWF-Y6-mDf">
- <rect key="frame" x="16" y="11" width="343" height="21"/>
- <fontDescription key="fontDescription" type="system" pointSize="17"/>
- <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
- <nil key="highlightedColor"/>
- </label>
- </subviews>
- <constraints>
- <constraint firstItem="PWF-Y6-mDf" firstAttribute="top" secondItem="KpJ-UC-PyV" secondAttribute="topMargin" id="7c8-Np-uyI"/>
- <constraint firstAttribute="trailingMargin" secondItem="PWF-Y6-mDf" secondAttribute="trailing" id="G6s-Z9-acp"/>
- <constraint firstAttribute="bottomMargin" secondItem="PWF-Y6-mDf" secondAttribute="bottom" id="ICb-f1-Zux"/>
- <constraint firstItem="PWF-Y6-mDf" firstAttribute="leading" secondItem="KpJ-UC-PyV" secondAttribute="leadingMargin" id="teH-t2-aJn"/>
- </constraints>
- </tableViewCellContentView>
- <color key="backgroundColor" name="Primary"/>
- <connections>
- <outlet property="titleLabel" destination="PWF-Y6-mDf" id="G5i-Wm-WZN"/>
- </connections>
- </tableViewCell>
- </prototypes>
- <sections/>
- <connections>
- <outlet property="dataSource" destination="9xf-6a-8vR" id="DSW-6u-Rhl"/>
- <outlet property="delegate" destination="9xf-6a-8vR" id="HBx-xF-dDg"/>
- </connections>
- </tableView>
- <navigationItem key="navigationItem" title="Settings" id="Xxl-r7-Sbm">
- <barButtonItem key="rightBarButtonItem" style="done" systemItem="done" id="AnV-sJ-aya">
- <connections>
- <action selector="handleDismiss" destination="SHd-a4-ewi" id="eE7-bB-mer"/>
- </connections>
- </barButtonItem>
- </navigationItem>
- <connections>
- <outlet property="staticDataSource" destination="9xf-6a-8vR" id="E8j-Z4-Ljk"/>
- </connections>
- </tableViewController>
- <placeholder placeholderIdentifier="IBFirstResponder" id="sR5-ix-4x7" userLabel="First Responder" sceneMemberID="firstResponder"/>
- <customObject id="9xf-6a-8vR" customClass="SettingsTableViewDataSource" customModule="MullvadVPN" customModuleProvider="target">
- <connections>
- <outlet property="tableView" destination="6Gz-UM-orK" id="Ipk-3P-ycO"/>
- </connections>
- </customObject>
- </objects>
- <point key="canvasLocation" x="1690" y="-832"/>
- </scene>
- <!--Settings Navigation Controller-->
- <scene sceneID="er3-W2-NkS">
- <objects>
- <navigationController storyboardIdentifier="Settings" id="Kqv-qu-mfF" customClass="SettingsNavigationController" customModule="MullvadVPN" customModuleProvider="target" sceneMemberID="viewController">
- <navigationItem key="navigationItem" id="7IR-NQ-qLb"/>
- <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" barStyle="black" largeTitles="YES" id="7PK-0x-byW" customClass="CustomNavigationBar" customModule="MullvadVPN" customModuleProvider="target">
- <rect key="frame" x="0.0" y="0.0" width="375" height="96"/>
- <autoresizingMask key="autoresizingMask"/>
- <color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
- </navigationBar>
- <connections>
- <segue destination="SHd-a4-ewi" kind="relationship" relationship="rootViewController" id="5n8-Yk-l4C"/>
- </connections>
- </navigationController>
- <placeholder placeholderIdentifier="IBFirstResponder" id="bHt-Id-Zc4" userLabel="First Responder" sceneMemberID="firstResponder"/>
- </objects>
- <point key="canvasLocation" x="670" y="-832"/>
- </scene>
</scenes>
<resources>
<namedColor name="Primary">
<color red="0.16078431372549021" green="0.30196078431372547" blue="0.45098039215686275" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
- <namedColor name="Secondary">
- <color red="0.098039215686274508" green="0.1803921568627451" blue="0.27058823529411763" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
- </namedColor>
</resources>
</document>
diff --git a/ios/MullvadVPN/BasicTableViewCell.swift b/ios/MullvadVPN/BasicTableViewCell.swift
index 68158801db..fd506d309d 100644
--- a/ios/MullvadVPN/BasicTableViewCell.swift
+++ b/ios/MullvadVPN/BasicTableViewCell.swift
@@ -10,8 +10,8 @@ import UIKit
class BasicTableViewCell: UITableViewCell {
- override func awakeFromNib() {
- super.awakeFromNib()
+ override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
+ super.init(style: style, reuseIdentifier: reuseIdentifier)
let backgroundView = UIView()
backgroundView.backgroundColor = UIColor.Cell.backgroundColor
@@ -25,4 +25,8 @@ class BasicTableViewCell: UITableViewCell {
contentView.backgroundColor = UIColor.clear
}
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
}
diff --git a/ios/MullvadVPN/RootContainerViewController.swift b/ios/MullvadVPN/RootContainerViewController.swift
index 7eed0459bc..9ddc903af5 100644
--- a/ios/MullvadVPN/RootContainerViewController.swift
+++ b/ios/MullvadVPN/RootContainerViewController.swift
@@ -40,7 +40,7 @@ protocol RootContainerViewControllerDelegate: class {
func rootContainerViewControllerShouldShowSettings(_ controller: RootContainerViewController, navigateTo route: SettingsNavigationRoute?, animated: Bool)
}
-/// A root container class that primarily handles the unwind storyboard segues on log out
+/// A root container view controller
class RootContainerViewController: UIViewController {
typealias CompletionHandler = () -> Void
diff --git a/ios/MullvadVPN/SettingsAccountCell.swift b/ios/MullvadVPN/SettingsAccountCell.swift
index 7167efb709..1dbbee3198 100644
--- a/ios/MullvadVPN/SettingsAccountCell.swift
+++ b/ios/MullvadVPN/SettingsAccountCell.swift
@@ -10,9 +10,6 @@ import UIKit
class SettingsAccountCell: SettingsCell {
- @IBOutlet var titleLabel: UILabel!
- @IBOutlet var expiryLabel: UILabel!
-
var accountExpiryDate: Date? {
didSet {
didUpdateAccountExpiry()
@@ -24,22 +21,22 @@ class SettingsAccountCell: SettingsCell {
let accountExpiry = AccountExpiry(date: accountExpiryDate)
if accountExpiry.isExpired {
- expiryLabel.text = NSLocalizedString("OUT OF TIME", comment: "")
- expiryLabel.textColor = .dangerColor
+ detailTitleLabel.text = NSLocalizedString("OUT OF TIME", comment: "")
+ detailTitleLabel.textColor = .dangerColor
} else {
if let remainingTime = accountExpiry.formattedRemainingTime {
let localizedString = NSLocalizedString("%@ left", comment: "")
let formattedString = String(format: localizedString, remainingTime)
- expiryLabel.text = formattedString.uppercased()
+ detailTitleLabel.text = formattedString.uppercased()
} else {
- expiryLabel.text = ""
+ detailTitleLabel.text = ""
}
- expiryLabel.textColor = .white
+ detailTitleLabel.textColor = .white
}
} else {
- expiryLabel.text = ""
- expiryLabel.textColor = .white
+ detailTitleLabel.text = ""
+ detailTitleLabel.textColor = .white
}
}
diff --git a/ios/MullvadVPN/SettingsAppVersionCell.swift b/ios/MullvadVPN/SettingsAppVersionCell.swift
deleted file mode 100644
index 8639687bd7..0000000000
--- a/ios/MullvadVPN/SettingsAppVersionCell.swift
+++ /dev/null
@@ -1,13 +0,0 @@
-//
-// SettingsAppVersionCell.swift
-// MullvadVPN
-//
-// Created by pronebird on 24/05/2019.
-// Copyright © 2019 Mullvad VPN AB. All rights reserved.
-//
-
-import UIKit
-
-class SettingsAppVersionCell: SettingsCell {
- @IBOutlet var versionLabel: UILabel!
-}
diff --git a/ios/MullvadVPN/SettingsBasicCell.swift b/ios/MullvadVPN/SettingsBasicCell.swift
deleted file mode 100644
index 8755dcdc69..0000000000
--- a/ios/MullvadVPN/SettingsBasicCell.swift
+++ /dev/null
@@ -1,13 +0,0 @@
-//
-// SettingsBasicCell.swift
-// MullvadVPN
-//
-// Created by pronebird on 04/12/2019.
-// Copyright © 2019 Mullvad VPN AB. All rights reserved.
-//
-
-import UIKit
-
-class SettingsBasicCell: SettingsCell {
- @IBOutlet var titleLabel: UILabel!
-}
diff --git a/ios/MullvadVPN/SettingsCell.swift b/ios/MullvadVPN/SettingsCell.swift
index 84967b9a1d..b8d46fe148 100644
--- a/ios/MullvadVPN/SettingsCell.swift
+++ b/ios/MullvadVPN/SettingsCell.swift
@@ -10,21 +10,66 @@ import UIKit
class SettingsCell: BasicTableViewCell {
+ let titleLabel = UILabel()
+ let detailTitleLabel = UILabel()
+
private let preferredMargins = UIEdgeInsets(top: 16, left: 24, bottom: 16, right: 12)
private var appDidBecomeActiveObserver: NSObjectProtocol?
- override func awakeFromNib() {
- super.awakeFromNib()
+ override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
+ super.init(style: style, reuseIdentifier: reuseIdentifier)
+ tintColor = .white
backgroundView?.backgroundColor = UIColor.Cell.backgroundColor
selectedBackgroundView?.backgroundColor = UIColor.Cell.selectedAltBackgroundColor
contentView.layoutMargins = preferredMargins
separatorInset = .zero
+ titleLabel.translatesAutoresizingMaskIntoConstraints = false
+ titleLabel.font = UIFont.systemFont(ofSize: 17)
+ titleLabel.textColor = .white
+
+ detailTitleLabel.translatesAutoresizingMaskIntoConstraints = false
+ detailTitleLabel.font = UIFont.systemFont(ofSize: 13)
+ detailTitleLabel.textColor = .white
+
+ titleLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
+ detailTitleLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
+
+ titleLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
+ detailTitleLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
+
+ contentView.addSubview(titleLabel)
+ contentView.addSubview(detailTitleLabel)
+
+ NSLayoutConstraint.activate([
+ titleLabel.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor),
+ titleLabel.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor),
+ titleLabel.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor),
+
+ detailTitleLabel.leadingAnchor.constraint(greaterThanOrEqualToSystemSpacingAfter: titleLabel.trailingAnchor, multiplier: 1),
+
+ detailTitleLabel.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor),
+ detailTitleLabel.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor),
+ detailTitleLabel.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor),
+ ])
+
enableDisclosureViewTintColorFix()
}
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ override func didAddSubview(_ subview: UIView) {
+ super.didAddSubview(subview)
+
+ if let button = subview as? UIButton {
+ updateDisclosureButtonBackgroundImageRenderingMode(button)
+ }
+ }
+
/// `UITableViewCell` resets the disclosure view image when the app goes in background
/// This fix ensures that the image is tinted when the app becomes active again.
private func enableDisclosureViewTintColorFix() {
@@ -42,9 +87,13 @@ class SettingsCell: BasicTableViewCell {
/// Fix this by looking for the accessory button and changing the image rendering mode
private func updateDisclosureViewTintColor() {
for case let button as UIButton in subviews {
- if let image = button.backgroundImage(for: .normal)?.withRenderingMode(.alwaysTemplate) {
- button.setBackgroundImage(image, for: .normal)
- }
+ updateDisclosureButtonBackgroundImageRenderingMode(button)
+ }
+ }
+
+ private func updateDisclosureButtonBackgroundImageRenderingMode(_ button: UIButton) {
+ if let image = button.backgroundImage(for: .normal)?.withRenderingMode(.alwaysTemplate) {
+ button.setBackgroundImage(image, for: .normal)
}
}
}
diff --git a/ios/MullvadVPN/SettingsNavigationController.swift b/ios/MullvadVPN/SettingsNavigationController.swift
index 326c2047bd..87527b77cb 100644
--- a/ios/MullvadVPN/SettingsNavigationController.swift
+++ b/ios/MullvadVPN/SettingsNavigationController.swift
@@ -10,10 +10,16 @@ import Foundation
import UIKit
class SettingsNavigationController: UINavigationController {
+
override func viewDidLoad() {
super.viewDidLoad()
+ navigationBar.barStyle = .black
+ navigationBar.tintColor = .white
+ navigationBar.prefersLargeTitles = true
+
// Update account expiry
Account.shared.updateAccountExpiry()
}
+
}
diff --git a/ios/MullvadVPN/SettingsViewController.swift b/ios/MullvadVPN/SettingsViewController.swift
index a3b3ab3f8a..201451c09e 100644
--- a/ios/MullvadVPN/SettingsViewController.swift
+++ b/ios/MullvadVPN/SettingsViewController.swift
@@ -25,15 +25,13 @@ protocol SettingsViewControllerDelegate: class {
class SettingsViewController: UITableViewController, AccountViewControllerDelegate {
- @IBOutlet var staticDataSource: SettingsTableViewDataSource!
-
private enum CellIdentifier: String {
- case account = "Account"
- case appVersion = "AppVersion"
- case basicDisclosure = "BasicDisclosure"
- case basic = "Basic"
+ case accountCell = "AccountCell"
+ case basicCell = "BasicCell"
}
+ private let staticDataSource = SettingsTableViewDataSource()
+
private weak var accountRow: StaticTableViewRow?
private var accountExpiryObserver: NSObjectProtocol?
@@ -42,6 +40,23 @@ class SettingsViewController: UITableViewController, AccountViewControllerDelega
override func viewDidLoad() {
super.viewDidLoad()
+ tableView.backgroundColor = .secondaryColor
+ tableView.separatorColor = .secondaryColor
+ tableView.rowHeight = UITableView.automaticDimension
+ tableView.estimatedRowHeight = 60
+ tableView.sectionHeaderHeight = 18
+ tableView.sectionFooterHeight = 18
+
+ tableView.dataSource = staticDataSource
+ tableView.delegate = staticDataSource
+
+ tableView.register(SettingsAccountCell.self, forCellReuseIdentifier: CellIdentifier.accountCell.rawValue)
+ tableView.register(SettingsCell.self, forCellReuseIdentifier: CellIdentifier.basicCell.rawValue)
+
+ navigationItem.title = NSLocalizedString("Settings", comment: "Navigation title")
+ navigationItem.largeTitleDisplayMode = .always
+ navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(handleDismiss))
+
accountExpiryObserver = NotificationCenter.default.addObserver(
forName: Account.didUpdateAccountExpiryNotification,
object: Account.shared,
@@ -88,21 +103,24 @@ class SettingsViewController: UITableViewController, AccountViewControllerDelega
private func setupDataSource() {
if Account.shared.isLoggedIn {
let topSection = StaticTableViewSection()
- let accountRow = StaticTableViewRow(reuseIdentifier: CellIdentifier.account.rawValue) { (_, cell) in
+ let accountRow = StaticTableViewRow(reuseIdentifier: CellIdentifier.accountCell.rawValue) { (_, cell) in
let cell = cell as! SettingsAccountCell
+ cell.titleLabel.text = NSLocalizedString("Account", comment: "")
cell.accountExpiryDate = Account.shared.expiry
+ cell.accessoryType = .disclosureIndicator
}
accountRow.actionBlock = { [weak self] (indexPath) in
self?.navigate(to: .account)
}
- let wireguardKeyRow = StaticTableViewRow(reuseIdentifier: CellIdentifier.basicDisclosure.rawValue) { (_, cell) in
- let cell = cell as! SettingsBasicCell
+ let wireguardKeyRow = StaticTableViewRow(reuseIdentifier: CellIdentifier.basicCell.rawValue) { (_, cell) in
+ let cell = cell as! SettingsCell
cell.titleLabel.text = NSLocalizedString("WireGuard key", comment: "")
cell.accessibilityIdentifier = "WireGuardKeyCell"
+ cell.accessoryType = .disclosureIndicator
}
wireguardKeyRow.actionBlock = { [weak self] (indexPath) in
@@ -116,11 +134,12 @@ class SettingsViewController: UITableViewController, AccountViewControllerDelega
}
let middleSection = StaticTableViewSection()
- let versionRow = StaticTableViewRow(reuseIdentifier: CellIdentifier.appVersion.rawValue) { (_, cell) in
- let cell = cell as! SettingsAppVersionCell
+ let versionRow = StaticTableViewRow(reuseIdentifier: CellIdentifier.basicCell.rawValue) { (_, cell) in
+ let cell = cell as! SettingsCell
let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
- cell.versionLabel.text = version
+ cell.titleLabel.text = NSLocalizedString("App version", comment: "")
+ cell.detailTitleLabel.text = version
}
versionRow.isSelectable = false
@@ -128,8 +147,8 @@ class SettingsViewController: UITableViewController, AccountViewControllerDelega
staticDataSource.addSections([middleSection])
#if DEBUG
- let logStreamerRow = StaticTableViewRow(reuseIdentifier: CellIdentifier.basic.rawValue) { (_, cell) in
- let cell = cell as! SettingsBasicCell
+ let logStreamerRow = StaticTableViewRow(reuseIdentifier: CellIdentifier.basicCell.rawValue) { (_, cell) in
+ let cell = cell as! SettingsCell
cell.titleLabel.text = NSLocalizedString("App logs", comment: "")
}
diff --git a/ios/MullvadVPN/ViewControllerIdentifier.swift b/ios/MullvadVPN/ViewControllerIdentifier.swift
deleted file mode 100644
index 247d31dc60..0000000000
--- a/ios/MullvadVPN/ViewControllerIdentifier.swift
+++ /dev/null
@@ -1,13 +0,0 @@
-//
-// ViewControllerIdentifier.swift
-// MullvadVPN
-//
-// Created by pronebird on 23/05/2019.
-// Copyright © 2019 Mullvad VPN AB. All rights reserved.
-//
-
-import Foundation
-
-enum ViewControllerIdentifier: String {
- case settings = "Settings"
-}