diff options
| -rw-r--r-- | ios/MullvadVPN.xcodeproj/project.pbxproj | 12 | ||||
| -rw-r--r-- | ios/MullvadVPN/AppDelegate.swift | 11 | ||||
| -rw-r--r-- | ios/MullvadVPN/Base.lproj/Main.storyboard | 183 | ||||
| -rw-r--r-- | ios/MullvadVPN/BasicTableViewCell.swift | 8 | ||||
| -rw-r--r-- | ios/MullvadVPN/RootContainerViewController.swift | 2 | ||||
| -rw-r--r-- | ios/MullvadVPN/SettingsAccountCell.swift | 17 | ||||
| -rw-r--r-- | ios/MullvadVPN/SettingsAppVersionCell.swift | 13 | ||||
| -rw-r--r-- | ios/MullvadVPN/SettingsBasicCell.swift | 13 | ||||
| -rw-r--r-- | ios/MullvadVPN/SettingsCell.swift | 59 | ||||
| -rw-r--r-- | ios/MullvadVPN/SettingsNavigationController.swift | 6 | ||||
| -rw-r--r-- | ios/MullvadVPN/SettingsViewController.swift | 47 | ||||
| -rw-r--r-- | ios/MullvadVPN/ViewControllerIdentifier.swift | 13 |
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" -} |
