Basic setup of ConnectionsTableViewController.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
d15972d2ce
commit
e6c6fd0b34
|
@ -0,0 +1,36 @@
|
||||||
|
//
|
||||||
|
// UITableView+WireGuard.swift
|
||||||
|
// WireGuard
|
||||||
|
//
|
||||||
|
// Created by Jeroen Leenarts on 24-05-18.
|
||||||
|
// Copyright © 2018 WireGuard. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension UITableView {
|
||||||
|
|
||||||
|
func register<T: Identifyable>(type: T.Type, prefix: String = "") where T: UITableViewCell {
|
||||||
|
register(type, forCellReuseIdentifier: prefix + type.identifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dequeueReusableCell<T: Identifyable>(type: T.Type, for indexPath: IndexPath, prefix: String = "") -> T where T: UITableViewCell {
|
||||||
|
return dequeueReusableCell(withIdentifier: prefix + type.identifier, for: indexPath) as! T // swiftlint:disable:this force_cast
|
||||||
|
}
|
||||||
|
|
||||||
|
func registerNib<T: Identifyable>(type: T.Type, prefix: String = "") where T: UITableViewCell {
|
||||||
|
let nib = UINib(nibName: prefix + type.identifier, bundle: nil)
|
||||||
|
register(nib, forCellReuseIdentifier: prefix + type.identifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
func registerNib<T: Identifyable>(type: T.Type, prefix: String = "") where T: UITableViewHeaderFooterView {
|
||||||
|
let nib = UINib(nibName: prefix + type.identifier, bundle: nil)
|
||||||
|
register(nib, forHeaderFooterViewReuseIdentifier: prefix + type.identifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dequeueReusableHeaderFooterView<T: Identifyable>(type: T.Type, prefix: String = "") -> T where T: UITableViewHeaderFooterView {
|
||||||
|
return dequeueReusableHeaderFooterView(withIdentifier: prefix + type.identifier) as! T // swiftlint:disable:this force_cast
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,7 @@
|
||||||
4A4BAD0E20B5F6C300F12B28 /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD0D20B5F6C300F12B28 /* Coordinator.swift */; };
|
4A4BAD0E20B5F6C300F12B28 /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD0D20B5F6C300F12B28 /* Coordinator.swift */; };
|
||||||
4A4BAD1020B5F6EC00F12B28 /* RootCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD0F20B5F6EC00F12B28 /* RootCoordinator.swift */; };
|
4A4BAD1020B5F6EC00F12B28 /* RootCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD0F20B5F6EC00F12B28 /* RootCoordinator.swift */; };
|
||||||
4A4BAD1320B5F82400F12B28 /* Identifyable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD1220B5F82400F12B28 /* Identifyable.swift */; };
|
4A4BAD1320B5F82400F12B28 /* Identifyable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD1220B5F82400F12B28 /* Identifyable.swift */; };
|
||||||
4A4BAD1720B5F8DE00F12B28 /* Wireguard.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD1520B5F8DE00F12B28 /* Wireguard.xcdatamodeld */; };
|
4A4BAD1720B5F8DE00F12B28 /* WireGuard.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD1520B5F8DE00F12B28 /* WireGuard.xcdatamodeld */; };
|
||||||
4A4BAD1A20B5F8FF00F12B28 /* Profile+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD1820B5F8FF00F12B28 /* Profile+CoreDataClass.swift */; };
|
4A4BAD1A20B5F8FF00F12B28 /* Profile+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD1820B5F8FF00F12B28 /* Profile+CoreDataClass.swift */; };
|
||||||
4A4BAD1B20B5F8FF00F12B28 /* Profile+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD1920B5F8FF00F12B28 /* Profile+CoreDataProperties.swift */; };
|
4A4BAD1B20B5F8FF00F12B28 /* Profile+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD1920B5F8FF00F12B28 /* Profile+CoreDataProperties.swift */; };
|
||||||
4A4BAD2020B6026900F12B28 /* Peer+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD1C20B6026900F12B28 /* Peer+CoreDataProperties.swift */; };
|
4A4BAD2020B6026900F12B28 /* Peer+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD1C20B6026900F12B28 /* Peer+CoreDataProperties.swift */; };
|
||||||
|
@ -28,6 +28,7 @@
|
||||||
4A4BAD2320B6026900F12B28 /* Interface+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD1F20B6026900F12B28 /* Interface+CoreDataClass.swift */; };
|
4A4BAD2320B6026900F12B28 /* Interface+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BAD1F20B6026900F12B28 /* Interface+CoreDataClass.swift */; };
|
||||||
4A7F6EDD20B674CD00B260B7 /* Address+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A7F6EDB20B674CD00B260B7 /* Address+CoreDataClass.swift */; };
|
4A7F6EDD20B674CD00B260B7 /* Address+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A7F6EDB20B674CD00B260B7 /* Address+CoreDataClass.swift */; };
|
||||||
4A7F6EDE20B674CD00B260B7 /* Address+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A7F6EDC20B674CD00B260B7 /* Address+CoreDataProperties.swift */; };
|
4A7F6EDE20B674CD00B260B7 /* Address+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A7F6EDC20B674CD00B260B7 /* Address+CoreDataProperties.swift */; };
|
||||||
|
4A8AABD820B6A79100B6D8C1 /* UITableView+WireGuard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A8AABD720B6A79100B6D8C1 /* UITableView+WireGuard.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
@ -58,7 +59,7 @@
|
||||||
4A4BAD0D20B5F6C300F12B28 /* Coordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = "<group>"; };
|
4A4BAD0D20B5F6C300F12B28 /* Coordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = "<group>"; };
|
||||||
4A4BAD0F20B5F6EC00F12B28 /* RootCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootCoordinator.swift; sourceTree = "<group>"; };
|
4A4BAD0F20B5F6EC00F12B28 /* RootCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootCoordinator.swift; sourceTree = "<group>"; };
|
||||||
4A4BAD1220B5F82400F12B28 /* Identifyable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Identifyable.swift; sourceTree = "<group>"; };
|
4A4BAD1220B5F82400F12B28 /* Identifyable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Identifyable.swift; sourceTree = "<group>"; };
|
||||||
4A4BAD1620B5F8DE00F12B28 /* Wireguard.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Wireguard.xcdatamodel; sourceTree = "<group>"; };
|
4A4BAD1620B5F8DE00F12B28 /* WireGuard.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = WireGuard.xcdatamodel; sourceTree = "<group>"; };
|
||||||
4A4BAD1820B5F8FF00F12B28 /* Profile+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Profile+CoreDataClass.swift"; sourceTree = "<group>"; };
|
4A4BAD1820B5F8FF00F12B28 /* Profile+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Profile+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||||
4A4BAD1920B5F8FF00F12B28 /* Profile+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Profile+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
4A4BAD1920B5F8FF00F12B28 /* Profile+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Profile+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||||
4A4BAD1C20B6026900F12B28 /* Peer+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Peer+CoreDataProperties.swift"; path = "/Users/jeroenleenarts/code/wireguard-ios/Wireguard/Models/Peer+CoreDataProperties.swift"; sourceTree = "<absolute>"; };
|
4A4BAD1C20B6026900F12B28 /* Peer+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Peer+CoreDataProperties.swift"; path = "/Users/jeroenleenarts/code/wireguard-ios/Wireguard/Models/Peer+CoreDataProperties.swift"; sourceTree = "<absolute>"; };
|
||||||
|
@ -67,6 +68,7 @@
|
||||||
4A4BAD1F20B6026900F12B28 /* Interface+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Interface+CoreDataClass.swift"; path = "/Users/jeroenleenarts/code/wireguard-ios/Wireguard/Models/Interface+CoreDataClass.swift"; sourceTree = "<absolute>"; };
|
4A4BAD1F20B6026900F12B28 /* Interface+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Interface+CoreDataClass.swift"; path = "/Users/jeroenleenarts/code/wireguard-ios/Wireguard/Models/Interface+CoreDataClass.swift"; sourceTree = "<absolute>"; };
|
||||||
4A7F6EDB20B674CD00B260B7 /* Address+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Address+CoreDataClass.swift"; sourceTree = "<group>"; };
|
4A7F6EDB20B674CD00B260B7 /* Address+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Address+CoreDataClass.swift"; sourceTree = "<group>"; };
|
||||||
4A7F6EDC20B674CD00B260B7 /* Address+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Address+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
4A7F6EDC20B674CD00B260B7 /* Address+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Address+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||||
|
4A8AABD720B6A79100B6D8C1 /* UITableView+WireGuard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableView+WireGuard.swift"; sourceTree = "<group>"; };
|
||||||
82069F3AE97A82448F990CFB /* Pods-Wireguard.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Wireguard.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Wireguard/Pods-Wireguard.debug.xcconfig"; sourceTree = "<group>"; };
|
82069F3AE97A82448F990CFB /* Pods-Wireguard.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Wireguard.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Wireguard/Pods-Wireguard.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
861983CAE8FDC13BC83E7E04 /* Pods_WireGuard.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WireGuard.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
861983CAE8FDC13BC83E7E04 /* Pods_WireGuard.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WireGuard.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
8BF50C7EC60CD91BBA05E51F /* Pods_Wireguard.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Wireguard.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
8BF50C7EC60CD91BBA05E51F /* Pods_Wireguard.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Wireguard.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
@ -160,6 +162,7 @@
|
||||||
children = (
|
children = (
|
||||||
4A4BAD1220B5F82400F12B28 /* Identifyable.swift */,
|
4A4BAD1220B5F82400F12B28 /* Identifyable.swift */,
|
||||||
4A4BACE720B5F1BF00F12B28 /* ConnectionsTableViewController.swift */,
|
4A4BACE720B5F1BF00F12B28 /* ConnectionsTableViewController.swift */,
|
||||||
|
4A8AABD720B6A79100B6D8C1 /* UITableView+WireGuard.swift */,
|
||||||
);
|
);
|
||||||
path = ViewControllers;
|
path = ViewControllers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -175,7 +178,7 @@
|
||||||
4A4BAD1E20B6026900F12B28 /* Interface+CoreDataProperties.swift */,
|
4A4BAD1E20B6026900F12B28 /* Interface+CoreDataProperties.swift */,
|
||||||
4A4BAD1820B5F8FF00F12B28 /* Profile+CoreDataClass.swift */,
|
4A4BAD1820B5F8FF00F12B28 /* Profile+CoreDataClass.swift */,
|
||||||
4A4BAD1920B5F8FF00F12B28 /* Profile+CoreDataProperties.swift */,
|
4A4BAD1920B5F8FF00F12B28 /* Profile+CoreDataProperties.swift */,
|
||||||
4A4BAD1520B5F8DE00F12B28 /* Wireguard.xcdatamodeld */,
|
4A4BAD1520B5F8DE00F12B28 /* WireGuard.xcdatamodeld */,
|
||||||
);
|
);
|
||||||
path = Models;
|
path = Models;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -393,7 +396,7 @@
|
||||||
4A4BAD2220B6026900F12B28 /* Interface+CoreDataProperties.swift in Sources */,
|
4A4BAD2220B6026900F12B28 /* Interface+CoreDataProperties.swift in Sources */,
|
||||||
4A7F6EDE20B674CD00B260B7 /* Address+CoreDataProperties.swift in Sources */,
|
4A7F6EDE20B674CD00B260B7 /* Address+CoreDataProperties.swift in Sources */,
|
||||||
4A4BAD1320B5F82400F12B28 /* Identifyable.swift in Sources */,
|
4A4BAD1320B5F82400F12B28 /* Identifyable.swift in Sources */,
|
||||||
4A4BAD1720B5F8DE00F12B28 /* Wireguard.xcdatamodeld in Sources */,
|
4A4BAD1720B5F8DE00F12B28 /* WireGuard.xcdatamodeld in Sources */,
|
||||||
4A4BAD1A20B5F8FF00F12B28 /* Profile+CoreDataClass.swift in Sources */,
|
4A4BAD1A20B5F8FF00F12B28 /* Profile+CoreDataClass.swift in Sources */,
|
||||||
4A4BACE820B5F1BF00F12B28 /* ConnectionsTableViewController.swift in Sources */,
|
4A4BACE820B5F1BF00F12B28 /* ConnectionsTableViewController.swift in Sources */,
|
||||||
4A4BAD1020B5F6EC00F12B28 /* RootCoordinator.swift in Sources */,
|
4A4BAD1020B5F6EC00F12B28 /* RootCoordinator.swift in Sources */,
|
||||||
|
@ -401,6 +404,7 @@
|
||||||
4A4BAD2020B6026900F12B28 /* Peer+CoreDataProperties.swift in Sources */,
|
4A4BAD2020B6026900F12B28 /* Peer+CoreDataProperties.swift in Sources */,
|
||||||
4A4BAD2320B6026900F12B28 /* Interface+CoreDataClass.swift in Sources */,
|
4A4BAD2320B6026900F12B28 /* Interface+CoreDataClass.swift in Sources */,
|
||||||
4A7F6EDD20B674CD00B260B7 /* Address+CoreDataClass.swift in Sources */,
|
4A7F6EDD20B674CD00B260B7 /* Address+CoreDataClass.swift in Sources */,
|
||||||
|
4A8AABD820B6A79100B6D8C1 /* UITableView+WireGuard.swift in Sources */,
|
||||||
4A4BAD2120B6026900F12B28 /* Peer+CoreDataClass.swift in Sources */,
|
4A4BAD2120B6026900F12B28 /* Peer+CoreDataClass.swift in Sources */,
|
||||||
4A4BAD1B20B5F8FF00F12B28 /* Profile+CoreDataProperties.swift in Sources */,
|
4A4BAD1B20B5F8FF00F12B28 /* Profile+CoreDataProperties.swift in Sources */,
|
||||||
4A4BACE620B5F1BF00F12B28 /* AppDelegate.swift in Sources */,
|
4A4BACE620B5F1BF00F12B28 /* AppDelegate.swift in Sources */,
|
||||||
|
@ -674,13 +678,13 @@
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCVersionGroup section */
|
/* Begin XCVersionGroup section */
|
||||||
4A4BAD1520B5F8DE00F12B28 /* Wireguard.xcdatamodeld */ = {
|
4A4BAD1520B5F8DE00F12B28 /* WireGuard.xcdatamodeld */ = {
|
||||||
isa = XCVersionGroup;
|
isa = XCVersionGroup;
|
||||||
children = (
|
children = (
|
||||||
4A4BAD1620B5F8DE00F12B28 /* Wireguard.xcdatamodel */,
|
4A4BAD1620B5F8DE00F12B28 /* WireGuard.xcdatamodel */,
|
||||||
);
|
);
|
||||||
currentVersion = 4A4BAD1620B5F8DE00F12B28 /* Wireguard.xcdatamodel */;
|
currentVersion = 4A4BAD1620B5F8DE00F12B28 /* WireGuard.xcdatamodel */;
|
||||||
path = Wireguard.xcdatamodeld;
|
path = WireGuard.xcdatamodeld;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
versionGroupType = wrapper.xcdatamodel;
|
versionGroupType = wrapper.xcdatamodel;
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,21 +9,30 @@
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<scenes>
|
<scenes>
|
||||||
<!--Connections Table View Controller-->
|
<!--Profiles-->
|
||||||
<scene sceneID="Tud-vM-cYZ">
|
<scene sceneID="Tud-vM-cYZ">
|
||||||
<objects>
|
<objects>
|
||||||
<tableViewController storyboardIdentifier="ConnectionsTableViewController" id="kTU-BV-32R" customClass="ConnectionsTableViewController" customModule="Wireguard" customModuleProvider="target" sceneMemberID="viewController">
|
<tableViewController storyboardIdentifier="ConnectionsTableViewController" id="kTU-BV-32R" customClass="ConnectionsTableViewController" customModule="WireGuard" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="AJg-r0-KJH">
|
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" id="AJg-r0-KJH">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" id="fM3-cC-KPN">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" accessoryType="detailDisclosureButton" indentationWidth="10" reuseIdentifier="ProfileTableViewCell" textLabel="hzX-lc-GyT" style="IBUITableViewCellStyleDefault" id="fM3-cC-KPN" customClass="ProfileTableViewCell" customModule="WireGuard" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="28" width="375" height="44"/>
|
<rect key="frame" x="0.0" y="28" width="375" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="fM3-cC-KPN" id="Rv6-XK-aK2">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="fM3-cC-KPN" id="Rv6-XK-aK2" customClass="ProfileTableViewCell" customModule="WireGuard" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="307" height="43.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="hzX-lc-GyT">
|
||||||
|
<rect key="frame" x="16" y="0.0" width="291" height="43.5"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
</subviews>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
</prototypes>
|
</prototypes>
|
||||||
|
@ -32,6 +41,14 @@
|
||||||
<outlet property="delegate" destination="kTU-BV-32R" id="b6T-ZR-cmO"/>
|
<outlet property="delegate" destination="kTU-BV-32R" id="b6T-ZR-cmO"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableView>
|
</tableView>
|
||||||
|
<navigationItem key="navigationItem" title="Profiles" id="j0L-5U-jDs">
|
||||||
|
<barButtonItem key="rightBarButtonItem" systemItem="add" id="h2H-H8-3Tn">
|
||||||
|
<connections>
|
||||||
|
<action selector="addProvider:" destination="kTU-BV-32R" id="xSg-ap-3Fx"/>
|
||||||
|
</connections>
|
||||||
|
</barButtonItem>
|
||||||
|
</navigationItem>
|
||||||
|
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
|
||||||
</tableViewController>
|
</tableViewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="4uZ-Vv-Fry" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="4uZ-Vv-Fry" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
|
|
|
@ -86,17 +86,21 @@ class AppCoordinator: RootViewCoordinator {
|
||||||
extension AppCoordinator: ConnectionsTableViewControllerDelegate {
|
extension AppCoordinator: ConnectionsTableViewControllerDelegate {
|
||||||
func addProvider(connectionsTableViewController: ConnectionsTableViewController) {
|
func addProvider(connectionsTableViewController: ConnectionsTableViewController) {
|
||||||
// TODO implement
|
// TODO implement
|
||||||
|
print("Add provider")
|
||||||
}
|
}
|
||||||
|
|
||||||
func settings(connectionsTableViewController: ConnectionsTableViewController) {
|
func connect(profile: Profile, connectionsTableViewController: ConnectionsTableViewController) {
|
||||||
// TODO implement
|
// TODO implement
|
||||||
|
print("connect profile \(profile)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func connect(profile: Profile) {
|
func configure(profile: Profile, connectionsTableViewController: ConnectionsTableViewController) {
|
||||||
// TODO implement
|
// TODO implement
|
||||||
|
print("configure profile \(profile)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func delete(profile: Profile) {
|
func delete(profile: Profile, connectionsTableViewController: ConnectionsTableViewController) {
|
||||||
// TODO implement
|
// TODO implement
|
||||||
|
print("delete profile \(profile)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,9 @@ import BNRCoreDataStack
|
||||||
|
|
||||||
protocol ConnectionsTableViewControllerDelegate: class {
|
protocol ConnectionsTableViewControllerDelegate: class {
|
||||||
func addProvider(connectionsTableViewController: ConnectionsTableViewController)
|
func addProvider(connectionsTableViewController: ConnectionsTableViewController)
|
||||||
func settings(connectionsTableViewController: ConnectionsTableViewController)
|
func connect(profile: Profile, connectionsTableViewController: ConnectionsTableViewController)
|
||||||
func connect(profile: Profile)
|
func configure(profile: Profile, connectionsTableViewController: ConnectionsTableViewController)
|
||||||
func delete(profile: Profile)
|
func delete(profile: Profile, connectionsTableViewController: ConnectionsTableViewController)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConnectionsTableViewController: UITableViewController {
|
class ConnectionsTableViewController: UITableViewController {
|
||||||
|
@ -23,16 +23,154 @@ class ConnectionsTableViewController: UITableViewController {
|
||||||
|
|
||||||
var viewContext: NSManagedObjectContext!
|
var viewContext: NSManagedObjectContext!
|
||||||
|
|
||||||
|
private lazy var fetchedResultsController: FetchedResultsController<Profile> = {
|
||||||
|
let fetchRequest = NSFetchRequest<Profile>()
|
||||||
|
fetchRequest.entity = Profile.entity()
|
||||||
|
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "title", ascending: true)]
|
||||||
|
let frc = FetchedResultsController<Profile>(fetchRequest: fetchRequest,
|
||||||
|
managedObjectContext: viewContext)
|
||||||
|
frc.setDelegate(self.frcDelegate)
|
||||||
|
return frc
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var frcDelegate: ProfileFetchedResultsControllerDelegate = { // swiftlint:disable:this weak_delegate
|
||||||
|
return ProfileFetchedResultsControllerDelegate(tableView: self.tableView)
|
||||||
|
}()
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
// Do any additional setup after loading the view, typically from a nib.
|
do {
|
||||||
|
try fetchedResultsController.performFetch()
|
||||||
|
} catch {
|
||||||
|
print("Failed to fetch objects: \(error)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func didReceiveMemoryWarning() {
|
@IBAction func addProvider(_ sender: Any) {
|
||||||
super.didReceiveMemoryWarning()
|
delegate?.addProvider(connectionsTableViewController: self)
|
||||||
// Dispose of any resources that can be recreated.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
|
return fetchedResultsController.sections?[0].objects.count ?? 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
|
let cell = tableView.dequeueReusableCell(type: ProfileTableViewCell.self, for: indexPath)
|
||||||
|
|
||||||
|
guard let sections = fetchedResultsController.sections else {
|
||||||
|
fatalError("FetchedResultsController \(fetchedResultsController) should have sections, but found nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
let section = sections[indexPath.section]
|
||||||
|
let profile = section.objects[indexPath.row]
|
||||||
|
|
||||||
|
cell.textLabel?.text = profile.title
|
||||||
|
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
guard let sections = fetchedResultsController.sections else {
|
||||||
|
fatalError("FetchedResultsController \(fetchedResultsController) should have sections, but found nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
let section = sections[indexPath.section]
|
||||||
|
let profile = section.objects[indexPath.row]
|
||||||
|
|
||||||
|
delegate?.connect(profile: profile, connectionsTableViewController: self)
|
||||||
|
|
||||||
|
tableView.deselectRow(at: indexPath, animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
|
||||||
|
guard let sections = fetchedResultsController.sections else {
|
||||||
|
fatalError("FetchedResultsController \(fetchedResultsController) should have sections, but found nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
let section = sections[indexPath.section]
|
||||||
|
let profile = section.objects[indexPath.row]
|
||||||
|
|
||||||
|
delegate?.configure(profile: profile, connectionsTableViewController: self)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
|
||||||
|
if editingStyle == .delete {
|
||||||
|
|
||||||
|
guard let sections = fetchedResultsController.sections else {
|
||||||
|
fatalError("FetchedResultsController \(fetchedResultsController) should have sections, but found nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
let section = sections[indexPath.section]
|
||||||
|
let profile = section.objects[indexPath.row]
|
||||||
|
|
||||||
|
delegate?.delete(profile: profile, connectionsTableViewController: self)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ConnectionsTableViewController: Identifyable {}
|
extension ConnectionsTableViewController: Identifyable {}
|
||||||
|
|
||||||
|
class ProfileFetchedResultsControllerDelegate: NSObject, FetchedResultsControllerDelegate {
|
||||||
|
|
||||||
|
private weak var tableView: UITableView?
|
||||||
|
|
||||||
|
// MARK: - Lifecycle
|
||||||
|
init(tableView: UITableView) {
|
||||||
|
self.tableView = tableView
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchedResultsControllerDidPerformFetch(_ controller: FetchedResultsController<Profile>) {
|
||||||
|
tableView?.reloadData()
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchedResultsControllerWillChangeContent(_ controller: FetchedResultsController<Profile>) {
|
||||||
|
tableView?.beginUpdates()
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchedResultsControllerDidChangeContent(_ controller: FetchedResultsController<Profile>) {
|
||||||
|
tableView?.endUpdates()
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchedResultsController(_ controller: FetchedResultsController<Profile>, didChangeObject change: FetchedResultsObjectChange<Profile>) {
|
||||||
|
guard let tableView = tableView else { return }
|
||||||
|
switch change {
|
||||||
|
case let .insert(_, indexPath):
|
||||||
|
tableView.insertRows(at: [indexPath], with: .automatic)
|
||||||
|
|
||||||
|
case let .delete(_, indexPath):
|
||||||
|
tableView.deleteRows(at: [indexPath], with: .automatic)
|
||||||
|
|
||||||
|
case let .move(_, fromIndexPath, toIndexPath):
|
||||||
|
tableView.moveRow(at: fromIndexPath, to: toIndexPath)
|
||||||
|
|
||||||
|
case let .update(_, indexPath):
|
||||||
|
tableView.reloadRows(at: [indexPath], with: .automatic)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchedResultsController(_ controller: FetchedResultsController<Profile>, didChangeSection change: FetchedResultsSectionChange<Profile>) {
|
||||||
|
guard let tableView = tableView else { return }
|
||||||
|
switch change {
|
||||||
|
case let .insert(_, index):
|
||||||
|
tableView.insertSections(IndexSet(integer: index), with: .automatic)
|
||||||
|
|
||||||
|
case let .delete(_, index):
|
||||||
|
tableView.deleteSections(IndexSet(integer: index), with: .automatic)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ProfileTableViewCell: UITableViewCell {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ProfileTableViewCell: Identifyable {}
|
||||||
|
|
Loading…
Reference in New Issue