Adding number with puller instead of old textfield
This commit is contained in:
parent
512a50b217
commit
1d377b8faa
@ -84,6 +84,14 @@
|
|||||||
7AABDE26253350C30041AFC6 /* RxSectionedDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AABDE25253350C30041AFC6 /* RxSectionedDataSource.swift */; };
|
7AABDE26253350C30041AFC6 /* RxSectionedDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AABDE25253350C30041AFC6 /* RxSectionedDataSource.swift */; };
|
||||||
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB67E8B2435C38700258F61 /* CustomTextField.swift */; };
|
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB67E8B2435C38700258F61 /* CustomTextField.swift */; };
|
||||||
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB67E8D2435D1A000258F61 /* CustomButton.swift */; };
|
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB67E8D2435D1A000258F61 /* CustomButton.swift */; };
|
||||||
|
7AC3554A2969652F00889457 /* SwiftEntryKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7AC355492969652F00889457 /* SwiftEntryKit */; };
|
||||||
|
7AC3554C29696A1C00889457 /* MainTabController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC3554B29696A1C00889457 /* MainTabController.swift */; };
|
||||||
|
7AC3554E29696C4500889457 /* DummyNewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC3554D29696C4500889457 /* DummyNewController.swift */; };
|
||||||
|
7AC3555029696D5A00889457 /* NewNumberController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC3554F29696D5A00889457 /* NewNumberController.swift */; };
|
||||||
|
7AC3555229696E3F00889457 /* UIView+layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC3555129696E3F00889457 /* UIView+layout.swift */; };
|
||||||
|
7AC35554296973E100889457 /* ACButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC35553296973E100889457 /* ACButton.swift */; };
|
||||||
|
7AC355592969746600889457 /* UIControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC355582969746600889457 /* UIControl.swift */; };
|
||||||
|
7AC3555B296995B200889457 /* UIEdgeInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC3555A296995B200889457 /* UIEdgeInsets.swift */; };
|
||||||
7AC76D7B270083AE0084DB27 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC76D7A270083AE0084DB27 /* TextView.swift */; };
|
7AC76D7B270083AE0084DB27 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC76D7A270083AE0084DB27 /* TextView.swift */; };
|
||||||
7ADF6C93250B954900F237B2 /* Navigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADF6C92250B954900F237B2 /* Navigation.swift */; };
|
7ADF6C93250B954900F237B2 /* Navigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADF6C92250B954900F237B2 /* Navigation.swift */; };
|
||||||
7ADF6C95250D037700F237B2 /* ShowEventController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADF6C94250D037700F237B2 /* ShowEventController.swift */; };
|
7ADF6C95250D037700F237B2 /* ShowEventController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADF6C94250D037700F237B2 /* ShowEventController.swift */; };
|
||||||
@ -251,6 +259,13 @@
|
|||||||
7AB562B9249C9E9B00473D53 /* VehicleRegion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleRegion.swift; sourceTree = "<group>"; };
|
7AB562B9249C9E9B00473D53 /* VehicleRegion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleRegion.swift; sourceTree = "<group>"; };
|
||||||
7AB67E8B2435C38700258F61 /* CustomTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextField.swift; sourceTree = "<group>"; };
|
7AB67E8B2435C38700258F61 /* CustomTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomTextField.swift; sourceTree = "<group>"; };
|
||||||
7AB67E8D2435D1A000258F61 /* CustomButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomButton.swift; sourceTree = "<group>"; };
|
7AB67E8D2435D1A000258F61 /* CustomButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomButton.swift; sourceTree = "<group>"; };
|
||||||
|
7AC3554B29696A1C00889457 /* MainTabController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabController.swift; sourceTree = "<group>"; };
|
||||||
|
7AC3554D29696C4500889457 /* DummyNewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DummyNewController.swift; sourceTree = "<group>"; };
|
||||||
|
7AC3554F29696D5A00889457 /* NewNumberController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewNumberController.swift; sourceTree = "<group>"; };
|
||||||
|
7AC3555129696E3F00889457 /* UIView+layout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+layout.swift"; sourceTree = "<group>"; };
|
||||||
|
7AC35553296973E100889457 /* ACButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACButton.swift; sourceTree = "<group>"; };
|
||||||
|
7AC355582969746600889457 /* UIControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIControl.swift; sourceTree = "<group>"; };
|
||||||
|
7AC3555A296995B200889457 /* UIEdgeInsets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIEdgeInsets.swift; sourceTree = "<group>"; };
|
||||||
7AC76D7A270083AE0084DB27 /* TextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = "<group>"; };
|
7AC76D7A270083AE0084DB27 /* TextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = "<group>"; };
|
||||||
7ADF6C92250B954900F237B2 /* Navigation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Navigation.swift; sourceTree = "<group>"; };
|
7ADF6C92250B954900F237B2 /* Navigation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Navigation.swift; sourceTree = "<group>"; };
|
||||||
7ADF6C94250D037700F237B2 /* ShowEventController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowEventController.swift; sourceTree = "<group>"; };
|
7ADF6C94250D037700F237B2 /* ShowEventController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowEventController.swift; sourceTree = "<group>"; };
|
||||||
@ -285,6 +300,7 @@
|
|||||||
7AA7BC3325A5DFB80053A5D5 /* Kingfisher in Frameworks */,
|
7AA7BC3325A5DFB80053A5D5 /* Kingfisher in Frameworks */,
|
||||||
7A813DBE2506A57100CC93B9 /* AuthenticationServices.framework in Frameworks */,
|
7A813DBE2506A57100CC93B9 /* AuthenticationServices.framework in Frameworks */,
|
||||||
7AA7BC3625A5DFB80053A5D5 /* PKHUD in Frameworks */,
|
7AA7BC3625A5DFB80053A5D5 /* PKHUD in Frameworks */,
|
||||||
|
7AC3554A2969652F00889457 /* SwiftEntryKit in Frameworks */,
|
||||||
7AF6D2042677C03B0086EA64 /* AutoCatCore.framework in Frameworks */,
|
7AF6D2042677C03B0086EA64 /* AutoCatCore.framework in Frameworks */,
|
||||||
7A35177B27E23F8800DC538C /* Eureka in Frameworks */,
|
7A35177B27E23F8800DC538C /* Eureka in Frameworks */,
|
||||||
7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */,
|
7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */,
|
||||||
@ -368,6 +384,7 @@
|
|||||||
7A1146FF23FDE7E500B424AF /* AutoCat */ = {
|
7A1146FF23FDE7E500B424AF /* AutoCat */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
7AC355552969742800889457 /* ACUIKit */,
|
||||||
7A530B7C24017FBE00CBFE6E /* Cells */,
|
7A530B7C24017FBE00CBFE6E /* Cells */,
|
||||||
7A11471423FDEAF800B424AF /* Controllers */,
|
7A11471423FDEAF800B424AF /* Controllers */,
|
||||||
7A3F07A924360D9100E59687 /* Extensions */,
|
7A3F07A924360D9100E59687 /* Extensions */,
|
||||||
@ -408,6 +425,9 @@
|
|||||||
7A3F07AC2436350B00E59687 /* SearchController.swift */,
|
7A3F07AC2436350B00E59687 /* SearchController.swift */,
|
||||||
7AEFE727240455E200910EB7 /* SettingsController.swift */,
|
7AEFE727240455E200910EB7 /* SettingsController.swift */,
|
||||||
7A6F095D26DB9F85003A965D /* NotesController.swift */,
|
7A6F095D26DB9F85003A965D /* NotesController.swift */,
|
||||||
|
7AC3554B29696A1C00889457 /* MainTabController.swift */,
|
||||||
|
7AC3554D29696C4500889457 /* DummyNewController.swift */,
|
||||||
|
7AC3554F29696D5A00889457 /* NewNumberController.swift */,
|
||||||
);
|
);
|
||||||
path = Controllers;
|
path = Controllers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -558,6 +578,33 @@
|
|||||||
path = Location;
|
path = Location;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
7AC355552969742800889457 /* ACUIKit */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7AC355562969743800889457 /* Views */,
|
||||||
|
7AC355572969744100889457 /* Extensions */,
|
||||||
|
);
|
||||||
|
path = ACUIKit;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
7AC355562969743800889457 /* Views */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7AC35553296973E100889457 /* ACButton.swift */,
|
||||||
|
);
|
||||||
|
path = Views;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
7AC355572969744100889457 /* Extensions */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7AC3555129696E3F00889457 /* UIView+layout.swift */,
|
||||||
|
7AC355582969746600889457 /* UIControl.swift */,
|
||||||
|
7AC3555A296995B200889457 /* UIEdgeInsets.swift */,
|
||||||
|
);
|
||||||
|
path = Extensions;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
7AF6D1DE2677A7E00086EA64 /* AutoCatTests */ = {
|
7AF6D1DE2677A7E00086EA64 /* AutoCatTests */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -642,6 +689,7 @@
|
|||||||
7A813DC02508C4D900CC93B9 /* ExceptionCatcher */,
|
7A813DC02508C4D900CC93B9 /* ExceptionCatcher */,
|
||||||
7AABDE1C2532F3EB0041AFC6 /* PKHUD */,
|
7AABDE1C2532F3EB0041AFC6 /* PKHUD */,
|
||||||
7A35177A27E23F8800DC538C /* Eureka */,
|
7A35177A27E23F8800DC538C /* Eureka */,
|
||||||
|
7AC355492969652F00889457 /* SwiftEntryKit */,
|
||||||
);
|
);
|
||||||
productName = AutoCat;
|
productName = AutoCat;
|
||||||
productReference = 7A1146FD23FDE7E500B424AF /* AutoCat.app */;
|
productReference = 7A1146FD23FDE7E500B424AF /* AutoCat.app */;
|
||||||
@ -734,6 +782,7 @@
|
|||||||
7AABDE1B2532F3EB0041AFC6 /* XCRemoteSwiftPackageReference "PKHUD" */,
|
7AABDE1B2532F3EB0041AFC6 /* XCRemoteSwiftPackageReference "PKHUD" */,
|
||||||
7AABDE21253327F10041AFC6 /* XCRemoteSwiftPackageReference "DifferenceKit" */,
|
7AABDE21253327F10041AFC6 /* XCRemoteSwiftPackageReference "DifferenceKit" */,
|
||||||
7A35177927E23F8800DC538C /* XCRemoteSwiftPackageReference "Eureka" */,
|
7A35177927E23F8800DC538C /* XCRemoteSwiftPackageReference "Eureka" */,
|
||||||
|
7AC355482969652F00889457 /* XCRemoteSwiftPackageReference "SwiftEntryKit" */,
|
||||||
);
|
);
|
||||||
productRefGroup = 7A1146FE23FDE7E500B424AF /* Products */;
|
productRefGroup = 7A1146FE23FDE7E500B424AF /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
@ -792,12 +841,14 @@
|
|||||||
7A6DD90824329144009DE740 /* CenterTextLayer.swift in Sources */,
|
7A6DD90824329144009DE740 /* CenterTextLayer.swift in Sources */,
|
||||||
7A99406426E4BFAE002E9CB6 /* VehicleNoteCell.swift in Sources */,
|
7A99406426E4BFAE002E9CB6 /* VehicleNoteCell.swift in Sources */,
|
||||||
7A8AB76B25A1D95500ECF2C1 /* SourceStatusRow.swift in Sources */,
|
7A8AB76B25A1D95500ECF2C1 /* SourceStatusRow.swift in Sources */,
|
||||||
|
7AC3554C29696A1C00889457 /* MainTabController.swift in Sources */,
|
||||||
7A813DC32508EE4F00CC93B9 /* EventCell.swift in Sources */,
|
7A813DC32508EE4F00CC93B9 /* EventCell.swift in Sources */,
|
||||||
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */,
|
7A3F07AD2436350B00E59687 /* SearchController.swift in Sources */,
|
||||||
7AABDE26253350C30041AFC6 /* RxSectionedDataSource.swift in Sources */,
|
7AABDE26253350C30041AFC6 /* RxSectionedDataSource.swift in Sources */,
|
||||||
7A0B96A0257D6D4B000B39AD /* MultilineLabelRow.swift in Sources */,
|
7A0B96A0257D6D4B000B39AD /* MultilineLabelRow.swift in Sources */,
|
||||||
7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */,
|
7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */,
|
||||||
7A761C0B267E8FF90005F28F /* Error.swift in Sources */,
|
7A761C0B267E8FF90005F28F /* Error.swift in Sources */,
|
||||||
|
7AC3555029696D5A00889457 /* NewNumberController.swift in Sources */,
|
||||||
7AE26A3524F31B0700625033 /* EventsController.swift in Sources */,
|
7AE26A3524F31B0700625033 /* EventsController.swift in Sources */,
|
||||||
7A2DE69E2589606A00A113FC /* ImageGridRow.swift in Sources */,
|
7A2DE69E2589606A00A113FC /* ImageGridRow.swift in Sources */,
|
||||||
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */,
|
7AB67E8C2435C38700258F61 /* CustomTextField.swift in Sources */,
|
||||||
@ -808,6 +859,7 @@
|
|||||||
7A27ADF3249F8B650035F39E /* RecordsController.swift in Sources */,
|
7A27ADF3249F8B650035F39E /* RecordsController.swift in Sources */,
|
||||||
7A8A2209248D10EC0073DFD9 /* ResizeImage.swift in Sources */,
|
7A8A2209248D10EC0073DFD9 /* ResizeImage.swift in Sources */,
|
||||||
7ADF6CA12512244400F237B2 /* MapExt.swift in Sources */,
|
7ADF6CA12512244400F237B2 /* MapExt.swift in Sources */,
|
||||||
|
7AC3554E29696C4500889457 /* DummyNewController.swift in Sources */,
|
||||||
7A659B5B24A3768A0043A0F2 /* Substrings.swift in Sources */,
|
7A659B5B24A3768A0043A0F2 /* Substrings.swift in Sources */,
|
||||||
7AEFE728240455E200910EB7 /* SettingsController.swift in Sources */,
|
7AEFE728240455E200910EB7 /* SettingsController.swift in Sources */,
|
||||||
7A27ADF7249FEF690035F39E /* Recorder.swift in Sources */,
|
7A27ADF7249FEF690035F39E /* Recorder.swift in Sources */,
|
||||||
@ -836,10 +888,14 @@
|
|||||||
7A813DCB250B5DC900CC93B9 /* LocationPickerController.swift in Sources */,
|
7A813DCB250B5DC900CC93B9 /* LocationPickerController.swift in Sources */,
|
||||||
7A9FEEC82529AB23001CA50E /* RxRealmDataSource.swift in Sources */,
|
7A9FEEC82529AB23001CA50E /* RxRealmDataSource.swift in Sources */,
|
||||||
7A8AB76525A0DB8F00ECF2C1 /* BundleVersion.swift in Sources */,
|
7A8AB76525A0DB8F00ECF2C1 /* BundleVersion.swift in Sources */,
|
||||||
|
7AC3555229696E3F00889457 /* UIView+layout.swift in Sources */,
|
||||||
7A0420AD2561A0B100034941 /* OsagoController.swift in Sources */,
|
7A0420AD2561A0B100034941 /* OsagoController.swift in Sources */,
|
||||||
|
7AC355592969746600889457 /* UIControl.swift in Sources */,
|
||||||
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */,
|
7AB67E8E2435D1A000258F61 /* CustomButton.swift in Sources */,
|
||||||
7A21112A24FC3D7E003BBF6F /* AudioEngine.swift in Sources */,
|
7A21112A24FC3D7E003BBF6F /* AudioEngine.swift in Sources */,
|
||||||
|
7AC35554296973E100889457 /* ACButton.swift in Sources */,
|
||||||
7A8A220B248D67B60073DFD9 /* VehicleReportImage.swift in Sources */,
|
7A8A220B248D67B60073DFD9 /* VehicleReportImage.swift in Sources */,
|
||||||
|
7AC3555B296995B200889457 /* UIEdgeInsets.swift in Sources */,
|
||||||
7ADF6C95250D037700F237B2 /* ShowEventController.swift in Sources */,
|
7ADF6C95250D037700F237B2 /* ShowEventController.swift in Sources */,
|
||||||
7A27ADC7249D43210035F39E /* RegionsController.swift in Sources */,
|
7A27ADC7249D43210035F39E /* RegionsController.swift in Sources */,
|
||||||
7AE492A1259232F000322D2E /* MultilineLinkRow.swift in Sources */,
|
7AE492A1259232F000322D2E /* MultilineLinkRow.swift in Sources */,
|
||||||
@ -1080,7 +1136,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 100;
|
CURRENT_PROJECT_VERSION = 101;
|
||||||
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
||||||
INFOPLIST_FILE = AutoCat/Info.plist;
|
INFOPLIST_FILE = AutoCat/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
@ -1105,7 +1161,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 100;
|
CURRENT_PROJECT_VERSION = 101;
|
||||||
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
DEVELOPMENT_TEAM = 46DTTB8X4S;
|
||||||
INFOPLIST_FILE = AutoCat/Info.plist;
|
INFOPLIST_FILE = AutoCat/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
@ -1329,6 +1385,14 @@
|
|||||||
minimumVersion = 1.1.5;
|
minimumVersion = 1.1.5;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
7AC355482969652F00889457 /* XCRemoteSwiftPackageReference "SwiftEntryKit" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/huri000/SwiftEntryKit";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 2.0.0;
|
||||||
|
};
|
||||||
|
};
|
||||||
7AF58D322402A91C00CE01A0 /* XCRemoteSwiftPackageReference "Kingfisher" */ = {
|
7AF58D322402A91C00CE01A0 /* XCRemoteSwiftPackageReference "Kingfisher" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/onevcat/Kingfisher";
|
repositoryURL = "https://github.com/onevcat/Kingfisher";
|
||||||
@ -1380,6 +1444,11 @@
|
|||||||
package = 7AABDE1B2532F3EB0041AFC6 /* XCRemoteSwiftPackageReference "PKHUD" */;
|
package = 7AABDE1B2532F3EB0041AFC6 /* XCRemoteSwiftPackageReference "PKHUD" */;
|
||||||
productName = PKHUD;
|
productName = PKHUD;
|
||||||
};
|
};
|
||||||
|
7AC355492969652F00889457 /* SwiftEntryKit */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 7AC355482969652F00889457 /* XCRemoteSwiftPackageReference "SwiftEntryKit" */;
|
||||||
|
productName = SwiftEntryKit;
|
||||||
|
};
|
||||||
7AF58D332402A91C00CE01A0 /* Kingfisher */ = {
|
7AF58D332402A91C00CE01A0 /* Kingfisher */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = 7AF58D322402A91C00CE01A0 /* XCRemoteSwiftPackageReference "Kingfisher" */;
|
package = 7AF58D322402A91C00CE01A0 /* XCRemoteSwiftPackageReference "Kingfisher" */;
|
||||||
|
|||||||
@ -89,6 +89,15 @@
|
|||||||
"revision" : "6190d0cefff3013e77ed567e6b074f324e5c5bf5",
|
"revision" : "6190d0cefff3013e77ed567e6b074f324e5c5bf5",
|
||||||
"version" : "6.3.1"
|
"version" : "6.3.1"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "swiftentrykit",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/huri000/SwiftEntryKit",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "5ad36cccf0c4b9fea32f4e9b17a8e38f07563ef0",
|
||||||
|
"version" : "2.0.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version" : 2
|
"version" : 2
|
||||||
|
|||||||
@ -4,38 +4,18 @@
|
|||||||
type = "1"
|
type = "1"
|
||||||
version = "2.0">
|
version = "2.0">
|
||||||
<Breakpoints>
|
<Breakpoints>
|
||||||
<BreakpointProxy
|
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.SwiftErrorBreakpoint">
|
|
||||||
<BreakpointContent
|
|
||||||
uuid = "C14D0996-5708-44D2-A6BA-4A4B50B522EE"
|
|
||||||
shouldBeEnabled = "No"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No">
|
|
||||||
</BreakpointContent>
|
|
||||||
</BreakpointProxy>
|
|
||||||
<BreakpointProxy
|
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
|
|
||||||
<BreakpointContent
|
|
||||||
uuid = "CF01B44D-372B-4C78-A197-7FDEC607CE0E"
|
|
||||||
shouldBeEnabled = "No"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No"
|
|
||||||
scope = "1"
|
|
||||||
stopOnStyle = "0">
|
|
||||||
</BreakpointContent>
|
|
||||||
</BreakpointProxy>
|
|
||||||
<BreakpointProxy
|
<BreakpointProxy
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.SymbolicBreakpoint">
|
BreakpointExtensionID = "Xcode.Breakpoint.SymbolicBreakpoint">
|
||||||
<BreakpointContent
|
<BreakpointContent
|
||||||
uuid = "B15A9E9C-A0CD-4FC9-8E24-DD93FB1B677F"
|
uuid = "676638C8-1CC5-4C04-98B0-1C0D6CB28B76"
|
||||||
shouldBeEnabled = "No"
|
shouldBeEnabled = "Yes"
|
||||||
ignoreCount = "0"
|
ignoreCount = "0"
|
||||||
continueAfterRunningActions = "No"
|
continueAfterRunningActions = "No"
|
||||||
symbolName = "UITableViewAlertForLayoutOutsideViewHierarchy"
|
symbolName = "UITableViewAlertForLayoutOutsideViewHierarchy"
|
||||||
moduleName = "">
|
moduleName = "">
|
||||||
<Locations>
|
<Locations>
|
||||||
<Location
|
<Location
|
||||||
uuid = "B15A9E9C-A0CD-4FC9-8E24-DD93FB1B677F - 620169ab4c7c265a"
|
uuid = "676638C8-1CC5-4C04-98B0-1C0D6CB28B76 - 620169ab4c7c265a"
|
||||||
shouldBeEnabled = "Yes"
|
shouldBeEnabled = "Yes"
|
||||||
ignoreCount = "0"
|
ignoreCount = "0"
|
||||||
continueAfterRunningActions = "No"
|
continueAfterRunningActions = "No"
|
||||||
@ -47,74 +27,5 @@
|
|||||||
</Locations>
|
</Locations>
|
||||||
</BreakpointContent>
|
</BreakpointContent>
|
||||||
</BreakpointProxy>
|
</BreakpointProxy>
|
||||||
<BreakpointProxy
|
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
||||||
<BreakpointContent
|
|
||||||
uuid = "CFC2DD73-A257-45F3-A7A8-7D9462944F86"
|
|
||||||
shouldBeEnabled = "Yes"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No"
|
|
||||||
filePath = "AutoCat/Extensions/AudioEngine.swift"
|
|
||||||
startingColumnNumber = "9223372036854775807"
|
|
||||||
endingColumnNumber = "9223372036854775807"
|
|
||||||
startingLineNumber = "12"
|
|
||||||
endingLineNumber = "12"
|
|
||||||
landmarkName = "setCategoryAsync(_:)"
|
|
||||||
landmarkType = "7">
|
|
||||||
</BreakpointContent>
|
|
||||||
</BreakpointProxy>
|
|
||||||
<BreakpointProxy
|
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.SwiftErrorBreakpoint">
|
|
||||||
<BreakpointContent
|
|
||||||
uuid = "4F72AC4F-FBCE-4C10-8BC2-2F434652DB31"
|
|
||||||
shouldBeEnabled = "No"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No">
|
|
||||||
</BreakpointContent>
|
|
||||||
</BreakpointProxy>
|
|
||||||
<BreakpointProxy
|
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
|
|
||||||
<BreakpointContent
|
|
||||||
uuid = "42580582-DA14-40D4-869A-FF91FCA9957C"
|
|
||||||
shouldBeEnabled = "No"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No"
|
|
||||||
breakpointStackSelectionBehavior = "1"
|
|
||||||
scope = "1"
|
|
||||||
stopOnStyle = "0">
|
|
||||||
</BreakpointContent>
|
|
||||||
</BreakpointProxy>
|
|
||||||
<BreakpointProxy
|
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
||||||
<BreakpointContent
|
|
||||||
uuid = "CA002588-A70B-4F96-BD13-7CC6C39BC2D5"
|
|
||||||
shouldBeEnabled = "Yes"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No"
|
|
||||||
filePath = "../../../Library/Developer/Xcode/DerivedData/AutoCat-fhilwnlnsrpirleiajogdcyhyyey/SourcePackages/checkouts/RxSwift/RxCocoa/Foundation/URLSession+Rx.swift"
|
|
||||||
startingColumnNumber = "9223372036854775807"
|
|
||||||
endingColumnNumber = "9223372036854775807"
|
|
||||||
startingLineNumber = "193"
|
|
||||||
endingLineNumber = "193"
|
|
||||||
landmarkName = "data(request:)"
|
|
||||||
landmarkType = "7">
|
|
||||||
</BreakpointContent>
|
|
||||||
</BreakpointProxy>
|
|
||||||
<BreakpointProxy
|
|
||||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
|
||||||
<BreakpointContent
|
|
||||||
uuid = "2B5BCCAE-FCA2-43D1-9835-08DB7E24B91C"
|
|
||||||
shouldBeEnabled = "No"
|
|
||||||
ignoreCount = "0"
|
|
||||||
continueAfterRunningActions = "No"
|
|
||||||
filePath = "AutoCat/Utils/RxRealmDataSource.swift"
|
|
||||||
startingColumnNumber = "9223372036854775807"
|
|
||||||
endingColumnNumber = "9223372036854775807"
|
|
||||||
startingLineNumber = "35"
|
|
||||||
endingLineNumber = "35"
|
|
||||||
landmarkName = "init(table:data:cellIdentifier:onSizeChanged:)"
|
|
||||||
landmarkType = "7">
|
|
||||||
</BreakpointContent>
|
|
||||||
</BreakpointProxy>
|
|
||||||
</Breakpoints>
|
</Breakpoints>
|
||||||
</Bucket>
|
</Bucket>
|
||||||
|
|||||||
35
AutoCat/ACUIKit/Extensions/UIControl.swift
Normal file
35
AutoCat/ACUIKit/Extensions/UIControl.swift
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension UIControl {
|
||||||
|
|
||||||
|
func addAction(for controlEvent: UIControl.Event = .touchUpInside, _ closure: @escaping () -> Void) {
|
||||||
|
|
||||||
|
addActionImpl(for: controlEvent, closure: closure)
|
||||||
|
}
|
||||||
|
|
||||||
|
func addActionAsync(for controlEvent: UIControl.Event = .touchUpInside, _ closure: @escaping () async -> Void) {
|
||||||
|
|
||||||
|
addActionImpl(for: controlEvent) {
|
||||||
|
Task {
|
||||||
|
await closure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addActionImpl(for controlEvents: UIControl.Event, closure: @escaping () -> Void) {
|
||||||
|
|
||||||
|
if #available(iOS 14.0, *) {
|
||||||
|
addAction(UIAction { _ in closure() }, for: controlEvents)
|
||||||
|
} else {
|
||||||
|
@objc class ClosureSleeve: NSObject {
|
||||||
|
let closure:()->()
|
||||||
|
init(_ closure: @escaping()->()) { self.closure = closure }
|
||||||
|
@objc func invoke() { closure() }
|
||||||
|
}
|
||||||
|
let sleeve = ClosureSleeve(closure)
|
||||||
|
addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
|
||||||
|
objc_setAssociatedObject(self, "\(UUID())", sleeve, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
15
AutoCat/ACUIKit/Extensions/UIEdgeInsets.swift
Normal file
15
AutoCat/ACUIKit/Extensions/UIEdgeInsets.swift
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension UIEdgeInsets {
|
||||||
|
|
||||||
|
init(all: CGFloat) {
|
||||||
|
self.init(top: all, left: all, bottom: all, right: all)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UIEdgeInsets {
|
||||||
|
|
||||||
|
static func all(_ value: CGFloat) -> UIEdgeInsets {
|
||||||
|
.init(all: value)
|
||||||
|
}
|
||||||
|
}
|
||||||
13
AutoCat/ACUIKit/Extensions/UIView+layout.swift
Normal file
13
AutoCat/ACUIKit/Extensions/UIView+layout.swift
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension UIView {
|
||||||
|
|
||||||
|
func pin(to view: UIView, insets: UIEdgeInsets = .zero) {
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: insets.left),
|
||||||
|
trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -insets.right),
|
||||||
|
topAnchor.constraint(equalTo: view.topAnchor, constant: insets.top),
|
||||||
|
bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -insets.bottom)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
80
AutoCat/ACUIKit/Views/ACButton.swift
Normal file
80
AutoCat/ACUIKit/Views/ACButton.swift
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import UIKit
|
||||||
|
|
||||||
|
enum ACButtonStyle {
|
||||||
|
case generic
|
||||||
|
case roundedBlue
|
||||||
|
}
|
||||||
|
|
||||||
|
class ACButton: UIButton {
|
||||||
|
|
||||||
|
private var style: ACButtonStyle = .generic
|
||||||
|
|
||||||
|
convenience init(style: ACButtonStyle = .roundedBlue, title: String, onTap: @escaping () -> Void) {
|
||||||
|
self.init()
|
||||||
|
self.style(style)
|
||||||
|
self.onTap(onTap)
|
||||||
|
self.title(title)
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
}
|
||||||
|
|
||||||
|
convenience init(style: ACButtonStyle = .roundedBlue, title: String, onTapAsync: @escaping () async -> Void) {
|
||||||
|
self.init()
|
||||||
|
self.style(style)
|
||||||
|
self.onTapAsync(onTapAsync)
|
||||||
|
self.title(title)
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
|
||||||
|
if style == .roundedBlue {
|
||||||
|
self.layer.opacity = self.isEnabled ? 1 : 0.5
|
||||||
|
} else {
|
||||||
|
self.layer.opacity = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func style(_ style: ACButtonStyle) -> ACButton {
|
||||||
|
|
||||||
|
self.style = style
|
||||||
|
|
||||||
|
switch style {
|
||||||
|
case .generic:
|
||||||
|
break
|
||||||
|
case .roundedBlue:
|
||||||
|
backgroundColor = .systemBlue
|
||||||
|
layer.cornerRadius = 6
|
||||||
|
}
|
||||||
|
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func title(_ title: String) -> ACButton {
|
||||||
|
|
||||||
|
setTitle(title, for: .normal)
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func enable(_ enabled: Bool) -> ACButton {
|
||||||
|
isEnabled = enabled
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func onTap(_ handler: @escaping () -> Void) -> ACButton {
|
||||||
|
|
||||||
|
addAction(for: .touchUpInside, handler)
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func onTapAsync(_ handler: @escaping () async -> Void) -> ACButton {
|
||||||
|
|
||||||
|
addActionAsync(for: .touchUpInside, handler)
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -173,17 +173,17 @@
|
|||||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="EventCell" id="QIb-Hv-tvk" customClass="EventCell" customModule="AutoCat" customModuleProvider="target">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="EventCell" id="QIb-Hv-tvk" customClass="EventCell" customModule="AutoCat" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="50" width="375" height="430.5"/>
|
<rect key="frame" x="0.0" y="50" width="375" height="431.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="QIb-Hv-tvk" id="Ypt-ch-fGT">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="QIb-Hv-tvk" id="Ypt-ch-fGT">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="430.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="431.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="HP8-oO-yhP">
|
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="HP8-oO-yhP">
|
||||||
<rect key="frame" x="16" y="8" width="343" height="414.5"/>
|
<rect key="frame" x="16" y="8" width="343" height="415.5"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="k4Z-KM-byE">
|
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="k4Z-KM-byE">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="335" height="414.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="335" height="415.5"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xcQ-Wz-gJ0">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xcQ-Wz-gJ0">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="335" height="201"/>
|
<rect key="frame" x="0.0" y="0.0" width="335" height="201"/>
|
||||||
@ -192,7 +192,7 @@
|
|||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1tQ-zM-6T9">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="1tQ-zM-6T9">
|
||||||
<rect key="frame" x="0.0" y="209" width="335" height="205.5"/>
|
<rect key="frame" x="0.0" y="209" width="335" height="206.5"/>
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
|
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
|
||||||
<color key="textColor" systemColor="secondaryLabelColor"/>
|
<color key="textColor" systemColor="secondaryLabelColor"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
@ -200,7 +200,7 @@
|
|||||||
</subviews>
|
</subviews>
|
||||||
</stackView>
|
</stackView>
|
||||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="750" verticalHuggingPriority="251" image="person" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="CFI-xa-eLs">
|
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="750" verticalHuggingPriority="251" image="person" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="CFI-xa-eLs">
|
||||||
<rect key="frame" x="343" y="1.5" width="0.0" height="412"/>
|
<rect key="frame" x="343" y="1.5" width="0.0" height="413"/>
|
||||||
</imageView>
|
</imageView>
|
||||||
</subviews>
|
</subviews>
|
||||||
</stackView>
|
</stackView>
|
||||||
@ -597,50 +597,19 @@
|
|||||||
<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>
|
<subviews>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="Peq-Zq-kNT">
|
|
||||||
<rect key="frame" x="62.5" y="68" width="250" height="114.5"/>
|
|
||||||
<subviews>
|
|
||||||
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="A001AA 777" textAlignment="center" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="8FU-Gy-4MU" customClass="SwiftMaskTextfield" customModule="AutoCat" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="250" height="50.5"/>
|
|
||||||
<fontDescription key="fontDescription" style="UICTFontTextStyleTitle0"/>
|
|
||||||
<textInputTraits key="textInputTraits" returnKeyType="done"/>
|
|
||||||
<connections>
|
|
||||||
<action selector="textFieldDidBeginEditing:" destination="twc-qR-t1G" eventType="editingDidBegin" id="Kvu-xK-QuZ"/>
|
|
||||||
<action selector="textFieldDidChange:" destination="twc-qR-t1G" eventType="editingChanged" id="x69-Ym-Zdm"/>
|
|
||||||
</connections>
|
|
||||||
</textField>
|
|
||||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Ync-fd-xQI" customClass="CustomButton" customModule="AutoCat" customModuleProvider="target">
|
|
||||||
<rect key="frame" x="0.0" y="66.5" width="250" height="48"/>
|
|
||||||
<color key="backgroundColor" systemColor="systemBlueColor"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="height" constant="48" id="YE0-lL-OwL"/>
|
|
||||||
</constraints>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="18"/>
|
|
||||||
<state key="normal" title="Check">
|
|
||||||
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
</state>
|
|
||||||
<connections>
|
|
||||||
<action selector="checkTapped:" destination="twc-qR-t1G" eventType="touchUpInside" id="WiK-lL-7q7"/>
|
|
||||||
</connections>
|
|
||||||
</button>
|
|
||||||
</subviews>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="width" constant="250" id="lqO-Yy-NyQ"/>
|
|
||||||
</constraints>
|
|
||||||
</stackView>
|
|
||||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" keyboardDismissMode="onDrag" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="JKr-UE-x8f">
|
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" keyboardDismissMode="onDrag" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="JKr-UE-x8f">
|
||||||
<rect key="frame" x="0.0" y="206.5" width="375" height="411.5"/>
|
<rect key="frame" x="0.0" y="44" width="375" height="623"/>
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||||
<prototypes>
|
<prototypes>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="VehicleCell" id="3ON-lr-UlV" customClass="VehicleCell" customModule="AutoCat" customModuleProvider="target">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="VehicleCell" id="3ON-lr-UlV" customClass="VehicleCell" customModule="AutoCat" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="50" width="375" height="84.5"/>
|
<rect key="frame" x="0.0" y="50" width="375" height="94.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="3ON-lr-UlV" id="IGw-UK-ebp">
|
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="3ON-lr-UlV" id="IGw-UK-ebp">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="84.5"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="94.5"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="6IZ-gM-D28">
|
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="6IZ-gM-D28">
|
||||||
<rect key="frame" x="8" y="8" width="359" height="68.5"/>
|
<rect key="frame" x="8" y="8" width="359" height="78.5"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="Rz6-wH-O1q">
|
<stackView opaque="NO" contentMode="scaleToFill" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="Rz6-wH-O1q">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="359" height="20"/>
|
<rect key="frame" x="0.0" y="0.0" width="359" height="20"/>
|
||||||
@ -675,18 +644,15 @@
|
|||||||
</subviews>
|
</subviews>
|
||||||
</stackView>
|
</stackView>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" alignment="bottom" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="nX1-KA-jqp">
|
<stackView opaque="NO" contentMode="scaleToFill" alignment="bottom" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="nX1-KA-jqp">
|
||||||
<rect key="frame" x="0.0" y="28" width="359" height="40.5"/>
|
<rect key="frame" x="0.0" y="28" width="359" height="50.5"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="VHX-o0-3BP" customClass="PlateView" customModule="AutoCat" customModuleProvider="target">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="VHX-o0-3BP" customClass="PlateView" customModule="AutoCat" customModuleProvider="target">
|
||||||
<rect key="frame" x="0.0" y="0.5" width="295" height="40"/>
|
<rect key="frame" x="0.0" y="0.5" width="295" height="50"/>
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||||
<color key="tintColor" systemColor="systemOrangeColor"/>
|
<color key="tintColor" systemColor="systemOrangeColor"/>
|
||||||
<constraints>
|
|
||||||
<constraint firstAttribute="height" constant="40" id="vzo-oF-mWb"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
</view>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="bottom" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="ApN-fV-Qw4">
|
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="bottom" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="ApN-fV-Qw4">
|
||||||
<rect key="frame" x="303" y="0.5" width="56" height="40"/>
|
<rect key="frame" x="303" y="10.5" width="56" height="40"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="1.01.2021" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rKr-3e-WYb">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" text="1.01.2021" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rKr-3e-WYb">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="56" height="16"/>
|
<rect key="frame" x="0.0" y="0.0" width="56" height="16"/>
|
||||||
@ -731,11 +697,9 @@
|
|||||||
<viewLayoutGuide key="safeArea" id="3Jk-FW-b3r"/>
|
<viewLayoutGuide key="safeArea" id="3Jk-FW-b3r"/>
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
|
<constraint firstItem="JKr-UE-x8f" firstAttribute="top" secondItem="3Jk-FW-b3r" secondAttribute="top" id="PUg-nV-TN6"/>
|
||||||
<constraint firstItem="JKr-UE-x8f" firstAttribute="trailing" secondItem="3Jk-FW-b3r" secondAttribute="trailing" id="Tc5-ri-5RD"/>
|
<constraint firstItem="JKr-UE-x8f" firstAttribute="trailing" secondItem="3Jk-FW-b3r" secondAttribute="trailing" id="Tc5-ri-5RD"/>
|
||||||
<constraint firstItem="Peq-Zq-kNT" firstAttribute="top" secondItem="3Jk-FW-b3r" secondAttribute="top" constant="24" id="Tft-8o-Cb1"/>
|
<constraint firstItem="JKr-UE-x8f" firstAttribute="bottom" secondItem="g5m-iL-O7A" secondAttribute="bottom" id="Zwj-XD-UhD"/>
|
||||||
<constraint firstItem="JKr-UE-x8f" firstAttribute="bottom" secondItem="3Jk-FW-b3r" secondAttribute="bottom" id="Zwj-XD-UhD"/>
|
|
||||||
<constraint firstItem="Peq-Zq-kNT" firstAttribute="centerX" secondItem="g5m-iL-O7A" secondAttribute="centerX" id="fXl-Na-1gb"/>
|
|
||||||
<constraint firstItem="JKr-UE-x8f" firstAttribute="top" secondItem="Peq-Zq-kNT" secondAttribute="bottom" constant="24" id="mm9-rL-KQ1"/>
|
|
||||||
<constraint firstItem="JKr-UE-x8f" firstAttribute="leading" secondItem="3Jk-FW-b3r" secondAttribute="leading" id="vfN-fu-5pA"/>
|
<constraint firstItem="JKr-UE-x8f" firstAttribute="leading" secondItem="3Jk-FW-b3r" secondAttribute="leading" id="vfN-fu-5pA"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
@ -754,9 +718,7 @@
|
|||||||
</rightBarButtonItems>
|
</rightBarButtonItems>
|
||||||
</navigationItem>
|
</navigationItem>
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="check" destination="Ync-fd-xQI" id="oxC-p6-Mou"/>
|
|
||||||
<outlet property="history" destination="JKr-UE-x8f" id="GP9-Gz-WBm"/>
|
<outlet property="history" destination="JKr-UE-x8f" id="GP9-Gz-WBm"/>
|
||||||
<outlet property="number" destination="8FU-Gy-4MU" id="PwP-Pn-eeO"/>
|
|
||||||
</connections>
|
</connections>
|
||||||
</viewController>
|
</viewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="h7Y-mR-2Ti" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="h7Y-mR-2Ti" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||||
@ -812,10 +774,10 @@
|
|||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="1704.8" y="-701.19940029985014"/>
|
<point key="canvasLocation" x="1704.8" y="-701.19940029985014"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--Tab Bar Controller-->
|
<!--Main Tab Controller-->
|
||||||
<scene sceneID="YhQ-kn-py3">
|
<scene sceneID="YhQ-kn-py3">
|
||||||
<objects>
|
<objects>
|
||||||
<tabBarController id="s9R-9a-TOT" sceneMemberID="viewController">
|
<tabBarController id="s9R-9a-TOT" customClass="MainTabController" customModule="AutoCat" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
<tabBar key="tabBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="7gI-Jq-j4q">
|
<tabBar key="tabBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="7gI-Jq-j4q">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="414" height="49"/>
|
<rect key="frame" x="0.0" y="0.0" width="414" height="49"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
@ -824,6 +786,7 @@
|
|||||||
<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="RK6-pn-2Bg" kind="relationship" relationship="viewControllers" id="KNz-WF-Kyy"/>
|
<segue destination="RK6-pn-2Bg" kind="relationship" relationship="viewControllers" id="KNz-WF-Kyy"/>
|
||||||
|
<segue destination="dxo-XS-x8Q" kind="relationship" relationship="viewControllers" id="MgV-gx-h7p"/>
|
||||||
<segue destination="GCa-Re-j14" 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>
|
||||||
@ -951,6 +914,22 @@
|
|||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="199" y="143"/>
|
<point key="canvasLocation" x="199" y="143"/>
|
||||||
</scene>
|
</scene>
|
||||||
|
<!--Add-->
|
||||||
|
<scene sceneID="bCG-fh-cdJ">
|
||||||
|
<objects>
|
||||||
|
<viewController id="dxo-XS-x8Q" customClass="DummyNewController" customModule="AutoCat" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
|
<view key="view" contentMode="scaleToFill" id="7Rw-QC-Av7">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<viewLayoutGuide key="safeArea" id="vIj-pz-YHR"/>
|
||||||
|
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||||
|
</view>
|
||||||
|
<tabBarItem key="tabBarItem" title="Add" image="plus" catalog="system" id="X0w-PF-Dn8"/>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="C2T-ZN-q8G" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
<point key="canvasLocation" x="929" y="-260"/>
|
||||||
|
</scene>
|
||||||
<!--Global Events Controller-->
|
<!--Global Events Controller-->
|
||||||
<scene sceneID="akP-Pw-M4Q">
|
<scene sceneID="akP-Pw-M4Q">
|
||||||
<objects>
|
<objects>
|
||||||
@ -989,11 +968,11 @@
|
|||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="7518" y="144"/>
|
<point key="canvasLocation" x="7518" y="144"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--Check-->
|
<!--History-->
|
||||||
<scene sceneID="pUX-kf-oY1">
|
<scene sceneID="pUX-kf-oY1">
|
||||||
<objects>
|
<objects>
|
||||||
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="TSb-ZG-qfD" sceneMemberID="viewController">
|
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="TSb-ZG-qfD" sceneMemberID="viewController">
|
||||||
<tabBarItem key="tabBarItem" title="Check" image="check" landscapeImage="check-compact" id="QJd-35-4OB"/>
|
<tabBarItem key="tabBarItem" title="History" image="clock.arrow.circlepath" catalog="system" id="QJd-35-4OB"/>
|
||||||
<toolbarItems/>
|
<toolbarItems/>
|
||||||
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="AAc-4d-GNh">
|
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="AAc-4d-GNh">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
|
||||||
@ -1084,14 +1063,14 @@
|
|||||||
</scene>
|
</scene>
|
||||||
</scenes>
|
</scenes>
|
||||||
<resources>
|
<resources>
|
||||||
<image name="check" width="25" height="25"/>
|
<image name="clock.arrow.circlepath" catalog="system" width="128" height="112"/>
|
||||||
<image name="check-compact" width="18" height="18"/>
|
|
||||||
<image name="doc.on.doc" catalog="system" width="116" height="128"/>
|
<image name="doc.on.doc" catalog="system" width="116" height="128"/>
|
||||||
<image name="exclamationmark.arrow.triangle.2.circlepath" catalog="system" width="128" height="104"/>
|
<image name="exclamationmark.arrow.triangle.2.circlepath" catalog="system" width="128" height="104"/>
|
||||||
<image name="line.horizontal.3.decrease" catalog="system" width="128" height="73"/>
|
<image name="line.horizontal.3.decrease" catalog="system" width="128" height="73"/>
|
||||||
<image name="map" catalog="system" width="128" height="112"/>
|
<image name="map" catalog="system" width="128" height="112"/>
|
||||||
<image name="person" catalog="system" width="128" height="121"/>
|
<image name="person" catalog="system" width="128" height="121"/>
|
||||||
<image name="play.fill" catalog="system" width="117" height="128"/>
|
<image name="play.fill" catalog="system" width="117" height="128"/>
|
||||||
|
<image name="plus" catalog="system" width="128" height="113"/>
|
||||||
<image name="record" width="31" height="31"/>
|
<image name="record" width="31" height="31"/>
|
||||||
<image name="record-compact" width="23" height="23"/>
|
<image name="record-compact" width="23" height="23"/>
|
||||||
<image name="search" width="23" height="23"/>
|
<image name="search" width="23" height="23"/>
|
||||||
|
|||||||
@ -23,6 +23,8 @@ class VehicleCell: UITableViewCell, ConfigurableCell {
|
|||||||
func configure(with vehicle: Vehicle) {
|
func configure(with vehicle: Vehicle) {
|
||||||
self.name.text = vehicle.brand?.name?.original ?? "<unknown>"
|
self.name.text = vehicle.brand?.name?.original ?? "<unknown>"
|
||||||
self.plate.number = PlateNumber(vehicle.getNumber())
|
self.plate.number = PlateNumber(vehicle.getNumber())
|
||||||
|
self.plate.fontSize = 40
|
||||||
|
|
||||||
if vehicle.unrecognized {
|
if vehicle.unrecognized {
|
||||||
self.plate.foreground = .systemRed
|
self.plate.foreground = .systemRed
|
||||||
} else if vehicle.outdated {
|
} else if vehicle.outdated {
|
||||||
|
|||||||
@ -27,29 +27,30 @@ extension String.StringInterpolation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegate, PNKeyboardDelegate {
|
class CheckController: UIViewController, UITableViewDelegate, UISearchResultsUpdating {
|
||||||
|
|
||||||
@IBOutlet weak var number: SwiftMaskTextfield!
|
|
||||||
@IBOutlet weak var check: UIButton!
|
|
||||||
@IBOutlet weak var history: UITableView!
|
@IBOutlet weak var history: UITableView!
|
||||||
|
|
||||||
private let bag = DisposeBag()
|
private let bag = DisposeBag()
|
||||||
private var historyDataSource: RealmSectionedDataSource<Vehicle, VehicleCell>!
|
private var historyDataSource: RealmSectionedDataSource<Vehicle, VehicleCell>!
|
||||||
private var historyFilter: HistoryFilter = .all
|
private var historyFilter: HistoryFilter = .all
|
||||||
|
|
||||||
|
private let searchController = UISearchController(searchResultsController: nil)
|
||||||
|
|
||||||
// MARK: - Lifecycle
|
// MARK: - Lifecycle
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
searchController.searchResultsUpdater = self
|
||||||
|
searchController.obscuresBackgroundDuringPresentation = false
|
||||||
|
searchController.searchBar.placeholder = NSLocalizedString("Search plate numbers", comment: "")
|
||||||
|
searchController.hidesNavigationBarDuringPresentation = false
|
||||||
|
navigationItem.searchController = searchController
|
||||||
|
|
||||||
guard let realm = try? Realm() else { return }
|
guard let realm = try? Realm() else { return }
|
||||||
|
|
||||||
self.hideKeyboardWhenTappedAround()
|
self.hideKeyboardWhenTappedAround()
|
||||||
let keyboard = PNKeyboard(target: self.number)
|
|
||||||
keyboard.delegate = self
|
|
||||||
//self.number.formatPattern = "@###@@###"
|
|
||||||
self.number.inputView = keyboard
|
|
||||||
self.check.isEnabled = false
|
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.historyDataSource = RealmSectionedDataSource(table: self.history, data: realm.objects(Vehicle.self).sorted(byKeyPath: "updatedDate", ascending: false)) { count in
|
self.historyDataSource = RealmSectionedDataSource(table: self.history, data: realm.objects(Vehicle.self).sorted(byKeyPath: "updatedDate", ascending: false)) { count in
|
||||||
@ -61,11 +62,6 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
|
|||||||
NotificationCenter.default.addObserver(self, selector:#selector(self.calendarDayDidChange(_:)), name:NSNotification.Name.NSCalendarDayChanged, object:nil)
|
NotificationCenter.default.addObserver(self, selector:#selector(self.calendarDayDidChange(_:)), name:NSNotification.Name.NSCalendarDayChanged, object:nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
|
||||||
super.viewWillAppear(animated)
|
|
||||||
//self.navigationController?.setNavigationBarHidden(true, animated: false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewWillDisappear(_ animated: Bool) {
|
override func viewWillDisappear(_ animated: Bool) {
|
||||||
super.viewWillDisappear(animated)
|
super.viewWillDisappear(animated)
|
||||||
if let index = self.history.indexPathForSelectedRow {
|
if let index = self.history.indexPathForSelectedRow {
|
||||||
@ -86,7 +82,9 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
|
|||||||
switch ad.quickAction {
|
switch ad.quickAction {
|
||||||
case .check:
|
case .check:
|
||||||
ad.quickAction = .none
|
ad.quickAction = .none
|
||||||
self.number.becomeFirstResponder()
|
if let tabBar = tabBarController as? MainTabController {
|
||||||
|
tabBar.showCheckPuller()
|
||||||
|
}
|
||||||
break
|
break
|
||||||
case .checkNumber(let number, let event):
|
case .checkNumber(let number, let event):
|
||||||
ad.quickAction = .none
|
ad.quickAction = .none
|
||||||
@ -204,13 +202,8 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
|
|||||||
|
|
||||||
// MARK: - Checking new number
|
// MARK: - Checking new number
|
||||||
|
|
||||||
@IBAction func checkTapped(_ sender: UIButton) {
|
func checkTapped(number: String) {
|
||||||
guard let number = self.number.text else { return }
|
|
||||||
|
|
||||||
let numberNormalized = number.filter { !$0.isWhitespace }.uppercased()
|
let numberNormalized = number.filter { !$0.isWhitespace }.uppercased()
|
||||||
self.number.resignFirstResponder()
|
|
||||||
self.number.text = nil
|
|
||||||
self.check.isEnabled = false
|
|
||||||
|
|
||||||
var events: [VehicleEvent] = []
|
var events: [VehicleEvent] = []
|
||||||
do {
|
do {
|
||||||
@ -258,29 +251,6 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - UITextFieldDelegate
|
|
||||||
|
|
||||||
@IBAction func textFieldDidBeginEditing(_ textField: UITextField) {
|
|
||||||
RxLocationManager.requestCurrentLocation().subscribe().disposed(by: self.bag)
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction func textFieldDidChange(_ textField: UITextField) {
|
|
||||||
guard let text = textField.text else {
|
|
||||||
self.check.isEnabled = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
self.check.isEnabled = text.count >= 8
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - PNKeyboardDelegate
|
|
||||||
|
|
||||||
func returnClicked() {
|
|
||||||
if self.check.isEnabled {
|
|
||||||
self.checkTapped(self.check)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - UITableViewDelegate
|
// MARK: - UITableViewDelegate
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
|
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
|
||||||
@ -322,6 +292,23 @@ class CheckController: UIViewController, UITableViewDelegate, UITextFieldDelegat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - UISearchResultsUpdating
|
||||||
|
|
||||||
|
func updateSearchResults(for searchController: UISearchController) {
|
||||||
|
guard let realm = try? Realm() else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var query = realm.objects(Vehicle.self)
|
||||||
|
.sorted(byKeyPath: "updatedDate", ascending: false)
|
||||||
|
|
||||||
|
if let text = searchController.searchBar.text?.uppercased(), !text.isEmpty {
|
||||||
|
query = query.filter("number CONTAINS '\(text)'")
|
||||||
|
}
|
||||||
|
|
||||||
|
historyDataSource.setQuery(query)
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Contextual actions
|
// MARK: - Contextual actions
|
||||||
|
|
||||||
func update(vehicle: Vehicle) {
|
func update(vehicle: Vehicle) {
|
||||||
|
|||||||
6
AutoCat/Controllers/DummyNewController.swift
Normal file
6
AutoCat/Controllers/DummyNewController.swift
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import UIKit
|
||||||
|
|
||||||
|
/// Dummy controller for detecting tap on "plus" tab
|
||||||
|
class DummyNewController: UIViewController {
|
||||||
|
|
||||||
|
}
|
||||||
55
AutoCat/Controllers/MainTabController.swift
Normal file
55
AutoCat/Controllers/MainTabController.swift
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import UIKit
|
||||||
|
import SwiftEntryKit
|
||||||
|
import AutoCatCore
|
||||||
|
import RxSwift
|
||||||
|
|
||||||
|
class MainTabController: UITabBarController, UITabBarControllerDelegate {
|
||||||
|
|
||||||
|
private let bag = DisposeBag()
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
self.delegate = self
|
||||||
|
}
|
||||||
|
|
||||||
|
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
|
||||||
|
if viewController is DummyNewController {
|
||||||
|
showCheckPuller()
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func showCheckPuller() {
|
||||||
|
guard let checkNav = viewControllers?.first as? UINavigationController,
|
||||||
|
let checkController = checkNav.viewControllers.first as? CheckController
|
||||||
|
else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var attributes = EKAttributes.bottomToast
|
||||||
|
attributes.displayDuration = .infinity
|
||||||
|
attributes.entryBackground = .color(color: .init(.secondarySystemBackground))
|
||||||
|
attributes.screenBackground = .color(color: EKColor(UIColor(white: 0, alpha: 0.7)))
|
||||||
|
attributes.roundCorners = .top(radius: 24)
|
||||||
|
attributes.screenInteraction = .dismiss
|
||||||
|
attributes.entryInteraction = .forward
|
||||||
|
attributes.entranceAnimation = .init(translate: .init(duration: 0.2))
|
||||||
|
attributes.exitAnimation = .init(translate: .init(duration: 0.2))
|
||||||
|
|
||||||
|
let newNumberController = NewNumberController()
|
||||||
|
newNumberController.onCheck = { number in
|
||||||
|
SwiftEntryKit.dismiss {
|
||||||
|
self.selectedIndex = 0
|
||||||
|
checkController.checkTapped(number: number)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SwiftEntryKit.display(entry: newNumberController, using: attributes)
|
||||||
|
|
||||||
|
// User probably just saw a vehicle and is about to start entering plate number
|
||||||
|
// Requesting current location ASAP while we still close to initial location
|
||||||
|
RxLocationManager.requestCurrentLocation().subscribe().disposed(by: self.bag)
|
||||||
|
}
|
||||||
|
}
|
||||||
83
AutoCat/Controllers/NewNumberController.swift
Normal file
83
AutoCat/Controllers/NewNumberController.swift
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
import UIKit
|
||||||
|
import AutoCatCore
|
||||||
|
|
||||||
|
class NewNumberController: UIViewController {
|
||||||
|
|
||||||
|
public var onCheck: ((String) -> Void)?
|
||||||
|
|
||||||
|
private lazy var keyboardView: PNKeyboard = {
|
||||||
|
let keyboard = PNKeyboard(target: self.plateView)
|
||||||
|
keyboard.delegate = self
|
||||||
|
return keyboard
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var plateView: PlateView = {
|
||||||
|
let view = PlateView(frame: .zero)
|
||||||
|
view.fontSize = 48
|
||||||
|
view.number = PlateNumber("")
|
||||||
|
view.onChange = onNumberChanged
|
||||||
|
view.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
||||||
|
view.accessibilityIdentifier = "plateView"
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var checkButton: ACButton = {
|
||||||
|
let button = ACButton(title: NSLocalizedString("Check", comment: ""), onTap: check)
|
||||||
|
button.isEnabled = false
|
||||||
|
button.contentEdgeInsets = .init(top: 0, left: 8, bottom: 0, right: 8)
|
||||||
|
button.accessibilityIdentifier = "checkButton"
|
||||||
|
return button
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var stackView: UIStackView = {
|
||||||
|
let stack = UIStackView(arrangedSubviews: [plateView, checkButton])
|
||||||
|
stack.axis = .horizontal
|
||||||
|
stack.spacing = 16
|
||||||
|
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return stack
|
||||||
|
}()
|
||||||
|
|
||||||
|
private let titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.text = NSLocalizedString("Check number", comment: "")
|
||||||
|
label.font = UIFont.preferredFont(forTextStyle: .headline)
|
||||||
|
label.textAlignment = .center
|
||||||
|
label.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var mainStackView: UIStackView = {
|
||||||
|
let stack = UIStackView(arrangedSubviews: [titleLabel, stackView, keyboardView])
|
||||||
|
stack.axis = .vertical
|
||||||
|
stack.spacing = 16
|
||||||
|
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
return stack
|
||||||
|
}()
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
view.addSubview(mainStackView)
|
||||||
|
mainStackView.pin(to: view, insets: .init(top: 16, left: 16, bottom: 16, right: 16))
|
||||||
|
}
|
||||||
|
|
||||||
|
func check() {
|
||||||
|
guard let number = plateView.number, number.isValid else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let numberNormalized = number.asString().filter { !$0.isWhitespace }.uppercased()
|
||||||
|
onCheck?(numberNormalized)
|
||||||
|
}
|
||||||
|
|
||||||
|
func onNumberChanged() {
|
||||||
|
checkButton.isEnabled = plateView.number?.isValid ?? false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension NewNumberController: PNKeyboardDelegate {
|
||||||
|
|
||||||
|
func returnClicked() {
|
||||||
|
check()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,12 +15,14 @@ class ReportController: FormViewController, MediaBrowserViewControllerDataSource
|
|||||||
|
|
||||||
var vehicle: Vehicle? {
|
var vehicle: Vehicle? {
|
||||||
didSet {
|
didSet {
|
||||||
loadViewIfNeeded()
|
//loadViewIfNeeded()
|
||||||
|
if isViewLoaded {
|
||||||
self.updateReport()
|
self.updateReport()
|
||||||
self.form.allSections.forEach { $0.reload() }
|
self.form.allSections.forEach { $0.reload() }
|
||||||
self.navigationController?.setNavigationBarHidden(self.vehicle == nil, animated: false)
|
self.navigationController?.setNavigationBarHidden(self.vehicle == nil, animated: false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private var notificationToken: NotificationToken?
|
private var notificationToken: NotificationToken?
|
||||||
var number: String? {
|
var number: String? {
|
||||||
@ -205,8 +207,8 @@ class ReportController: FormViewController, MediaBrowserViewControllerDataSource
|
|||||||
return value ? yes : no
|
return value ? yes : no
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
super.viewWillAppear(animated)
|
super.viewDidAppear(animated)
|
||||||
guard let ad = UIApplication.shared.delegate as? AppDelegate else { return }
|
guard let ad = UIApplication.shared.delegate as? AppDelegate else { return }
|
||||||
|
|
||||||
self.navigationController?.setNavigationBarHidden(self.vehicle == nil, animated: animated)
|
self.navigationController?.setNavigationBarHidden(self.vehicle == nil, animated: animated)
|
||||||
|
|||||||
@ -33,6 +33,7 @@ class SearchController: UIViewController, UISearchResultsUpdating, UITableViewDe
|
|||||||
searchController.searchResultsUpdater = self
|
searchController.searchResultsUpdater = self
|
||||||
searchController.obscuresBackgroundDuringPresentation = false
|
searchController.obscuresBackgroundDuringPresentation = false
|
||||||
searchController.searchBar.placeholder = NSLocalizedString("Search plate numbers", comment: "")
|
searchController.searchBar.placeholder = NSLocalizedString("Search plate numbers", comment: "")
|
||||||
|
searchController.hidesNavigationBarDuringPresentation = false
|
||||||
navigationItem.searchController = searchController
|
navigationItem.searchController = searchController
|
||||||
definesPresentationContext = true
|
definesPresentationContext = true
|
||||||
|
|
||||||
|
|||||||
@ -18,16 +18,23 @@ class RealmSectionedDataSource<Item,Cell>: NSObject, UITableViewDataSource
|
|||||||
private var cellIdentifier: String
|
private var cellIdentifier: String
|
||||||
private var filterPredicate: FilterPredicate<Item>?
|
private var filterPredicate: FilterPredicate<Item>?
|
||||||
|
|
||||||
|
private let onSizeChanged: ((Int) -> Void)?
|
||||||
|
|
||||||
init(table: UITableView, data: Results<Item>, cellIdentifier: String = String(describing: Cell.self), onSizeChanged: ((Int) -> Void)? = nil) {
|
init(table: UITableView, data: Results<Item>, cellIdentifier: String = String(describing: Cell.self), onSizeChanged: ((Int) -> Void)? = nil) {
|
||||||
self.tv = table
|
self.tv = table
|
||||||
self.data = data
|
self.data = data
|
||||||
self.cellIdentifier = cellIdentifier
|
self.cellIdentifier = cellIdentifier
|
||||||
|
self.onSizeChanged = onSizeChanged
|
||||||
super.init()
|
super.init()
|
||||||
self.tv.dataSource = self
|
self.tv.dataSource = self
|
||||||
self.tv.reloadData()
|
self.tv.reloadData()
|
||||||
|
|
||||||
|
startObservingChanges()
|
||||||
|
}
|
||||||
|
|
||||||
|
func startObservingChanges() {
|
||||||
self.notificationToken = self.data.observe { changes in
|
self.notificationToken = self.data.observe { changes in
|
||||||
onSizeChanged?(self.data.count)
|
self.onSizeChanged?(self.data.count)
|
||||||
switch changes {
|
switch changes {
|
||||||
case .initial:
|
case .initial:
|
||||||
self.reload(animated: false)
|
self.reload(animated: false)
|
||||||
@ -170,4 +177,9 @@ class RealmSectionedDataSource<Item,Cell>: NSObject, UITableViewDataSource
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setQuery(_ query: Results<Item>) {
|
||||||
|
self.data = query
|
||||||
|
startObservingChanges()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,11 +66,9 @@ class RxSectionedDataSource<Item,Cell>: NSObject, UITableViewDataSource where I
|
|||||||
|
|
||||||
DispatchQueue.global().async {
|
DispatchQueue.global().async {
|
||||||
let newSections = self.items.groupedByDate(type: self.sortParam)
|
let newSections = self.items.groupedByDate(type: self.sortParam)
|
||||||
let changeset = StagedChangeset(source: self.sections, target: newSections)
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.tv.reload(using: changeset, with: .automatic) { newSects in
|
self.sections = newSections
|
||||||
self.sections = newSects
|
self.tv.reloadData()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -110,8 +110,11 @@ class PNKeyboard: UIView, UIInputViewAudioFeedback, PNButtonDelegate {
|
|||||||
private weak var target: UIKeyInput?
|
private weak var target: UIKeyInput?
|
||||||
weak var delegate: PNKeyboardDelegate?
|
weak var delegate: PNKeyboardDelegate?
|
||||||
|
|
||||||
init(target: UIKeyInput) {
|
private let insets: UIEdgeInsets
|
||||||
|
|
||||||
|
init(target: UIKeyInput, insets: UIEdgeInsets = .zero) {
|
||||||
self.target = target
|
self.target = target
|
||||||
|
self.insets = insets
|
||||||
super.init(frame: .zero)
|
super.init(frame: .zero)
|
||||||
self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||||
|
|
||||||
@ -176,10 +179,10 @@ class PNKeyboard: UIView, UIInputViewAudioFeedback, PNButtonDelegate {
|
|||||||
self.addSubview(mainStack)
|
self.addSubview(mainStack)
|
||||||
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
mainStack.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 16),
|
mainStack.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: insets.left),
|
||||||
mainStack.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -16),
|
mainStack.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -insets.right),
|
||||||
mainStack.topAnchor.constraint(equalTo: self.topAnchor, constant: 16),
|
mainStack.topAnchor.constraint(equalTo: self.topAnchor, constant: insets.top),
|
||||||
mainStack.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor, constant: -16)
|
mainStack.bottomAnchor.constraint(equalTo: self.safeAreaLayoutGuide.bottomAnchor, constant: -insets.bottom)
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,15 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import AutoCatCore
|
import AutoCatCore
|
||||||
|
|
||||||
|
private class CALayerAnimationsDisablingDelegate: NSObject, CALayerDelegate {
|
||||||
|
static let shared = CALayerAnimationsDisablingDelegate()
|
||||||
|
private let null = NSNull()
|
||||||
|
|
||||||
|
func action(for layer: CALayer, forKey event: String) -> CAAction? {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class PlateView: UIView {
|
class PlateView: UIView {
|
||||||
// Some driver plate parameters from "ГОСТ Р 50577-93"
|
// Some driver plate parameters from "ГОСТ Р 50577-93"
|
||||||
// http://docs.cntd.ru/document/gost-r-50577-93
|
// http://docs.cntd.ru/document/gost-r-50577-93
|
||||||
@ -27,9 +36,25 @@ class PlateView: UIView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var fontSize: CGFloat = 10 {
|
||||||
|
didSet {
|
||||||
|
self.layoutSubviews()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var onChange: (() -> Void)?
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
setup()
|
||||||
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
super.init(coder: coder)
|
super.init(coder: coder)
|
||||||
|
setup()
|
||||||
|
}
|
||||||
|
|
||||||
|
func setup() {
|
||||||
self.layer.backgroundColor = UIColor.clear.cgColor
|
self.layer.backgroundColor = UIColor.clear.cgColor
|
||||||
|
|
||||||
self.bgLayer.cornerRadius = 6 //self.bounds.height/8
|
self.bgLayer.cornerRadius = 6 //self.bounds.height/8
|
||||||
@ -56,6 +81,20 @@ class PlateView: UIView {
|
|||||||
|
|
||||||
self.flagLayer.contentsScale = UIScreen.main.scale
|
self.flagLayer.contentsScale = UIScreen.main.scale
|
||||||
self.layer.addSublayer(self.flagLayer)
|
self.layer.addSublayer(self.flagLayer)
|
||||||
|
|
||||||
|
disableAnimations(for: [
|
||||||
|
bgLayer,
|
||||||
|
mainBgLayer,
|
||||||
|
regionBgLayer,
|
||||||
|
numberLayer,
|
||||||
|
regionLayer,
|
||||||
|
countryLayer,
|
||||||
|
flagLayer
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func disableAnimations(for layers: [CALayer]) {
|
||||||
|
layers.forEach { $0.delegate = CALayerAnimationsDisablingDelegate.shared }
|
||||||
}
|
}
|
||||||
|
|
||||||
private func pathForFlag(in rect: CGRect) -> CGPath {
|
private func pathForFlag(in rect: CGRect) -> CGPath {
|
||||||
@ -116,15 +155,31 @@ class PlateView: UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override var intrinsicContentSize: CGSize {
|
override var intrinsicContentSize: CGSize {
|
||||||
guard self.bounds.width != 0 || self.bounds.height != 0 else {
|
|
||||||
return CGSize.zero
|
let height = fontSize/1.1 + 4
|
||||||
|
let width = height/PlateView.aspectRatio
|
||||||
|
print("")
|
||||||
|
return CGSize(width: width, height: height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension PlateView: UIKeyInput {
|
||||||
|
|
||||||
|
var hasText: Bool {
|
||||||
|
number?.hasText ?? false
|
||||||
}
|
}
|
||||||
|
|
||||||
let curAspectRatio = self.bounds.height/self.bounds.width
|
func insertText(_ text: String) {
|
||||||
if curAspectRatio >= PlateView.aspectRatio {
|
if number?.insertText(text) == true {
|
||||||
return CGSize(width: self.bounds.width, height: self.bounds.width*PlateView.aspectRatio)
|
layoutSubviews()
|
||||||
} else {
|
onChange?()
|
||||||
return CGSize(width: self.bounds.height/PlateView.aspectRatio, height: self.bounds.height)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteBackward() {
|
||||||
|
if number?.deleteBackward() == true {
|
||||||
|
layoutSubviews()
|
||||||
|
onChange?()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,6 +70,9 @@
|
|||||||
/* No comment provided by engineer. */
|
/* No comment provided by engineer. */
|
||||||
"Check date" = "Дата проверки";
|
"Check date" = "Дата проверки";
|
||||||
|
|
||||||
|
/* No comment provided by engineer. */
|
||||||
|
"Check number" = "Проверить номер";
|
||||||
|
|
||||||
/* No comment provided by engineer. */
|
/* No comment provided by engineer. */
|
||||||
"Check parameters" = "Параметры проверки";
|
"Check parameters" = "Параметры проверки";
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
/* Class = "UIBarButtonItem"; title = "Back"; ObjectID = "7QQ-Qi-qEw"; */
|
/* Class = "UIBarButtonItem"; title = "Back"; ObjectID = "7QQ-Qi-qEw"; */
|
||||||
"7QQ-Qi-qEw.title" = "Назад";
|
"7QQ-Qi-qEw.title" = "Назад";
|
||||||
|
|
||||||
/* Class = "UITextField"; placeholder = "A001AA 777"; ObjectID = "8FU-Gy-4MU"; */
|
|
||||||
"8FU-Gy-4MU.placeholder" = "A001AA 777";
|
|
||||||
|
|
||||||
/* Class = "UILabel"; text = "00:00"; ObjectID = "bFQ-eU-5YJ"; */
|
/* Class = "UILabel"; text = "00:00"; ObjectID = "bFQ-eU-5YJ"; */
|
||||||
"bFQ-eU-5YJ.text" = "00:00";
|
"bFQ-eU-5YJ.text" = "00:00";
|
||||||
|
|
||||||
@ -31,8 +28,8 @@
|
|||||||
/* Class = "UITabBarItem"; title = "Records"; ObjectID = "lxF-EY-z8V"; */
|
/* Class = "UITabBarItem"; title = "Records"; ObjectID = "lxF-EY-z8V"; */
|
||||||
"lxF-EY-z8V.title" = "Аудио";
|
"lxF-EY-z8V.title" = "Аудио";
|
||||||
|
|
||||||
/* Class = "UITabBarItem"; title = "Check"; ObjectID = "QJd-35-4OB"; */
|
/* Class = "UITabBarItem"; title = "History"; ObjectID = "QJd-35-4OB"; */
|
||||||
"QJd-35-4OB.title" = "Проверка";
|
"QJd-35-4OB.title" = "История";
|
||||||
|
|
||||||
/* Class = "UILabel"; text = "or"; ObjectID = "SXb-1Q-TxY"; */
|
/* Class = "UILabel"; text = "or"; ObjectID = "SXb-1Q-TxY"; */
|
||||||
"SXb-1Q-TxY.text" = "или";
|
"SXb-1Q-TxY.text" = "или";
|
||||||
@ -43,8 +40,8 @@
|
|||||||
/* Class = "UITextField"; placeholder = "Email"; ObjectID = "Uey-88-eZL"; */
|
/* Class = "UITextField"; placeholder = "Email"; ObjectID = "Uey-88-eZL"; */
|
||||||
"Uey-88-eZL.placeholder" = "Email";
|
"Uey-88-eZL.placeholder" = "Email";
|
||||||
|
|
||||||
/* Class = "UIButton"; normalTitle = "Check"; ObjectID = "Ync-fd-xQI"; */
|
/* Class = "UITabBarItem"; title = "Add"; ObjectID = "X0w-PF-Dn8"; */
|
||||||
"Ync-fd-xQI.normalTitle" = "Проверить";
|
"X0w-PF-Dn8.title" = "Добавить";
|
||||||
|
|
||||||
/* Class = "UITabBarItem"; title = "Settings"; ObjectID = "zEL-ph-E2f"; */
|
/* Class = "UITabBarItem"; title = "Settings"; ObjectID = "zEL-ph-E2f"; */
|
||||||
"zEL-ph-E2f.title" = "Настройки";
|
"zEL-ph-E2f.title" = "Настройки";
|
||||||
|
|||||||
@ -5,12 +5,16 @@ import DifferenceKit
|
|||||||
public struct DateSection<T>: Differentiable, DifferentiableSection, Hashable where T: Differentiable & Hashable {
|
public struct DateSection<T>: Differentiable, DifferentiableSection, Hashable where T: Differentiable & Hashable {
|
||||||
|
|
||||||
var timestamp: Double = 0
|
var timestamp: Double = 0
|
||||||
public var header: String
|
var dateString: String
|
||||||
public var elements: [T]
|
public var elements: [T]
|
||||||
|
|
||||||
|
public var header: String {
|
||||||
|
"\(dateString) (\(elements.count))"
|
||||||
|
}
|
||||||
|
|
||||||
public init<C>(source: DateSection<T>, elements: C) where C : Swift.Collection, C.Element == Self.Collection.Element {
|
public init<C>(source: DateSection<T>, elements: C) where C : Swift.Collection, C.Element == Self.Collection.Element {
|
||||||
self.timestamp = source.timestamp
|
self.timestamp = source.timestamp
|
||||||
self.header = source.header
|
self.dateString = source.dateString
|
||||||
self.elements = Array(elements)
|
self.elements = Array(elements)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,20 +35,20 @@ public struct DateSection<T>: Differentiable, DifferentiableSection, Hashable wh
|
|||||||
let date = Date(timeIntervalSince1970: timestamp)
|
let date = Date(timeIntervalSince1970: timestamp)
|
||||||
let dateInRegion = DateInRegion(date, region: Region.current)
|
let dateInRegion = DateInRegion(date, region: Region.current)
|
||||||
if dateInRegion.isToday {
|
if dateInRegion.isToday {
|
||||||
self.header = NSLocalizedString("Today", comment: "")
|
self.dateString = NSLocalizedString("Today", comment: "")
|
||||||
}
|
}
|
||||||
else if dateInRegion.isYesterday {
|
else if dateInRegion.isYesterday {
|
||||||
self.header = NSLocalizedString("Yesterday", comment: "")
|
self.dateString = NSLocalizedString("Yesterday", comment: "")
|
||||||
} else if dateInRegion.isAfterDate(weekStart, granularity: .day) {
|
} else if dateInRegion.isAfterDate(weekStart, granularity: .day) {
|
||||||
formatter.dateFormat = "EEEE"
|
formatter.dateFormat = "EEEE"
|
||||||
self.header = formatter.string(from: date)
|
self.dateString = formatter.string(from: date)
|
||||||
} else if dateInRegion.isAfterDate(monthStart, orEqual: false, granularity: .day) {
|
} else if dateInRegion.isAfterDate(monthStart, orEqual: false, granularity: .day) {
|
||||||
formatter.dateStyle = .medium
|
formatter.dateStyle = .medium
|
||||||
formatter.timeStyle = .none
|
formatter.timeStyle = .none
|
||||||
self.header = formatter.string(from: date)
|
self.dateString = formatter.string(from: date)
|
||||||
} else {
|
} else {
|
||||||
formatter.dateFormat = "LLLL yyyy"
|
formatter.dateFormat = "LLLL yyyy"
|
||||||
self.header = formatter.string(from: date)
|
self.dateString = formatter.string(from: date)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.timestamp = timestamp
|
self.timestamp = timestamp
|
||||||
@ -74,7 +78,7 @@ public struct DateSection<T>: Differentiable, DifferentiableSection, Hashable wh
|
|||||||
// MARK: - Differentiable
|
// MARK: - Differentiable
|
||||||
|
|
||||||
public var differenceIdentifier: String {
|
public var differenceIdentifier: String {
|
||||||
return header
|
return dateString
|
||||||
}
|
}
|
||||||
|
|
||||||
public func isContentEqual(to source: DateSection<T>) -> Bool {
|
public func isContentEqual(to source: DateSection<T>) -> Bool {
|
||||||
|
|||||||
@ -1,12 +1,15 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public class PlateNumber {
|
public class PlateNumber {
|
||||||
private var number: String
|
private var number: String = ""
|
||||||
private var numberEnglish: String
|
private var numberEnglish: String = ""
|
||||||
|
|
||||||
|
private let maxLength = 9
|
||||||
|
private let mainPartLength = 6
|
||||||
|
private let isDigitMask = [false, true, true, true, false, false, true, true, true]
|
||||||
|
|
||||||
public init(_ string: String) {
|
public init(_ string: String) {
|
||||||
self.number = string
|
setNumber(string)
|
||||||
self.numberEnglish = String(self.number.map { Constants.pnLettersMap[$0] ?? $0 })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func asString() -> String {
|
public func asString() -> String {
|
||||||
@ -14,12 +17,56 @@ public class PlateNumber {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func mainPart() -> String {
|
public func mainPart() -> String {
|
||||||
let index = self.numberEnglish.index(self.numberEnglish.startIndex, offsetBy: 6)
|
return String(self.numberEnglish.prefix(mainPartLength))
|
||||||
return String(self.numberEnglish[..<index])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func region() -> String {
|
public func region() -> String {
|
||||||
let index = self.numberEnglish.index(self.numberEnglish.startIndex, offsetBy: 6)
|
guard numberEnglish.count > mainPartLength else {
|
||||||
return String(self.numberEnglish[index...])
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return String(self.numberEnglish.dropFirst(mainPartLength))
|
||||||
|
}
|
||||||
|
|
||||||
|
public var isValid: Bool {
|
||||||
|
number.count >= 8
|
||||||
|
}
|
||||||
|
|
||||||
|
public func setNumber(_ number: String) {
|
||||||
|
self.number = number
|
||||||
|
self.numberEnglish = String(self.number.map { Constants.pnLettersMap[$0] ?? $0 })
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - UIKeyInput
|
||||||
|
|
||||||
|
public var hasText: Bool {
|
||||||
|
return !number.isEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if number was changed
|
||||||
|
public func insertText(_ text: String) -> Bool {
|
||||||
|
guard number.count < maxLength, text.count == 1 else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Do proper validation
|
||||||
|
// if text.first?.isNumber == isDigitMask[number.count] {
|
||||||
|
// setNumber(number + text)
|
||||||
|
// return true
|
||||||
|
// } else {
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
|
||||||
|
setNumber(number + text)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
public func deleteBackward() -> Bool {
|
||||||
|
guard !number.isEmpty else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
setNumber(String(number.dropLast()))
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -364,7 +364,7 @@ public class Vehicle: Object, Decodable, Identifiable, Differentiable, Cloneable
|
|||||||
// MARK: - Exportable
|
// MARK: - Exportable
|
||||||
|
|
||||||
public static var csvHeader: String {
|
public static var csvHeader: String {
|
||||||
return "Model, Color, Year, Plate Number, VIN, STS, PTS, Added Date, Updated date, Locations"
|
return "Plate Number, Model, Color, Year, Owners, VIN, STS, PTS, Added Date, Updated date, Locations, Notes"
|
||||||
}
|
}
|
||||||
|
|
||||||
public var csvLine: String {
|
public var csvLine: String {
|
||||||
@ -379,16 +379,22 @@ public class Vehicle: Object, Decodable, Identifiable, Differentiable, Cloneable
|
|||||||
eventsString.append(location + "; " + date + "\r\n")
|
eventsString.append(location + "; " + date + "\r\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
return String(format: "\"%@\", %@, %d, %@, %@, %@, %@, \"%@\", \"%@\", \"%@\"",
|
let notesString = self.notes.reduce("") { partialResult, note in
|
||||||
|
partialResult + note.text + "\r\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
return String(format: "%@, \"%@\", %@, %d, %d, %@, %@, %@, \"%@\", \"%@\", \"%@\", \"%@\"",
|
||||||
|
self.number,
|
||||||
model,
|
model,
|
||||||
self.color ?? "",
|
self.color ?? "",
|
||||||
self.year,
|
self.year,
|
||||||
self.number,
|
self.ownershipPeriods.count,
|
||||||
self.vin1 ?? "",
|
self.vin1 ?? "",
|
||||||
self.sts ?? "",
|
self.sts ?? "",
|
||||||
self.pts ?? "",
|
self.pts ?? "",
|
||||||
added,
|
added,
|
||||||
updated,
|
updated,
|
||||||
eventsString)
|
eventsString,
|
||||||
|
notesString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user