base implementation of text cell view model. remove old implementation of same stuff
This commit is contained in:
parent
17561204c3
commit
4988dd65d9
|
|
@ -7,10 +7,17 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0A08E37F1F2A13BF00F9AB62 /* CellTextFieldToolBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A08E37E1F2A13BF00F9AB62 /* CellTextFieldToolBar.swift */; };
|
||||
248389A288C0A6D7914F0546 /* Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0ED4A1B793EAA73C9E95969F /* Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework */; };
|
||||
67779CBC206986390098F024 /* BaseTextFieldViewEvents+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67779CBB206986390098F024 /* BaseTextFieldViewEvents+Extensions.swift */; };
|
||||
67779CBD206986390098F024 /* BaseTextFieldViewEvents+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67779CBB206986390098F024 /* BaseTextFieldViewEvents+Extensions.swift */; };
|
||||
678D26AA206935B900B05B93 /* BiometricsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D26A9206935B900B05B93 /* BiometricsService.swift */; };
|
||||
67B4E6EB206941CE00E233EA /* BiometricsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 678D26A9206935B900B05B93 /* BiometricsService.swift */; };
|
||||
67B4E6F3206945D200E233EA /* BaseTextFieldViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B4E6F1206945D200E233EA /* BaseTextFieldViewModel.swift */; };
|
||||
67B4E6F6206945DD00E233EA /* OnlineValidationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B4E6F5206945DC00E233EA /* OnlineValidationResult.swift */; };
|
||||
67B4E6F7206945DD00E233EA /* OnlineValidationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B4E6F5206945DC00E233EA /* OnlineValidationResult.swift */; };
|
||||
67B4E6F9206945F900E233EA /* OnlineValidationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B4E6F8206945F900E233EA /* OnlineValidationState.swift */; };
|
||||
67B4E6FA206945F900E233EA /* OnlineValidationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B4E6F8206945F900E233EA /* OnlineValidationState.swift */; };
|
||||
67B4E6FB20694A4200E233EA /* BaseTextFieldViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 67B4E6F1206945D200E233EA /* BaseTextFieldViewModel.swift */; };
|
||||
A6CFB8D91F5024A500A42CC2 /* Error+NetworkingExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6CFB8D81F5024A500A42CC2 /* Error+NetworkingExtensions.swift */; };
|
||||
B326804BA6CC8B8BB136A46A /* Pods_LeadKitAdditions_LeadKitAdditions_iOS_Extensions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CFD5627139CAB27705F75C07 /* Pods_LeadKitAdditions_LeadKitAdditions_iOS_Extensions.framework */; };
|
||||
CAE698E81E968820000394B0 /* LeadKitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = CAE698E61E968820000394B0 /* LeadKitAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
|
|
@ -44,22 +51,10 @@
|
|||
ED0C34201F2906EC00FAE9FD /* UIBarButtonItem+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33E81F2906EC00FAE9FD /* UIBarButtonItem+Extensions.swift */; };
|
||||
ED0C34211F2906EC00FAE9FD /* UserDefaults+UserService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33E91F2906EC00FAE9FD /* UserDefaults+UserService.swift */; };
|
||||
ED0C34221F2906EC00FAE9FD /* UserDefaults+UserService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33E91F2906EC00FAE9FD /* UserDefaults+UserService.swift */; };
|
||||
ED0C34231F2906EC00FAE9FD /* CellFieldJumpingProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33EB1F2906EC00FAE9FD /* CellFieldJumpingProtocol.swift */; };
|
||||
ED0C34241F2906EC00FAE9FD /* CellFieldJumpingProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33EB1F2906EC00FAE9FD /* CellFieldJumpingProtocol.swift */; };
|
||||
ED0C34251F2906EC00FAE9FD /* CellFieldMaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33EC1F2906EC00FAE9FD /* CellFieldMaskProtocol.swift */; };
|
||||
ED0C34261F2906EC00FAE9FD /* CellFieldMaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33EC1F2906EC00FAE9FD /* CellFieldMaskProtocol.swift */; };
|
||||
ED0C34271F2906EC00FAE9FD /* CellFieldsToolBarProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33ED1F2906EC00FAE9FD /* CellFieldsToolBarProtocol.swift */; };
|
||||
ED0C34281F2906EC00FAE9FD /* CellFieldsToolBarProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33ED1F2906EC00FAE9FD /* CellFieldsToolBarProtocol.swift */; };
|
||||
ED0C34291F2906EC00FAE9FD /* CellFieldValidationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33EE1F2906EC00FAE9FD /* CellFieldValidationProtocol.swift */; };
|
||||
ED0C342A1F2906EC00FAE9FD /* CellFieldValidationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33EE1F2906EC00FAE9FD /* CellFieldValidationProtocol.swift */; };
|
||||
ED0C342B1F2906EC00FAE9FD /* FormCellViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33EF1F2906EC00FAE9FD /* FormCellViewModelProtocol.swift */; };
|
||||
ED0C342C1F2906EC00FAE9FD /* FormCellViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33EF1F2906EC00FAE9FD /* FormCellViewModelProtocol.swift */; };
|
||||
ED0C342D1F2906EC00FAE9FD /* BasePassCodeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33F11F2906EC00FAE9FD /* BasePassCodeService.swift */; };
|
||||
ED0C342E1F2906EC00FAE9FD /* BasePassCodeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33F11F2906EC00FAE9FD /* BasePassCodeService.swift */; };
|
||||
ED0C342F1F2906EC00FAE9FD /* BaseUserService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33F21F2906EC00FAE9FD /* BaseUserService.swift */; };
|
||||
ED0C34301F2906EC00FAE9FD /* BaseUserService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33F21F2906EC00FAE9FD /* BaseUserService.swift */; };
|
||||
ED0C34311F2906EC00FAE9FD /* CellFieldsJumpingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33F31F2906EC00FAE9FD /* CellFieldsJumpingService.swift */; };
|
||||
ED0C34321F2906EC00FAE9FD /* CellFieldsJumpingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33F31F2906EC00FAE9FD /* CellFieldsJumpingService.swift */; };
|
||||
ED0C34331F2906EC00FAE9FD /* MaskFieldTextProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33F41F2906EC00FAE9FD /* MaskFieldTextProxy.swift */; };
|
||||
ED0C34341F2906EC00FAE9FD /* MaskFieldTextProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33F41F2906EC00FAE9FD /* MaskFieldTextProxy.swift */; };
|
||||
ED0C34351F2906EC00FAE9FD /* ApiNetworkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33F61F2906EC00FAE9FD /* ApiNetworkService.swift */; };
|
||||
|
|
@ -74,20 +69,18 @@
|
|||
ED0C34421F2906EC00FAE9FD /* ValidationItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33FD1F2906EC00FAE9FD /* ValidationItem.swift */; };
|
||||
ED0C34431F2906EC00FAE9FD /* ValidationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33FE1F2906EC00FAE9FD /* ValidationService.swift */; };
|
||||
ED0C34441F2906EC00FAE9FD /* ValidationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C33FE1F2906EC00FAE9FD /* ValidationService.swift */; };
|
||||
ED0C34451F2906EC00FAE9FD /* CellTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C34011F2906EC00FAE9FD /* CellTextField.swift */; };
|
||||
ED0C34461F2906EC00FAE9FD /* CellTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C34011F2906EC00FAE9FD /* CellTextField.swift */; };
|
||||
ED0C34471F2906EC00FAE9FD /* CellTextFieldViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C34021F2906EC00FAE9FD /* CellTextFieldViewModel.swift */; };
|
||||
ED0C34481F2906EC00FAE9FD /* CellTextFieldViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0C34021F2906EC00FAE9FD /* CellTextFieldViewModel.swift */; };
|
||||
ED69E7E81F2AC7CC00C74895 /* CellTextFieldToolBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A08E37E1F2A13BF00F9AB62 /* CellTextFieldToolBar.swift */; };
|
||||
EFBD55921EBB9A980062AA63 /* LeadKitAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = CAE698E61E968820000394B0 /* LeadKitAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
01605ECA03749D49C27FA3DD /* Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.release.xcconfig"; path = "Pods/Target Support Files/Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions/Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.release.xcconfig"; sourceTree = "<group>"; };
|
||||
0A08E37E1F2A13BF00F9AB62 /* CellTextFieldToolBar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellTextFieldToolBar.swift; sourceTree = "<group>"; };
|
||||
0ED4A1B793EAA73C9E95969F /* Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKitAdditions_LeadKitAdditions_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
49738551AC648B0AFA74E57F /* Pods-LeadKitAdditions-LeadKitAdditions iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKitAdditions-LeadKitAdditions iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LeadKitAdditions-LeadKitAdditions iOS/Pods-LeadKitAdditions-LeadKitAdditions iOS.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
67779CBB206986390098F024 /* BaseTextFieldViewEvents+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BaseTextFieldViewEvents+Extensions.swift"; sourceTree = "<group>"; };
|
||||
678D26A9206935B900B05B93 /* BiometricsService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BiometricsService.swift; sourceTree = "<group>"; };
|
||||
67B4E6F1206945D200E233EA /* BaseTextFieldViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTextFieldViewModel.swift; sourceTree = "<group>"; };
|
||||
67B4E6F5206945DC00E233EA /* OnlineValidationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnlineValidationResult.swift; sourceTree = "<group>"; };
|
||||
67B4E6F8206945F900E233EA /* OnlineValidationState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnlineValidationState.swift; sourceTree = "<group>"; };
|
||||
7B7F57C5E5275C4D8DC71992 /* Pods_LeadKitAdditions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_LeadKitAdditions.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9D549FA5A7579702358E07DF /* Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.debug.xcconfig"; path = "Pods/Target Support Files/Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions/Pods-LeadKitAdditions-LeadKitAdditions iOS Extensions.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
A6CFB8D81F5024A500A42CC2 /* Error+NetworkingExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Error+NetworkingExtensions.swift"; sourceTree = "<group>"; };
|
||||
|
|
@ -110,14 +103,8 @@
|
|||
ED0C33E71F2906EC00FAE9FD /* Observable+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Observable+Extensions.swift"; sourceTree = "<group>"; };
|
||||
ED0C33E81F2906EC00FAE9FD /* UIBarButtonItem+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIBarButtonItem+Extensions.swift"; sourceTree = "<group>"; };
|
||||
ED0C33E91F2906EC00FAE9FD /* UserDefaults+UserService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UserDefaults+UserService.swift"; sourceTree = "<group>"; };
|
||||
ED0C33EB1F2906EC00FAE9FD /* CellFieldJumpingProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellFieldJumpingProtocol.swift; sourceTree = "<group>"; };
|
||||
ED0C33EC1F2906EC00FAE9FD /* CellFieldMaskProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellFieldMaskProtocol.swift; sourceTree = "<group>"; };
|
||||
ED0C33ED1F2906EC00FAE9FD /* CellFieldsToolBarProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellFieldsToolBarProtocol.swift; sourceTree = "<group>"; };
|
||||
ED0C33EE1F2906EC00FAE9FD /* CellFieldValidationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellFieldValidationProtocol.swift; sourceTree = "<group>"; };
|
||||
ED0C33EF1F2906EC00FAE9FD /* FormCellViewModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormCellViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
ED0C33F11F2906EC00FAE9FD /* BasePassCodeService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasePassCodeService.swift; sourceTree = "<group>"; };
|
||||
ED0C33F21F2906EC00FAE9FD /* BaseUserService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseUserService.swift; sourceTree = "<group>"; };
|
||||
ED0C33F31F2906EC00FAE9FD /* CellFieldsJumpingService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellFieldsJumpingService.swift; sourceTree = "<group>"; };
|
||||
ED0C33F41F2906EC00FAE9FD /* MaskFieldTextProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MaskFieldTextProxy.swift; sourceTree = "<group>"; };
|
||||
ED0C33F61F2906EC00FAE9FD /* ApiNetworkService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiNetworkService.swift; sourceTree = "<group>"; };
|
||||
ED0C33F71F2906EC00FAE9FD /* DefaultNetworkService+ActivityIndicator+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DefaultNetworkService+ActivityIndicator+Extension.swift"; sourceTree = "<group>"; };
|
||||
|
|
@ -126,8 +113,6 @@
|
|||
ED0C33FC1F2906EC00FAE9FD /* ValidationError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidationError.swift; sourceTree = "<group>"; };
|
||||
ED0C33FD1F2906EC00FAE9FD /* ValidationItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidationItem.swift; sourceTree = "<group>"; };
|
||||
ED0C33FE1F2906EC00FAE9FD /* ValidationService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValidationService.swift; sourceTree = "<group>"; };
|
||||
ED0C34011F2906EC00FAE9FD /* CellTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellTextField.swift; sourceTree = "<group>"; };
|
||||
ED0C34021F2906EC00FAE9FD /* CellTextFieldViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellTextFieldViewModel.swift; sourceTree = "<group>"; };
|
||||
EFBD55701EBB87100062AA63 /* LeadKitAdditions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LeadKitAdditions.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
EFBD55781EBB893F0062AA63 /* Info-iOS-Extensions.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS-Extensions.plist"; sourceTree = "<group>"; };
|
||||
EFBD55791EBB893F0062AA63 /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = "<group>"; };
|
||||
|
|
@ -153,6 +138,22 @@
|
|||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
67B4E6F0206945D200E233EA /* BaseTextFieldViewModel */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
67B4E6F1206945D200E233EA /* BaseTextFieldViewModel.swift */,
|
||||
);
|
||||
path = BaseTextFieldViewModel;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
67B4E6F4206945DC00E233EA /* ValidationService */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
67B4E6F5206945DC00E233EA /* OnlineValidationResult.swift */,
|
||||
);
|
||||
path = ValidationService;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
A3117951840B8B7D2E7A8A80 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -202,6 +203,7 @@
|
|||
ED0C33D21F2906EC00FAE9FD /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
67B4E6F0206945D200E233EA /* BaseTextFieldViewModel */,
|
||||
ED0C33D31F2906EC00FAE9FD /* ApiResponse.swift */,
|
||||
ED0C33D41F2906EC00FAE9FD /* BaseDateFormatter.swift */,
|
||||
ED0C33D51F2906EC00FAE9FD /* LoadingBarButton.swift */,
|
||||
|
|
@ -271,6 +273,7 @@
|
|||
ED0C33E81F2906EC00FAE9FD /* UIBarButtonItem+Extensions.swift */,
|
||||
ED0C33E91F2906EC00FAE9FD /* UserDefaults+UserService.swift */,
|
||||
A6CFB8D81F5024A500A42CC2 /* Error+NetworkingExtensions.swift */,
|
||||
67779CBB206986390098F024 /* BaseTextFieldViewEvents+Extensions.swift */,
|
||||
);
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -278,11 +281,7 @@
|
|||
ED0C33EA1F2906EC00FAE9FD /* Protocols */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ED0C33EB1F2906EC00FAE9FD /* CellFieldJumpingProtocol.swift */,
|
||||
ED0C33EC1F2906EC00FAE9FD /* CellFieldMaskProtocol.swift */,
|
||||
ED0C33EE1F2906EC00FAE9FD /* CellFieldValidationProtocol.swift */,
|
||||
ED0C33ED1F2906EC00FAE9FD /* CellFieldsToolBarProtocol.swift */,
|
||||
ED0C33EF1F2906EC00FAE9FD /* FormCellViewModelProtocol.swift */,
|
||||
67B4E6F4206945DC00E233EA /* ValidationService */,
|
||||
);
|
||||
path = Protocols;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -294,7 +293,6 @@
|
|||
ED0C33FB1F2906EC00FAE9FD /* ValidationService */,
|
||||
ED0C33F11F2906EC00FAE9FD /* BasePassCodeService.swift */,
|
||||
ED0C33F21F2906EC00FAE9FD /* BaseUserService.swift */,
|
||||
ED0C33F31F2906EC00FAE9FD /* CellFieldsJumpingService.swift */,
|
||||
ED0C33F41F2906EC00FAE9FD /* MaskFieldTextProxy.swift */,
|
||||
678D26A9206935B900B05B93 /* BiometricsService.swift */,
|
||||
);
|
||||
|
|
@ -315,6 +313,7 @@
|
|||
ED0C33FB1F2906EC00FAE9FD /* ValidationService */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
67B4E6F8206945F900E233EA /* OnlineValidationState.swift */,
|
||||
ED0C33FC1F2906EC00FAE9FD /* ValidationError.swift */,
|
||||
ED0C33FD1F2906EC00FAE9FD /* ValidationItem.swift */,
|
||||
ED0C33FE1F2906EC00FAE9FD /* ValidationService.swift */,
|
||||
|
|
@ -325,21 +324,10 @@
|
|||
ED0C33FF1F2906EC00FAE9FD /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0A08E37E1F2A13BF00F9AB62 /* CellTextFieldToolBar.swift */,
|
||||
ED0C34001F2906EC00FAE9FD /* CellTextField */,
|
||||
);
|
||||
path = Views;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
ED0C34001F2906EC00FAE9FD /* CellTextField */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ED0C34011F2906EC00FAE9FD /* CellTextField.swift */,
|
||||
ED0C34021F2906EC00FAE9FD /* CellTextFieldViewModel.swift */,
|
||||
);
|
||||
path = CellTextField;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F8A65FEC7C0EB4B93746E50F /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -573,39 +561,34 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
ED0C34171F2906EC00FAE9FD /* ApiError.swift in Sources */,
|
||||
67B4E6FB20694A4200E233EA /* BaseTextFieldViewModel.swift in Sources */,
|
||||
ED0C343B1F2906EC00FAE9FD /* DefaultNetworkService.swift in Sources */,
|
||||
ED0C34351F2906EC00FAE9FD /* ApiNetworkService.swift in Sources */,
|
||||
ED0C340F1F2906EC00FAE9FD /* PassCodeHolderProtocol.swift in Sources */,
|
||||
ED0C343F1F2906EC00FAE9FD /* ValidationError.swift in Sources */,
|
||||
ED0C342F1F2906EC00FAE9FD /* BaseUserService.swift in Sources */,
|
||||
ED0C34231F2906EC00FAE9FD /* CellFieldJumpingProtocol.swift in Sources */,
|
||||
678D26AA206935B900B05B93 /* BiometricsService.swift in Sources */,
|
||||
ED0C34411F2906EC00FAE9FD /* ValidationItem.swift in Sources */,
|
||||
ED0C341F1F2906EC00FAE9FD /* UIBarButtonItem+Extensions.swift in Sources */,
|
||||
ED0C34091F2906EC00FAE9FD /* PassCodeConfiguration.swift in Sources */,
|
||||
ED0C342B1F2906EC00FAE9FD /* FormCellViewModelProtocol.swift in Sources */,
|
||||
ED0C341D1F2906EC00FAE9FD /* Observable+Extensions.swift in Sources */,
|
||||
ED0C34471F2906EC00FAE9FD /* CellTextFieldViewModel.swift in Sources */,
|
||||
ED0C34191F2906EC00FAE9FD /* ApiErrorProtocol.swift in Sources */,
|
||||
ED0C34131F2906EC00FAE9FD /* BasePassCodeViewController.swift in Sources */,
|
||||
ED0C342D1F2906EC00FAE9FD /* BasePassCodeService.swift in Sources */,
|
||||
67B4E6F9206945F900E233EA /* OnlineValidationState.swift in Sources */,
|
||||
67779CBC206986390098F024 /* BaseTextFieldViewEvents+Extensions.swift in Sources */,
|
||||
ED0C340D1F2906EC00FAE9FD /* PassCodeHolder.swift in Sources */,
|
||||
ED0C34451F2906EC00FAE9FD /* CellTextField.swift in Sources */,
|
||||
ED0C34271F2906EC00FAE9FD /* CellFieldsToolBarProtocol.swift in Sources */,
|
||||
ED0C34291F2906EC00FAE9FD /* CellFieldValidationProtocol.swift in Sources */,
|
||||
0A08E37F1F2A13BF00F9AB62 /* CellTextFieldToolBar.swift in Sources */,
|
||||
ED0C34031F2906EC00FAE9FD /* ApiResponse.swift in Sources */,
|
||||
A6CFB8D91F5024A500A42CC2 /* Error+NetworkingExtensions.swift in Sources */,
|
||||
ED0C34071F2906EC00FAE9FD /* LoadingBarButton.swift in Sources */,
|
||||
ED0C34251F2906EC00FAE9FD /* CellFieldMaskProtocol.swift in Sources */,
|
||||
ED0C34211F2906EC00FAE9FD /* UserDefaults+UserService.swift in Sources */,
|
||||
ED0C34391F2906EC00FAE9FD /* DefaultNetworkService+ActivityIndicator.swift in Sources */,
|
||||
ED0C34311F2906EC00FAE9FD /* CellFieldsJumpingService.swift in Sources */,
|
||||
ED0C34111F2906EC00FAE9FD /* PassCodeValidationResult.swift in Sources */,
|
||||
ED0C34051F2906EC00FAE9FD /* BaseDateFormatter.swift in Sources */,
|
||||
ED0C34431F2906EC00FAE9FD /* ValidationService.swift in Sources */,
|
||||
ED0C34331F2906EC00FAE9FD /* MaskFieldTextProxy.swift in Sources */,
|
||||
ED0C340B1F2906EC00FAE9FD /* PassCodeError.swift in Sources */,
|
||||
67B4E6F6206945DD00E233EA /* OnlineValidationResult.swift in Sources */,
|
||||
ED0C34151F2906EC00FAE9FD /* BasePassCodeViewModel.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
@ -616,32 +599,27 @@
|
|||
files = (
|
||||
ED0C34181F2906EC00FAE9FD /* ApiError.swift in Sources */,
|
||||
ED0C343C1F2906EC00FAE9FD /* DefaultNetworkService.swift in Sources */,
|
||||
67779CBD206986390098F024 /* BaseTextFieldViewEvents+Extensions.swift in Sources */,
|
||||
ED0C34361F2906EC00FAE9FD /* ApiNetworkService.swift in Sources */,
|
||||
ED0C34101F2906EC00FAE9FD /* PassCodeHolderProtocol.swift in Sources */,
|
||||
ED0C34401F2906EC00FAE9FD /* ValidationError.swift in Sources */,
|
||||
ED0C34301F2906EC00FAE9FD /* BaseUserService.swift in Sources */,
|
||||
ED0C34241F2906EC00FAE9FD /* CellFieldJumpingProtocol.swift in Sources */,
|
||||
ED0C34421F2906EC00FAE9FD /* ValidationItem.swift in Sources */,
|
||||
ED0C34201F2906EC00FAE9FD /* UIBarButtonItem+Extensions.swift in Sources */,
|
||||
ED0C340A1F2906EC00FAE9FD /* PassCodeConfiguration.swift in Sources */,
|
||||
ED0C342C1F2906EC00FAE9FD /* FormCellViewModelProtocol.swift in Sources */,
|
||||
67B4E6FA206945F900E233EA /* OnlineValidationState.swift in Sources */,
|
||||
ED0C34381F2906EC00FAE9FD /* DefaultNetworkService+ActivityIndicator+Extension.swift in Sources */,
|
||||
ED0C341E1F2906EC00FAE9FD /* Observable+Extensions.swift in Sources */,
|
||||
ED0C34481F2906EC00FAE9FD /* CellTextFieldViewModel.swift in Sources */,
|
||||
67B4E6EB206941CE00E233EA /* BiometricsService.swift in Sources */,
|
||||
ED0C341A1F2906EC00FAE9FD /* ApiErrorProtocol.swift in Sources */,
|
||||
ED0C34141F2906EC00FAE9FD /* BasePassCodeViewController.swift in Sources */,
|
||||
ED0C342E1F2906EC00FAE9FD /* BasePassCodeService.swift in Sources */,
|
||||
67B4E6F7206945DD00E233EA /* OnlineValidationResult.swift in Sources */,
|
||||
ED0C340E1F2906EC00FAE9FD /* PassCodeHolder.swift in Sources */,
|
||||
ED0C34461F2906EC00FAE9FD /* CellTextField.swift in Sources */,
|
||||
ED0C34281F2906EC00FAE9FD /* CellFieldsToolBarProtocol.swift in Sources */,
|
||||
ED69E7E81F2AC7CC00C74895 /* CellTextFieldToolBar.swift in Sources */,
|
||||
ED0C342A1F2906EC00FAE9FD /* CellFieldValidationProtocol.swift in Sources */,
|
||||
67B4E6F3206945D200E233EA /* BaseTextFieldViewModel.swift in Sources */,
|
||||
ED0C34041F2906EC00FAE9FD /* ApiResponse.swift in Sources */,
|
||||
ED0C34081F2906EC00FAE9FD /* LoadingBarButton.swift in Sources */,
|
||||
ED0C34261F2906EC00FAE9FD /* CellFieldMaskProtocol.swift in Sources */,
|
||||
ED0C34221F2906EC00FAE9FD /* UserDefaults+UserService.swift in Sources */,
|
||||
ED0C34321F2906EC00FAE9FD /* CellFieldsJumpingService.swift in Sources */,
|
||||
ED0C34121F2906EC00FAE9FD /* PassCodeValidationResult.swift in Sources */,
|
||||
ED0C34061F2906EC00FAE9FD /* BaseDateFormatter.swift in Sources */,
|
||||
ED0C34441F2906EC00FAE9FD /* ValidationService.swift in Sources */,
|
||||
|
|
|
|||
4
Podfile
4
Podfile
|
|
@ -15,7 +15,7 @@ abstract_target 'LeadKitAdditions' do
|
|||
|
||||
use_frameworks!
|
||||
|
||||
pod "LeadKit", '~> 0.6.0'
|
||||
pod 'LeadKit', :git => 'https://github.com/TouchInstinct/LeadKit', :branch => 'feature/text_field_view_model'
|
||||
end
|
||||
|
||||
target 'LeadKitAdditions iOS Extensions' do
|
||||
|
|
@ -23,7 +23,7 @@ abstract_target 'LeadKitAdditions' do
|
|||
|
||||
use_frameworks!
|
||||
|
||||
pod "LeadKit/Core-iOS-Extension", '~> 0.6.0'
|
||||
pod "LeadKit/Core-iOS-Extension", :git => 'https://github.com/TouchInstinct/LeadKit', :branch => 'feature/text_field_view_model'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
70
Podfile.lock
70
Podfile.lock
|
|
@ -1,7 +1,7 @@
|
|||
PODS:
|
||||
- Alamofire (4.7.0)
|
||||
- CocoaLumberjack/Default (3.3.0)
|
||||
- CocoaLumberjack/Swift (3.3.0):
|
||||
- CocoaLumberjack/Default (3.4.1)
|
||||
- CocoaLumberjack/Swift (3.4.1):
|
||||
- CocoaLumberjack/Default
|
||||
- IDZSwiftCommonCrypto (0.10.0)
|
||||
- InputMask (3.0.0)
|
||||
|
|
@ -9,58 +9,68 @@ PODS:
|
|||
- LeadKit (0.6.7):
|
||||
- LeadKit/Core (= 0.6.7)
|
||||
- LeadKit/Core (0.6.7):
|
||||
- CocoaLumberjack/Swift (~> 3.3.0)
|
||||
- ObjectMapper (~> 3.0.0)
|
||||
- RxAlamofire (= 4.0.0)
|
||||
- RxCocoa (= 4.0.0)
|
||||
- RxSwift (= 4.0.0)
|
||||
- TableKit (~> 2.5.0)
|
||||
- CocoaLumberjack/Swift (~> 3.4)
|
||||
- ObjectMapper (~> 3.0)
|
||||
- RxAlamofire (~> 4.1)
|
||||
- RxCocoa (~> 4.1)
|
||||
- RxSwift (~> 4.1)
|
||||
- TableKit (~> 2.6)
|
||||
- UIScrollView-InfiniteScroll (~> 1.0.0)
|
||||
- LeadKit/Core-iOS-Extension (0.6.7):
|
||||
- CocoaLumberjack/Swift (~> 3.3.0)
|
||||
- ObjectMapper (~> 3.0.0)
|
||||
- RxAlamofire (= 4.0.0)
|
||||
- RxCocoa (= 4.0.0)
|
||||
- RxSwift (= 4.0.0)
|
||||
- ObjectMapper (3.0.0)
|
||||
- RxAlamofire (4.0.0):
|
||||
- RxAlamofire/Core (= 4.0.0)
|
||||
- RxAlamofire/Core (4.0.0):
|
||||
- CocoaLumberjack/Swift (~> 3.4)
|
||||
- ObjectMapper (~> 3.0)
|
||||
- RxAlamofire (~> 4.1)
|
||||
- RxCocoa (~> 4.1)
|
||||
- RxSwift (~> 4.1)
|
||||
- ObjectMapper (3.1.0)
|
||||
- RxAlamofire (4.1.0):
|
||||
- RxAlamofire/Core (= 4.1.0)
|
||||
- RxAlamofire/Core (4.1.0):
|
||||
- Alamofire (~> 4.5)
|
||||
- RxSwift (~> 4.0)
|
||||
- RxCocoa (4.0.0):
|
||||
- RxCocoa (4.1.2):
|
||||
- RxSwift (~> 4.0)
|
||||
- RxSwift (4.0.0)
|
||||
- RxSwift (4.1.2)
|
||||
- SwiftLint (0.25.0)
|
||||
- SwiftValidator (5.0.0)
|
||||
- TableKit (2.5.0)
|
||||
- TableKit (2.6.0)
|
||||
- UIScrollView-InfiniteScroll (1.0.2)
|
||||
|
||||
DEPENDENCIES:
|
||||
- IDZSwiftCommonCrypto
|
||||
- InputMask (= 3.0.0)
|
||||
- KeychainAccess (= 3.1.0)
|
||||
- LeadKit (~> 0.6.0)
|
||||
- LeadKit/Core-iOS-Extension (~> 0.6.0)
|
||||
- LeadKit (from `https://github.com/TouchInstinct/LeadKit`, branch `feature/text_field_view_model`)
|
||||
- LeadKit/Core-iOS-Extension (from `https://github.com/TouchInstinct/LeadKit`, branch `feature/text_field_view_model`)
|
||||
- SwiftLint (~> 0.25)
|
||||
- SwiftValidator (= 5.0.0)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
LeadKit:
|
||||
:branch: feature/text_field_view_model
|
||||
:git: https://github.com/TouchInstinct/LeadKit
|
||||
|
||||
CHECKOUT OPTIONS:
|
||||
LeadKit:
|
||||
:commit: 463279d2865b2e77bd727e18d7bc9793c9539160
|
||||
:git: https://github.com/TouchInstinct/LeadKit
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Alamofire: 907e0a98eb68cdb7f9d1f541a563d6ac5dc77b25
|
||||
CocoaLumberjack: 3c8c74683302f9012bb168e1c4b7ae3c0b558431
|
||||
CocoaLumberjack: 2e258a064cacc8eb9a2aca318e24d02a0a7fd56d
|
||||
IDZSwiftCommonCrypto: 4eef2c46e262dfbcbc1fd76365e066336680ad7d
|
||||
InputMask: 37c273bde6705187d80cf0b4240cb42ea92096c3
|
||||
KeychainAccess: 94c5540b32eabf7bc32bfb976a268e8ea05fd6da
|
||||
LeadKit: 7d84bb111e7b6aca0c5d3ac5aee6f99d375d94d4
|
||||
ObjectMapper: 92230db59bf8f341a5c3a3cf0b9fbdde3cf0d87f
|
||||
RxAlamofire: 6ea579ac53bf14cb4bc7049a3866e5a769989b1d
|
||||
RxCocoa: d62846ca96495d862fa4c59ea7d87e5031d7340e
|
||||
RxSwift: fd680d75283beb5e2559486f3c0ff852f0d35334
|
||||
LeadKit: d6dd4ec58e535c3a76cbc78b53d283278f61cbfa
|
||||
ObjectMapper: 20505058f54e5c3ca69e1d6de9897d152a5369a6
|
||||
RxAlamofire: 96a2bff4694a1609bb59c57b53d99ea7a0ddc64a
|
||||
RxCocoa: d88ba0f1f6abf040011a9eb4b539324fc426843a
|
||||
RxSwift: e49536837d9901277638493ea537394d4b55f570
|
||||
SwiftLint: e14651157288e9e01d6e1a71db7014fb5744a8ea
|
||||
SwiftValidator: 46cdd2061962df3ee8bab3c536dea9b34191d459
|
||||
TableKit: 42d4dff2944f273cdeec2ef6352064eb6a9a355b
|
||||
TableKit: 61880e4c13ac0ba396a308fcb1ae48f6dec8b458
|
||||
UIScrollView-InfiniteScroll: c132d6d5851daff229ab4a1060ccf70a05a051c9
|
||||
|
||||
PODFILE CHECKSUM: d2f39766e2e1169f9216c0dc43b52873927b77cc
|
||||
PODFILE CHECKSUM: d35945b0ded474b18dc52df4f9b12cb7fdf59377
|
||||
|
||||
COCOAPODS: 1.4.0
|
||||
|
|
|
|||
|
|
@ -0,0 +1,169 @@
|
|||
//
|
||||
// Copyright (c) 2018 Touch Instinct
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the Software), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
import LeadKit
|
||||
import RxSwift
|
||||
import RxCocoa
|
||||
|
||||
/// Base implementation of TextFieldViewEvents.
|
||||
open class BaseTextFieldViewEvents: TextFieldViewEvents {
|
||||
|
||||
public let textChangedDriver: Driver<String?>
|
||||
|
||||
/// Memberwise initializer.
|
||||
///
|
||||
/// - Parameter textChangedDriver: Driver that emits text changes from a view.
|
||||
public init(textChangedDriver: Driver<String?>) {
|
||||
self.textChangedDriver = textChangedDriver
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Base implementation of text field view model events.
|
||||
open class BaseTextFieldViewModelEvents: TextFieldViewModelEvents {
|
||||
|
||||
public let setTextDriver: Driver<String?>
|
||||
public let changeValidationStateDriver: Driver<ValidationItemState>
|
||||
public let changeOnlineValidationStateDriver: Driver<OnlineValidationState>
|
||||
|
||||
/// Memberwise initializer.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - setTextDriver: Driver that emit text that should be set inside a view.
|
||||
/// - changeValidationStateDriver: Driver that emit validation state changes events.
|
||||
/// - changeOnlineValidationStateDriver: Driver that emit online validation state changes events.
|
||||
public init(setTextDriver: Driver<String?>,
|
||||
changeValidationStateDriver: Driver<ValidationItemState>,
|
||||
changeOnlineValidationStateDriver: Driver<OnlineValidationState>) {
|
||||
|
||||
self.setTextDriver = setTextDriver
|
||||
self.changeValidationStateDriver = changeValidationStateDriver
|
||||
self.changeOnlineValidationStateDriver = changeOnlineValidationStateDriver
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
import SwiftValidator
|
||||
|
||||
public extension BaseTextFieldViewModelEvents {
|
||||
|
||||
/// Method that binds text driver to validation service via validation rules.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - textDriver: Driver that emits text changes.
|
||||
/// - rules: Rules to validate for.
|
||||
/// - validationService: Validation service to register in.
|
||||
/// - Returns: Driver that emit validation state changes.
|
||||
static func offlineValidationDriver(with textDriver: Driver<String?>,
|
||||
using rules: [Rule] = [RequiredRule()],
|
||||
in validationService: ValidationService) -> Driver<ValidationItemState> {
|
||||
|
||||
let validationItem = ValidationItem(rules: rules, textDriver: textDriver)
|
||||
|
||||
validationService.register(item: validationItem)
|
||||
|
||||
let validationStateDriver = validationItem
|
||||
.validationStateObservable
|
||||
.asDriver(onErrorJustReturn: .initial)
|
||||
|
||||
return validationStateDriver
|
||||
}
|
||||
|
||||
typealias OnlineValidationClosure = (String) -> Single<OnlineValidationResult>
|
||||
|
||||
/// Method that binds text driver to validation chain (offline validation -> online validation)
|
||||
/// and returns online validation state driver.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - textDriver: Driver that emits text changes.
|
||||
/// - offlineRules: Rules to validate before online validation will be requested.
|
||||
/// - validationClosure: Closure that will be called for online validation request.
|
||||
/// - Returns: Driver that emit online validation state changes.
|
||||
static func onlineValidationDriver(with textDriver: Driver<String?>,
|
||||
using offlineRules: [Rule] = [],
|
||||
validationClosure: @escaping OnlineValidationClosure) -> Driver<OnlineValidationState> {
|
||||
|
||||
return textDriver.flatMap { string -> Driver<OnlineValidationState> in
|
||||
guard let nonEmptyString = string, !nonEmptyString.isEmpty else {
|
||||
return .just(.initial)
|
||||
}
|
||||
|
||||
let passedRules = offlineRules
|
||||
.map { $0.validate(nonEmptyString) }
|
||||
.reduce(true) { $0 && $1 }
|
||||
|
||||
guard passedRules else {
|
||||
return .just(.initial)
|
||||
}
|
||||
|
||||
let validationDriver = validationClosure(nonEmptyString).map { result -> OnlineValidationState in
|
||||
if result.isValid {
|
||||
return .valid
|
||||
} else {
|
||||
return .invalid(error: result.error)
|
||||
}
|
||||
}
|
||||
.asDriver(onErrorJustReturn: .initial)
|
||||
|
||||
return Driver.merge([.just(.initial), .just(.processing), validationDriver])
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience initializer with offline and online validation.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - binding: Data model field binding.
|
||||
/// - rules: Rules to validate before online validation will be requested.
|
||||
/// - validationService: Validation service to register in.
|
||||
/// - onlineValidationClosure: Closure that will be called for online validation request.
|
||||
/// - onlineValidationThrottle: Throttling duration for each text change.
|
||||
convenience init<T>(binding: DataModelFieldBinding<T>,
|
||||
rules: [Rule] = [RequiredRule()],
|
||||
validationService: ValidationService,
|
||||
onlineValidationClosure: OnlineValidationClosure? = nil,
|
||||
onlineValidationThrottle: RxTimeInterval = 0.5) {
|
||||
|
||||
let dataModelFieldDriver = binding.fieldDriver
|
||||
|
||||
let offlineValidationDriver = BaseTextFieldViewModelEvents.offlineValidationDriver(with: dataModelFieldDriver,
|
||||
using: rules,
|
||||
in: validationService)
|
||||
|
||||
let onlineValidationDriver: Driver<OnlineValidationState>
|
||||
|
||||
if let onlineValidationClosure = onlineValidationClosure {
|
||||
let throttledTextDriver = dataModelFieldDriver.throttle(onlineValidationThrottle)
|
||||
|
||||
onlineValidationDriver = BaseTextFieldViewModelEvents
|
||||
.onlineValidationDriver(with: throttledTextDriver,
|
||||
using: rules,
|
||||
validationClosure: onlineValidationClosure)
|
||||
} else {
|
||||
onlineValidationDriver = .just(.initial)
|
||||
}
|
||||
|
||||
self.init(setTextDriver: dataModelFieldDriver,
|
||||
changeValidationStateDriver: offlineValidationDriver,
|
||||
changeOnlineValidationStateDriver: onlineValidationDriver)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// Copyright (c) 2018 Touch Instinct
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the Software), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
import RxSwift
|
||||
|
||||
public extension BaseTextFieldViewEvents {
|
||||
|
||||
/// Convenience init with UITextField as textChangedDriver.
|
||||
///
|
||||
/// - Parameter textField: UITextField to use for text events.
|
||||
convenience init(textField: UITextField) {
|
||||
let textChangedDriver = textField.rx
|
||||
.text
|
||||
.asDriver()
|
||||
.distinctUntilChanged { $0 == $1 }
|
||||
|
||||
self.init(textChangedDriver: textChangedDriver)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
import RxSwift
|
||||
import RxCocoa
|
||||
import UIKit
|
||||
|
||||
typealias ItemSettingsBlock<UIItem> = (UIItem) -> Void where UIItem: UIView
|
||||
|
||||
protocol CellFieldJumpingProtocol: FormCellViewModelProtocol {
|
||||
|
||||
var toolBar: UIToolbar? { get set }
|
||||
|
||||
var shouldGoForward: PublishSubject<Void> { get }
|
||||
|
||||
var shouldBecomeFirstResponder: PublishSubject<Void> { get }
|
||||
var shouldResignFirstResponder: PublishSubject<Void> { get }
|
||||
|
||||
var returnButtonType: UIReturnKeyType { get set }
|
||||
|
||||
}
|
||||
|
||||
extension CellFieldJumpingProtocol {
|
||||
|
||||
func bind(for textField: UITextField, to disposeBag: DisposeBag) {
|
||||
shouldResignFirstResponder.asObservable()
|
||||
.observeOn(MainScheduler.instance)
|
||||
.subscribe(onNext: { [weak textField] _ in
|
||||
textField?.resignFirstResponder()
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
shouldBecomeFirstResponder.asObservable()
|
||||
.observeOn(MainScheduler.instance)
|
||||
.subscribe(onNext: { [weak textField] _ in
|
||||
textField?.becomeFirstResponder()
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
protocol CellFieldMaskProtocol {
|
||||
|
||||
var haveMask: Bool { get }
|
||||
var maskFieldTextProxy: MaskFieldTextProxy? { get set }
|
||||
|
||||
}
|
||||
|
||||
extension CellFieldMaskProtocol {
|
||||
|
||||
var haveMask: Bool {
|
||||
return maskFieldTextProxy != nil
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
protocol CellFieldValidationProtocol {
|
||||
|
||||
var validationItem: ValidationItem? { get set }
|
||||
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
protocol CellFieldsToolBarProtocol: class {
|
||||
|
||||
var needArrows: Bool { get set }
|
||||
|
||||
var canGoForward: Bool { get set }
|
||||
var canGoBackward: Bool { get set }
|
||||
|
||||
var shouldGoForward: PublishSubject<Void> { get }
|
||||
var shouldGoBackward: PublishSubject<Void> { get }
|
||||
|
||||
var shouldEndEditing: PublishSubject<Void> { get }
|
||||
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
import RxCocoa
|
||||
import RxSwift
|
||||
|
||||
protocol FormCellViewModelProtocol: class {
|
||||
var isActive: Bool { get set }
|
||||
}
|
||||
|
||||
extension FormCellViewModelProtocol {
|
||||
|
||||
func activate(_ isActive: Bool) -> Self {
|
||||
self.isActive = isActive
|
||||
return self
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
//
|
||||
// Copyright (c) 2018 Touch Instinct
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the Software), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Prototol with two fields that describes result of online validation.
|
||||
public protocol OnlineValidationResult {
|
||||
|
||||
/// Contains true if online validation did passed.
|
||||
var isValid: Bool { get }
|
||||
|
||||
/// May contain an error if validation did failed.
|
||||
var error: Error? { get }
|
||||
|
||||
}
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
import RxSwift
|
||||
import UIKit
|
||||
|
||||
struct CellFieldsJumpingServiceConfig {
|
||||
|
||||
var toolBarNeedArrows = true
|
||||
|
||||
init() {}
|
||||
|
||||
static var `default`: CellFieldsJumpingServiceConfig {
|
||||
return CellFieldsJumpingServiceConfig()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class CellFieldsJumpingService {
|
||||
|
||||
private var disposeBag = DisposeBag()
|
||||
|
||||
// MARK: - Private properties
|
||||
|
||||
private var cellFields: [CellFieldJumpingProtocol] = []
|
||||
|
||||
// MARK: - Public propertries
|
||||
|
||||
var config: CellFieldsJumpingServiceConfig = .default {
|
||||
didSet {
|
||||
configure()
|
||||
}
|
||||
}
|
||||
|
||||
let didDone = PublishSubject<Void>()
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
init() {}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func removeAll() {
|
||||
cellFields.removeAll()
|
||||
disposeBag = DisposeBag()
|
||||
}
|
||||
|
||||
func add(fieled: CellFieldJumpingProtocol, shouldConfigure: Bool = true) {
|
||||
add(fieleds: [fieled], shouldConfigure: shouldConfigure)
|
||||
}
|
||||
|
||||
func add(fieleds: [CellFieldJumpingProtocol], shouldConfigure: Bool = true) {
|
||||
cellFields += fieleds
|
||||
|
||||
if shouldConfigure {
|
||||
configure()
|
||||
}
|
||||
}
|
||||
|
||||
func configure() {
|
||||
disposeBag = DisposeBag()
|
||||
|
||||
let cellFields = self.cellFields
|
||||
|
||||
cellFields
|
||||
.filter { $0.isActive }
|
||||
.enumerated()
|
||||
.forEach { offset, field in
|
||||
field.toolBar = toolBar(for: field, with: offset)
|
||||
field.returnButtonType = .next
|
||||
|
||||
field.shouldGoForward.asObservable()
|
||||
.subscribe(onNext: { [weak self] in
|
||||
self?.shouldGoForwardAction(from: offset)
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
}
|
||||
|
||||
cellFields.lastActive?.returnButtonType = .done
|
||||
}
|
||||
|
||||
private func toolBar(for field: CellFieldJumpingProtocol, with index: Int) -> UIToolbar {
|
||||
let toolBar = CellTextFieldToolBar()
|
||||
toolBar.canGoForward = cellFields.nextActive(from: index) != nil
|
||||
toolBar.canGoBackward = cellFields.previousActive(from: index) != nil
|
||||
|
||||
toolBar.needArrows = config.toolBarNeedArrows
|
||||
|
||||
toolBar.shouldGoForward.asObservable()
|
||||
.subscribe(onNext: { [weak self] in
|
||||
self?.shouldGoForwardAction(from: index)
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
toolBar.shouldGoBackward
|
||||
.subscribe(onNext: { [weak self] in
|
||||
if let previousActive = self?.cellFields.previousActive(from: index) {
|
||||
previousActive.shouldBecomeFirstResponder.onNext(Void())
|
||||
}
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
toolBar.shouldEndEditing
|
||||
.subscribe(onNext: { [field] in
|
||||
field.shouldResignFirstResponder.onNext(Void())
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
return toolBar
|
||||
}
|
||||
|
||||
private func shouldGoForwardAction(from index: Int) {
|
||||
if let nextActive = cellFields.nextActive(from: index) {
|
||||
nextActive.shouldBecomeFirstResponder.onNext(Void())
|
||||
} else {
|
||||
didDone.onNext(Void())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension Array where Element == CellFieldJumpingProtocol {
|
||||
|
||||
var firstActive: CellFieldJumpingProtocol? {
|
||||
return first { $0.isActive }
|
||||
}
|
||||
|
||||
var lastActive: CellFieldJumpingProtocol? {
|
||||
return reversed().first { $0.isActive }
|
||||
}
|
||||
|
||||
func nextActive(from index: Int) -> CellFieldJumpingProtocol? {
|
||||
return enumerated().first { $0 > index && $1.isActive }?.element
|
||||
}
|
||||
|
||||
func previousActive(from index: Int) -> CellFieldJumpingProtocol? {
|
||||
let reversedIndex = count - index - 1
|
||||
return reversed().enumerated().first { $0 > reversedIndex && $1.isActive }?.element
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// Copyright (c) 2018 Touch Instinct
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the Software), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
/// Enum that describes current state of online validation.
|
||||
///
|
||||
/// - initial: Nothing did happen.
|
||||
/// - processing: Processing validation.
|
||||
/// - valid: Got a valid result.
|
||||
/// - invalid: Got an invalid result.
|
||||
public enum OnlineValidationState {
|
||||
|
||||
case initial
|
||||
case processing
|
||||
case valid
|
||||
case invalid(error: Error?)
|
||||
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
import UIKit
|
||||
import RxCocoa
|
||||
import RxSwift
|
||||
|
||||
class CellTextField: UITextField {
|
||||
|
||||
private var disposeBag = DisposeBag()
|
||||
|
||||
var viewModel: CellTextFieldViewModel? {
|
||||
didSet {
|
||||
configure()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Init
|
||||
|
||||
private func configure() {
|
||||
disposeBag = DisposeBag()
|
||||
|
||||
guard let viewModel = viewModel else {
|
||||
return
|
||||
}
|
||||
|
||||
inputAccessoryView = viewModel.toolBar
|
||||
returnKeyType = viewModel.returnButtonType
|
||||
|
||||
text = viewModel.textValue
|
||||
placeholder = viewModel.placeholder
|
||||
viewModel.textFieldSettingsBlock?(self)
|
||||
|
||||
viewModel.bind(for: self, to: disposeBag)
|
||||
|
||||
rx.text.asDriver()
|
||||
.drive(onNext: {
|
||||
viewModel.setTextValue($0)
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
|
||||
rx.controlEvent(.editingDidEndOnExit)
|
||||
.subscribe(onNext: { [viewModel] in
|
||||
viewModel.shouldGoForward.onNext(Void())
|
||||
})
|
||||
.disposed(by: disposeBag)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
import UIKit
|
||||
import RxSwift
|
||||
|
||||
class CellTextFieldViewModel: CellFieldJumpingProtocol {
|
||||
|
||||
private let text: Variable<String?>
|
||||
|
||||
let placeholder: String
|
||||
|
||||
let textFieldSettingsBlock: ItemSettingsBlock<UITextField>?
|
||||
|
||||
// MARK: - CellFieldJumpingProtocol
|
||||
|
||||
var toolBar: UIToolbar?
|
||||
|
||||
let shouldGoForward = PublishSubject<Void>()
|
||||
|
||||
let shouldBecomeFirstResponder = PublishSubject<Void>()
|
||||
let shouldResignFirstResponder = PublishSubject<Void>()
|
||||
|
||||
var returnButtonType: UIReturnKeyType = .default
|
||||
|
||||
var isActive: Bool = true
|
||||
|
||||
init(initialText: String = "", placeholder: String = "", textFieldSettingsBlock: ItemSettingsBlock<UITextField>? = nil) {
|
||||
text = Variable(initialText)
|
||||
self.placeholder = placeholder
|
||||
self.textFieldSettingsBlock = textFieldSettingsBlock
|
||||
}
|
||||
|
||||
// MARK: - Internal
|
||||
|
||||
var textValue: String? {
|
||||
return text.value
|
||||
}
|
||||
|
||||
func setTextValue(_ value: String?) {
|
||||
text.value = value
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
import UIKit
|
||||
import RxSwift
|
||||
import RxCocoa
|
||||
import LeadKit
|
||||
|
||||
class CellTextFieldToolBar: UIToolbar, CellFieldsToolBarProtocol {
|
||||
|
||||
private let buttonSpace: CGFloat = 20
|
||||
|
||||
// MARK: - CellFieldsToolBarProtocol
|
||||
|
||||
var needArrows: Bool = true
|
||||
|
||||
var canGoForward: Bool = false {
|
||||
didSet {
|
||||
forwardButton.isEnabled = canGoForward
|
||||
}
|
||||
}
|
||||
var canGoBackward: Bool = false {
|
||||
didSet {
|
||||
backButton.isEnabled = canGoBackward
|
||||
}
|
||||
}
|
||||
|
||||
var shouldGoForward = PublishSubject<Void>()
|
||||
var shouldGoBackward = PublishSubject<Void>()
|
||||
var shouldEndEditing = PublishSubject<Void>()
|
||||
|
||||
// MARK: - UIBarButtonItems
|
||||
|
||||
var backButtonImage: UIImage? {
|
||||
didSet {
|
||||
backButton.image = backButtonImage
|
||||
}
|
||||
}
|
||||
var forwardButtonImage: UIImage? {
|
||||
didSet {
|
||||
backButton.image = backButtonImage
|
||||
}
|
||||
}
|
||||
|
||||
private(set) lazy var backButton: UIBarButtonItem = {
|
||||
let backButton = UIBarButtonItem(image: self.backButtonImage,
|
||||
style: .plain,
|
||||
target: self,
|
||||
action: #selector(backAction))
|
||||
return backButton
|
||||
}()
|
||||
|
||||
private(set) lazy var forwardButton: UIBarButtonItem = {
|
||||
let forwardButton = UIBarButtonItem(image: self.forwardButtonImage,
|
||||
style: .plain,
|
||||
target: self,
|
||||
action: #selector(forwardAction))
|
||||
return forwardButton
|
||||
}()
|
||||
|
||||
private(set) lazy var closeButton: UIBarButtonItem = {
|
||||
let doneButton = UIBarButtonItem(barButtonSystemItem: .done,
|
||||
target: self,
|
||||
action: #selector(doneAction))
|
||||
return doneButton
|
||||
}()
|
||||
|
||||
// MARK: - Initialization
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
initialization()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
initialization()
|
||||
}
|
||||
|
||||
private func initialization() {
|
||||
barStyle = .default
|
||||
isTranslucent = true
|
||||
tintColor = UIColor(hex6: 0x0A84DF)
|
||||
sizeToFit()
|
||||
|
||||
let leftSpacer = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
|
||||
let firstButtonsSpacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
|
||||
firstButtonsSpacer.width = buttonSpace
|
||||
let secondButtonsSpacer = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
|
||||
secondButtonsSpacer.width = buttonSpace
|
||||
|
||||
setItems([leftSpacer, backButton, firstButtonsSpacer, forwardButton, secondButtonsSpacer, closeButton], animated: true)
|
||||
items?.forEach { $0.tintColor = tintColor }
|
||||
}
|
||||
|
||||
// MARK: - Actions
|
||||
|
||||
@objc private func backAction() {
|
||||
shouldGoBackward.onNext(Void())
|
||||
}
|
||||
|
||||
@objc private func forwardAction() {
|
||||
shouldGoForward.onNext(Void())
|
||||
}
|
||||
|
||||
@objc private func doneAction() {
|
||||
shouldEndEditing.onNext(Void())
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue