Search plate numbers
This commit is contained in:
parent
cbace022ab
commit
6bf0ad8d12
@ -31,6 +31,9 @@
|
|||||||
7A11474923FF2B2D00B424AF /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A11474823FF2B2D00B424AF /* Response.swift */; };
|
7A11474923FF2B2D00B424AF /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A11474823FF2B2D00B424AF /* Response.swift */; };
|
||||||
7A11474B23FF368B00B424AF /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A11474A23FF368B00B424AF /* Settings.swift */; };
|
7A11474B23FF368B00B424AF /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A11474A23FF368B00B424AF /* Settings.swift */; };
|
||||||
7A11474E23FFEE8800B424AF /* SVProgressHUD.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A11474D23FFEE8800B424AF /* SVProgressHUD.framework */; };
|
7A11474E23FFEE8800B424AF /* SVProgressHUD.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A11474D23FFEE8800B424AF /* SVProgressHUD.framework */; };
|
||||||
|
7A3F07AB24360DC800E59687 /* Dated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AA24360DC800E59687 /* Dated.swift */; };
|
||||||
|
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AC2436350B00E59687 /* SearchController.swift */; };
|
||||||
|
7A3F07AF24366DF900E59687 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3F07AE24366DF900E59687 /* Filter.swift */; };
|
||||||
7A530B78240010D900CBFE6E /* InputMask in Frameworks */ = {isa = PBXBuildFile; productRef = 7A530B77240010D900CBFE6E /* InputMask */; };
|
7A530B78240010D900CBFE6E /* InputMask in Frameworks */ = {isa = PBXBuildFile; productRef = 7A530B77240010D900CBFE6E /* InputMask */; };
|
||||||
7A530B7A24001D3300CBFE6E /* CheckController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7924001D3300CBFE6E /* CheckController.swift */; };
|
7A530B7A24001D3300CBFE6E /* CheckController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7924001D3300CBFE6E /* CheckController.swift */; };
|
||||||
7A530B7E24017FEE00CBFE6E /* VehicleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */; };
|
7A530B7E24017FEE00CBFE6E /* VehicleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */; };
|
||||||
@ -71,6 +74,9 @@
|
|||||||
7A11474823FF2B2D00B424AF /* Response.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Response.swift; sourceTree = "<group>"; };
|
7A11474823FF2B2D00B424AF /* Response.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Response.swift; sourceTree = "<group>"; };
|
||||||
7A11474A23FF368B00B424AF /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
|
7A11474A23FF368B00B424AF /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
|
||||||
7A11474D23FFEE8800B424AF /* SVProgressHUD.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SVProgressHUD.framework; path = Carthage/Build/iOS/SVProgressHUD.framework; sourceTree = "<group>"; };
|
7A11474D23FFEE8800B424AF /* SVProgressHUD.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SVProgressHUD.framework; path = Carthage/Build/iOS/SVProgressHUD.framework; sourceTree = "<group>"; };
|
||||||
|
7A3F07AA24360DC800E59687 /* Dated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Dated.swift; sourceTree = "<group>"; };
|
||||||
|
7A3F07AC2436350B00E59687 /* SearchController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchController.swift; sourceTree = "<group>"; };
|
||||||
|
7A3F07AE24366DF900E59687 /* Filter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Filter.swift; sourceTree = "<group>"; };
|
||||||
7A530B7924001D3300CBFE6E /* CheckController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckController.swift; sourceTree = "<group>"; };
|
7A530B7924001D3300CBFE6E /* CheckController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckController.swift; sourceTree = "<group>"; };
|
||||||
7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleCell.swift; sourceTree = "<group>"; };
|
7A530B7D24017FEE00CBFE6E /* VehicleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleCell.swift; sourceTree = "<group>"; };
|
||||||
7A530B7F2401803A00CBFE6E /* Vehicle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Vehicle.swift; sourceTree = "<group>"; };
|
7A530B7F2401803A00CBFE6E /* Vehicle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Vehicle.swift; sourceTree = "<group>"; };
|
||||||
@ -137,6 +143,7 @@
|
|||||||
7A1146FF23FDE7E500B424AF /* AutoCat */ = {
|
7A1146FF23FDE7E500B424AF /* AutoCat */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
7A3F07A924360D9100E59687 /* Extensions */,
|
||||||
7A6DD90424326788009DE740 /* Fonts */,
|
7A6DD90424326788009DE740 /* Fonts */,
|
||||||
7A6DD901242BF48D009DE740 /* Views */,
|
7A6DD901242BF48D009DE740 /* Views */,
|
||||||
7A530B7C24017FBE00CBFE6E /* Cells */,
|
7A530B7C24017FBE00CBFE6E /* Cells */,
|
||||||
@ -162,6 +169,7 @@
|
|||||||
7A11471923FE839000B424AF /* AuthController.swift */,
|
7A11471923FE839000B424AF /* AuthController.swift */,
|
||||||
7A530B7924001D3300CBFE6E /* CheckController.swift */,
|
7A530B7924001D3300CBFE6E /* CheckController.swift */,
|
||||||
7AEFE727240455E200910EB7 /* SettingsController.swift */,
|
7AEFE727240455E200910EB7 /* SettingsController.swift */,
|
||||||
|
7A3F07AC2436350B00E59687 /* SearchController.swift */,
|
||||||
);
|
);
|
||||||
path = Controllers;
|
path = Controllers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -191,6 +199,7 @@
|
|||||||
7A530B7F2401803A00CBFE6E /* Vehicle.swift */,
|
7A530B7F2401803A00CBFE6E /* Vehicle.swift */,
|
||||||
7A0516192414FF0900FC55AC /* DateSection.swift */,
|
7A0516192414FF0900FC55AC /* DateSection.swift */,
|
||||||
7A6DD90D24337930009DE740 /* PlateNumber.swift */,
|
7A6DD90D24337930009DE740 /* PlateNumber.swift */,
|
||||||
|
7A3F07AE24366DF900E59687 /* Filter.swift */,
|
||||||
);
|
);
|
||||||
path = Models;
|
path = Models;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -204,6 +213,14 @@
|
|||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
7A3F07A924360D9100E59687 /* Extensions */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7A3F07AA24360DC800E59687 /* Dated.swift */,
|
||||||
|
);
|
||||||
|
path = Extensions;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
7A530B7C24017FBE00CBFE6E /* Cells */ = {
|
7A530B7C24017FBE00CBFE6E /* Cells */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -362,10 +379,12 @@
|
|||||||
7A530B802401803A00CBFE6E /* Vehicle.swift in Sources */,
|
7A530B802401803A00CBFE6E /* Vehicle.swift in Sources */,
|
||||||
7A11470123FDE7E500B424AF /* AppDelegate.swift in Sources */,
|
7A11470123FDE7E500B424AF /* AppDelegate.swift in Sources */,
|
||||||
7A6DD90824329144009DE740 /* CenterTextLayer.swift in Sources */,
|
7A6DD90824329144009DE740 /* CenterTextLayer.swift in Sources */,
|
||||||
|
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */,
|
||||||
7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */,
|
7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */,
|
||||||
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */,
|
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */,
|
||||||
7A6DD90E24337930009DE740 /* PlateNumber.swift in Sources */,
|
7A6DD90E24337930009DE740 /* PlateNumber.swift in Sources */,
|
||||||
7AEFE728240455E200910EB7 /* SettingsController.swift in Sources */,
|
7AEFE728240455E200910EB7 /* SettingsController.swift in Sources */,
|
||||||
|
7A3F07AB24360DC800E59687 /* Dated.swift in Sources */,
|
||||||
7A11474923FF2B2D00B424AF /* Response.swift in Sources */,
|
7A11474923FF2B2D00B424AF /* Response.swift in Sources */,
|
||||||
7A11471823FDEBFA00B424AF /* ReportController.swift in Sources */,
|
7A11471823FDEBFA00B424AF /* ReportController.swift in Sources */,
|
||||||
7A11471A23FE839000B424AF /* AuthController.swift in Sources */,
|
7A11471A23FE839000B424AF /* AuthController.swift in Sources */,
|
||||||
@ -382,6 +401,7 @@
|
|||||||
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */,
|
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */,
|
||||||
7A05161A2414FF0900FC55AC /* DateSection.swift in Sources */,
|
7A05161A2414FF0900FC55AC /* DateSection.swift in Sources */,
|
||||||
7A11474B23FF368B00B424AF /* Settings.swift in Sources */,
|
7A11474B23FF368B00B424AF /* Settings.swift in Sources */,
|
||||||
|
7A3F07AF24366DF900E59687 /* Filter.swift in Sources */,
|
||||||
7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */,
|
7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|||||||
@ -181,21 +181,84 @@
|
|||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="844" y="948.57571214392806"/>
|
<point key="canvasLocation" x="844" y="948.57571214392806"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--Search-->
|
<!--Search Controller-->
|
||||||
<scene sceneID="3Md-yW-a0R">
|
<scene sceneID="3Md-yW-a0R">
|
||||||
<objects>
|
<objects>
|
||||||
<viewController id="UPf-uT-oOr" sceneMemberID="viewController">
|
<viewController id="UPf-uT-oOr" customClass="SearchController" customModule="AutoCat" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<view key="view" contentMode="scaleToFill" id="IJP-gV-Ojc">
|
<view key="view" contentMode="scaleToFill" id="IJP-gV-Ojc">
|
||||||
<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"/>
|
||||||
|
<subviews>
|
||||||
|
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="dB3-iP-QRo">
|
||||||
|
<rect key="frame" x="0.0" y="44" width="375" height="574"/>
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||||
|
<prototypes>
|
||||||
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="VehicleCell" id="VEP-QD-i6y" customClass="VehicleCell" customModule="AutoCat" customModuleProvider="target">
|
||||||
|
<rect key="frame" x="0.0" y="28" width="375" height="85.5"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="VEP-QD-i6y" id="8hH-8I-XLB">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="85.5"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
<subviews>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Kia (JF) Optima" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="AQY-7N-q8D">
|
||||||
|
<rect key="frame" x="8" y="8" width="124" height="21.5"/>
|
||||||
|
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RPA-NR-0C6">
|
||||||
|
<rect key="frame" x="334" y="8" width="33" height="16"/>
|
||||||
|
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
|
||||||
|
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cvf-vM-QnT" customClass="PlateView" customModule="AutoCat" customModuleProvider="target">
|
||||||
|
<rect key="frame" x="8" y="37.5" width="317" height="40"/>
|
||||||
|
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstAttribute="height" constant="40" id="Xoz-Iw-PCU"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
</subviews>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="RPA-NR-0C6" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="AQY-7N-q8D" secondAttribute="trailing" constant="8" id="AB5-Fg-dMQ"/>
|
||||||
|
<constraint firstItem="AQY-7N-q8D" firstAttribute="top" secondItem="8hH-8I-XLB" secondAttribute="top" constant="8" id="FiA-ZH-YN0"/>
|
||||||
|
<constraint firstItem="RPA-NR-0C6" firstAttribute="top" secondItem="8hH-8I-XLB" secondAttribute="top" constant="8" id="JyS-ht-gyH"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="RPA-NR-0C6" secondAttribute="trailing" constant="8" id="Ki4-ca-I55"/>
|
||||||
|
<constraint firstAttribute="bottom" secondItem="cvf-vM-QnT" secondAttribute="bottom" constant="8" id="NoD-uC-htT"/>
|
||||||
|
<constraint firstItem="cvf-vM-QnT" firstAttribute="leading" secondItem="8hH-8I-XLB" secondAttribute="leading" constant="8" id="aO8-6i-9jc"/>
|
||||||
|
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="cvf-vM-QnT" secondAttribute="trailing" constant="8" id="ipf-aR-tuv"/>
|
||||||
|
<constraint firstItem="AQY-7N-q8D" firstAttribute="leading" secondItem="8hH-8I-XLB" secondAttribute="leading" constant="8" id="lJ4-uW-IwQ"/>
|
||||||
|
<constraint firstItem="cvf-vM-QnT" firstAttribute="top" secondItem="AQY-7N-q8D" secondAttribute="bottom" constant="8" id="qh7-O4-4d1"/>
|
||||||
|
</constraints>
|
||||||
|
</tableViewCellContentView>
|
||||||
|
<inset key="separatorInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="date" destination="RPA-NR-0C6" id="ih3-3R-Y8J"/>
|
||||||
|
<outlet property="name" destination="AQY-7N-q8D" id="hSi-Nh-mc2"/>
|
||||||
|
<outlet property="plate" destination="cvf-vM-QnT" id="8Bm-gA-bbm"/>
|
||||||
|
</connections>
|
||||||
|
</tableViewCell>
|
||||||
|
</prototypes>
|
||||||
|
</tableView>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="6Uh-9i-MKR" firstAttribute="bottom" secondItem="dB3-iP-QRo" secondAttribute="bottom" id="Qq7-Rm-AvA"/>
|
||||||
|
<constraint firstItem="dB3-iP-QRo" firstAttribute="top" secondItem="6Uh-9i-MKR" secondAttribute="top" id="SUK-IH-xTR"/>
|
||||||
|
<constraint firstItem="dB3-iP-QRo" firstAttribute="leading" secondItem="6Uh-9i-MKR" secondAttribute="leading" id="XTb-EI-bvm"/>
|
||||||
|
<constraint firstItem="dB3-iP-QRo" firstAttribute="trailing" secondItem="6Uh-9i-MKR" secondAttribute="trailing" id="w3e-Ir-qlo"/>
|
||||||
|
</constraints>
|
||||||
<viewLayoutGuide key="safeArea" id="6Uh-9i-MKR"/>
|
<viewLayoutGuide key="safeArea" id="6Uh-9i-MKR"/>
|
||||||
</view>
|
</view>
|
||||||
<tabBarItem key="tabBarItem" title="Search" image="magnifyingglass" catalog="system" id="gDG-z8-R0t"/>
|
<navigationItem key="navigationItem" id="kEp-Rw-7hu"/>
|
||||||
|
<connections>
|
||||||
|
<outlet property="tableView" destination="dB3-iP-QRo" id="b3n-R9-6lI"/>
|
||||||
|
</connections>
|
||||||
</viewController>
|
</viewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="xsk-7S-rvc" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="xsk-7S-rvc" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="3262" y="143"/>
|
<point key="canvasLocation" x="4200.8000000000002" y="142.57871064467767"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--Settings-->
|
<!--Settings-->
|
||||||
<scene sceneID="G47-o0-Caa">
|
<scene sceneID="G47-o0-Caa">
|
||||||
@ -354,7 +417,7 @@
|
|||||||
</tabBar>
|
</tabBar>
|
||||||
<connections>
|
<connections>
|
||||||
<segue destination="TSb-ZG-qfD" kind="relationship" relationship="viewControllers" id="Bwf-98-gjF"/>
|
<segue destination="TSb-ZG-qfD" kind="relationship" relationship="viewControllers" id="Bwf-98-gjF"/>
|
||||||
<segue destination="UPf-uT-oOr" kind="relationship" relationship="viewControllers" id="FGp-f6-fUh"/>
|
<segue destination="GCa-Re-j14" kind="relationship" relationship="viewControllers" id="FGp-f6-fUh"/>
|
||||||
<segue destination="4jU-Z3-PF2" kind="relationship" relationship="viewControllers" id="aH2-IT-86l"/>
|
<segue destination="4jU-Z3-PF2" kind="relationship" relationship="viewControllers" id="aH2-IT-86l"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tabBarController>
|
</tabBarController>
|
||||||
@ -485,6 +548,25 @@
|
|||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="844" y="1648"/>
|
<point key="canvasLocation" x="844" y="1648"/>
|
||||||
</scene>
|
</scene>
|
||||||
|
<!--Search-->
|
||||||
|
<scene sceneID="kiS-EQ-VFl">
|
||||||
|
<objects>
|
||||||
|
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="GCa-Re-j14" sceneMemberID="viewController">
|
||||||
|
<tabBarItem key="tabBarItem" title="Search" image="magnifyingglass" catalog="system" id="gDG-z8-R0t"/>
|
||||||
|
<toolbarItems/>
|
||||||
|
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="vdY-9n-hjX">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
|
||||||
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
|
</navigationBar>
|
||||||
|
<nil name="viewControllers"/>
|
||||||
|
<connections>
|
||||||
|
<segue destination="UPf-uT-oOr" kind="relationship" relationship="rootViewController" id="aun-Tj-SJT"/>
|
||||||
|
</connections>
|
||||||
|
</navigationController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="XQB-kc-hUv" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="3261.5999999999999" y="142.57871064467767"/>
|
||||||
|
</scene>
|
||||||
</scenes>
|
</scenes>
|
||||||
<resources>
|
<resources>
|
||||||
<image name="eye" catalog="system" width="128" height="81"/>
|
<image name="eye" catalog="system" width="128" height="81"/>
|
||||||
|
|||||||
@ -19,6 +19,8 @@ class CheckController: UIViewController, MaskedTextFieldDelegateListener {
|
|||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
guard let realm = try? Realm() else { return }
|
||||||
|
|
||||||
self.maskFieldDelegate.primaryMaskFormat = "[A][000][AA] [009]"
|
self.maskFieldDelegate.primaryMaskFormat = "[A][000][AA] [009]"
|
||||||
self.maskFieldDelegate.listener = self
|
self.maskFieldDelegate.listener = self
|
||||||
self.number.delegate = self.maskFieldDelegate
|
self.number.delegate = self.maskFieldDelegate
|
||||||
@ -41,34 +43,9 @@ class CheckController: UIViewController, MaskedTextFieldDelegateListener {
|
|||||||
.subscribe(onNext: self.updateDetailController(with:))
|
.subscribe(onNext: self.updateDetailController(with:))
|
||||||
.disposed(by: self.bag)
|
.disposed(by: self.bag)
|
||||||
|
|
||||||
let now = Date()
|
Observable.collection(from: realm.objects(Vehicle.self)
|
||||||
let monthStart = now.dateAtStartOf(.month)
|
.sorted(byKeyPath: "addedDate", ascending: false))
|
||||||
let realm = try! Realm()
|
.map { $0.groupedByDate() }
|
||||||
|
|
||||||
Observable.collection(from: realm.objects(Vehicle.self).sorted(byKeyPath: "addedDate", ascending: false)).map { (vehicles: Results<Vehicle>) -> [DateSection<Vehicle>] in
|
|
||||||
var sections: [TimeInterval: [Vehicle]] = [:]
|
|
||||||
for vehicle in vehicles {
|
|
||||||
let date = Date(timeIntervalSince1970: vehicle.addedDate/1000)
|
|
||||||
|
|
||||||
var key = date.dateAtStartOf(.day).timeIntervalSince1970
|
|
||||||
if date.isBeforeDate(monthStart, orEqual: false, granularity: .day) {
|
|
||||||
key = date.dateAtStartOf(.month).timeIntervalSince1970
|
|
||||||
}
|
|
||||||
|
|
||||||
if sections[key] == nil {
|
|
||||||
sections[key] = [vehicle]
|
|
||||||
} else {
|
|
||||||
sections[key]?.append(vehicle)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var sectionsArray: [DateSection<Vehicle>] = []
|
|
||||||
for (timestamp, vehicles) in sections {
|
|
||||||
sectionsArray.append(DateSection<Vehicle>(timestamp: timestamp, items: vehicles))
|
|
||||||
}
|
|
||||||
|
|
||||||
return sectionsArray.sorted { $0.timestamp > $1.timestamp }
|
|
||||||
}
|
|
||||||
.bind(to: self.history.rx.items(dataSource: ds))
|
.bind(to: self.history.rx.items(dataSource: ds))
|
||||||
.disposed(by: self.bag)
|
.disposed(by: self.bag)
|
||||||
}
|
}
|
||||||
@ -109,7 +86,6 @@ class CheckController: UIViewController, MaskedTextFieldDelegateListener {
|
|||||||
|
|
||||||
func textField(_ textField: UITextField, didFillMandatoryCharacters complete: Bool, didExtractValue value: String) {
|
func textField(_ textField: UITextField, didFillMandatoryCharacters complete: Bool, didExtractValue value: String) {
|
||||||
self.check.isEnabled = complete
|
self.check.isEnabled = complete
|
||||||
print(value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
|
||||||
|
|||||||
82
AutoCat/Controllers/SearchController.swift
Normal file
82
AutoCat/Controllers/SearchController.swift
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import UIKit
|
||||||
|
import RxDataSources
|
||||||
|
import RxSwift
|
||||||
|
import RxCocoa
|
||||||
|
|
||||||
|
class SearchController: UIViewController, UISearchResultsUpdating {
|
||||||
|
|
||||||
|
@IBOutlet weak var tableView: UITableView!
|
||||||
|
|
||||||
|
let bag = DisposeBag()
|
||||||
|
let searchController = UISearchController(searchResultsController: nil)
|
||||||
|
|
||||||
|
var filterRelay = BehaviorRelay<Filter>(value: Filter())
|
||||||
|
var filter = Filter()
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
searchController.searchResultsUpdater = self
|
||||||
|
searchController.obscuresBackgroundDuringPresentation = false
|
||||||
|
searchController.searchBar.placeholder = "Search plate numbers"
|
||||||
|
navigationItem.searchController = searchController
|
||||||
|
definesPresentationContext = true
|
||||||
|
|
||||||
|
let ds = RxTableViewSectionedAnimatedDataSource<DateSection<Vehicle>>(configureCell: { dataSource, tableView, indexPath, item in
|
||||||
|
if let cell = tableView.dequeueReusableCell(withIdentifier: "VehicleCell", for: indexPath) as? VehicleCell {
|
||||||
|
cell.configure(with: item)
|
||||||
|
return cell
|
||||||
|
} else {
|
||||||
|
return UITableViewCell()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
ds.titleForHeaderInSection = { dataSourse, index in
|
||||||
|
return dataSourse.sectionModels[index].header
|
||||||
|
}
|
||||||
|
|
||||||
|
self.tableView.rx.modelSelected(Vehicle.self)
|
||||||
|
.subscribe(onNext: self.updateDetailController(with:))
|
||||||
|
.disposed(by: self.bag)
|
||||||
|
|
||||||
|
self.filterRelay
|
||||||
|
//.throttle(.seconds(2), scheduler: MainScheduler.instance)
|
||||||
|
.debounce(.milliseconds(500), scheduler: MainScheduler.instance)
|
||||||
|
.flatMap(Api.getVehicles)
|
||||||
|
.observeOn(MainScheduler.instance)
|
||||||
|
.do(onNext: { self.navigationItem.title = "\($0.count) vehicles found" })
|
||||||
|
.map { $0.groupedByDate() }
|
||||||
|
.bind(to: self.tableView.rx.items(dataSource: ds))
|
||||||
|
.disposed(by: self.bag)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Code duplication
|
||||||
|
func updateDetailController(with vehicle: Vehicle) {
|
||||||
|
if let splitViewController = self.view.window?.rootViewController as? UISplitViewController
|
||||||
|
{
|
||||||
|
var detail: ReportController?
|
||||||
|
if splitViewController.viewControllers.count == 2 {
|
||||||
|
detail = splitViewController.viewControllers.last as? ReportController
|
||||||
|
} else {
|
||||||
|
let storyboard = UIStoryboard(name: "Main", bundle: nil)
|
||||||
|
detail = storyboard.instantiateViewController(identifier: "ReportController")
|
||||||
|
}
|
||||||
|
|
||||||
|
if let detail = detail {
|
||||||
|
detail.vehicle = vehicle
|
||||||
|
splitViewController.showDetailViewController(detail, sender: self)
|
||||||
|
//self.performSegue(withIdentifier: "OpenDetailSegue", sender: self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - UISearchResultsUpdating
|
||||||
|
|
||||||
|
func updateSearchResults(for searchController: UISearchController) {
|
||||||
|
let newQuery = searchController.searchBar.text?.uppercased() ?? ""
|
||||||
|
guard self.filter.searchString != newQuery else { return }
|
||||||
|
|
||||||
|
self.filter.searchString = newQuery
|
||||||
|
self.filterRelay.accept(self.filter)
|
||||||
|
}
|
||||||
|
}
|
||||||
40
AutoCat/Extensions/Dated.swift
Normal file
40
AutoCat/Extensions/Dated.swift
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import Foundation
|
||||||
|
import RxDataSources
|
||||||
|
import SwiftDate
|
||||||
|
|
||||||
|
protocol Dated {
|
||||||
|
var date: Date { get }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Vehicle: Dated {
|
||||||
|
var date: Date {
|
||||||
|
Date(timeIntervalSince1970: self.addedDate/1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension RandomAccessCollection where Element: Dated & IdentifiableType & Equatable {
|
||||||
|
func groupedByDate() -> [DateSection<Element>] {
|
||||||
|
let now = Date()
|
||||||
|
let monthStart = now.dateAtStartOf(.month)
|
||||||
|
var sections: [TimeInterval: [Element]] = [:]
|
||||||
|
for vehicle in self {
|
||||||
|
var key = vehicle.date.dateAtStartOf(.day).timeIntervalSince1970
|
||||||
|
if vehicle.date.isBeforeDate(monthStart, orEqual: false, granularity: .day) {
|
||||||
|
key = vehicle.date.dateAtStartOf(.month).timeIntervalSince1970
|
||||||
|
}
|
||||||
|
|
||||||
|
if sections[key] == nil {
|
||||||
|
sections[key] = [vehicle]
|
||||||
|
} else {
|
||||||
|
sections[key]?.append(vehicle)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var sectionsArray: [DateSection<Element>] = []
|
||||||
|
for (timestamp, vehicles) in sections {
|
||||||
|
sectionsArray.append(DateSection<Element>(timestamp: timestamp, items: vehicles))
|
||||||
|
}
|
||||||
|
|
||||||
|
return sectionsArray.sorted { $0.timestamp > $1.timestamp }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -27,7 +27,6 @@ struct DateSection<T>: AnimatableSectionModelType where T: IdentifiableType, T:
|
|||||||
let weekStart = now.dateAtStartOf(.weekOfMonth)
|
let weekStart = now.dateAtStartOf(.weekOfMonth)
|
||||||
|
|
||||||
let date = Date(timeIntervalSince1970: timestamp)
|
let date = Date(timeIntervalSince1970: timestamp)
|
||||||
print("Date: \(date)")
|
|
||||||
if date.isToday {
|
if date.isToday {
|
||||||
self.header = "Today"
|
self.header = "Today"
|
||||||
}
|
}
|
||||||
|
|||||||
5
AutoCat/Models/Filter.swift
Normal file
5
AutoCat/Models/Filter.swift
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct Filter {
|
||||||
|
var searchString = ""
|
||||||
|
}
|
||||||
@ -8,23 +8,27 @@ class Api {
|
|||||||
return NSError(domain: "", code: code, userInfo: [NSLocalizedDescriptionKey: msg, NSLocalizedRecoverySuggestionErrorKey: suggestion])
|
return NSError(domain: "", code: code, userInfo: [NSLocalizedDescriptionKey: msg, NSLocalizedRecoverySuggestionErrorKey: suggestion])
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func createRequest(api: String, method: String, body: [String: Any]? = nil) -> URLRequest? {
|
private static func createRequest<T>(api: String, method: String, body: [String: T]? = nil) -> URLRequest? where T: LosslessStringConvertible {
|
||||||
guard let url = URL(string: baseUrl + api) else { return nil }
|
guard var urlComponents = URLComponents(string: baseUrl + api) else { return nil }
|
||||||
|
|
||||||
var request = URLRequest(url: url)
|
if let body = body, method.uppercased() == "GET" {
|
||||||
|
urlComponents.queryItems = body.map { URLQueryItem(name: $0, value: String($1)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
var request = URLRequest(url: urlComponents.url!)
|
||||||
request.httpMethod = method
|
request.httpMethod = method
|
||||||
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||||
request.addValue("application/json", forHTTPHeaderField: "Accept")
|
request.addValue("application/json", forHTTPHeaderField: "Accept")
|
||||||
request.addValue("Bearer " + Settings.shared.user.token, forHTTPHeaderField: "Authorization")
|
request.addValue("Bearer " + Settings.shared.user.token, forHTTPHeaderField: "Authorization")
|
||||||
|
|
||||||
if let body = body {
|
if let body = body, method.uppercased() != "GET" {
|
||||||
request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .prettyPrinted)
|
request.httpBody = try? JSONSerialization.data(withJSONObject: body, options: .prettyPrinted)
|
||||||
}
|
}
|
||||||
|
|
||||||
return request
|
return request
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func makeRequest<T>(api: String, method: String, body: [String: Any]? = nil) -> Observable<T> where T: Decodable {
|
private static func makeRequest<T, U>(api: String, method: String, body: [String: U]? = nil) -> Observable<T> where T: Decodable, U: LosslessStringConvertible {
|
||||||
guard let request = self.createRequest(api: api, method: method, body: body) else {
|
guard let request = self.createRequest(api: api, method: method, body: body) else {
|
||||||
return Observable.error(self.genError("Error creating request", suggestion: ""))
|
return Observable.error(self.genError("Error creating request", suggestion: ""))
|
||||||
}
|
}
|
||||||
@ -59,8 +63,12 @@ class Api {
|
|||||||
return self.makeRequest(api: "user/signup", method: "POST", body: body)
|
return self.makeRequest(api: "user/signup", method: "POST", body: body)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func getVehicles() -> Observable<[Vehicle]> {
|
public static func getVehicles(with filter: Filter) -> Observable<[Vehicle]> {
|
||||||
return self.makeRequest(api: "vehicles", method: "GET")
|
let body = [
|
||||||
|
"limit": "0", // Unlimited
|
||||||
|
"query": filter.searchString
|
||||||
|
]
|
||||||
|
return self.makeRequest(api: "vehicles", method: "GET", body: body)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func checkVehicle(by number: String) -> Observable<Vehicle> {
|
public static func checkVehicle(by number: String) -> Observable<Vehicle> {
|
||||||
|
|||||||
@ -8,7 +8,6 @@ class FlagLayer: CALayer {
|
|||||||
let red = CGColor(srgbRed: 213/256.0, green: 43/256.0, blue: 30/256.0, alpha: 1)
|
let red = CGColor(srgbRed: 213/256.0, green: 43/256.0, blue: 30/256.0, alpha: 1)
|
||||||
|
|
||||||
override func draw(in ctx: CGContext) {
|
override func draw(in ctx: CGContext) {
|
||||||
print("Draw in bounds: \(bounds)")
|
|
||||||
ctx.saveGState()
|
ctx.saveGState()
|
||||||
super.draw(in: ctx)
|
super.draw(in: ctx)
|
||||||
|
|
||||||
|
|||||||
@ -14,8 +14,17 @@ class PlateView: UIView {
|
|||||||
private var countryLayer = CenterTextLayer()
|
private var countryLayer = CenterTextLayer()
|
||||||
private var flagLayer = FlagLayer()
|
private var flagLayer = FlagLayer()
|
||||||
|
|
||||||
var number: PlateNumber?
|
var number: PlateNumber? {
|
||||||
var unrecognized: Bool = false
|
didSet {
|
||||||
|
self.layoutSubviews()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var unrecognized: Bool = false {
|
||||||
|
didSet {
|
||||||
|
self.layoutSubviews()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
super.init(coder: coder)
|
super.init(coder: coder)
|
||||||
@ -63,8 +72,6 @@ class PlateView: UIView {
|
|||||||
|
|
||||||
let fgColor = self.unrecognized ? /*fgColorErr*/UIColor.systemRed.cgColor : fgColorMain
|
let fgColor = self.unrecognized ? /*fgColorErr*/UIColor.systemRed.cgColor : fgColorMain
|
||||||
|
|
||||||
print("Layout for number: \(number.asString())")
|
|
||||||
|
|
||||||
self.bgLayer.backgroundColor = fgColor
|
self.bgLayer.backgroundColor = fgColor
|
||||||
self.bgLayer.frame = self.bounds
|
self.bgLayer.frame = self.bounds
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user