Commit 87e234ab authored by “Icebear”'s avatar “Icebear”

登录页UI、协调器模式、中间件模式配置、URL配置

parent 483d2fd8
......@@ -8,29 +8,55 @@
/* Begin PBXBuildFile section */
1669D09F86E4ECF0C01BD71C /* Pods_NetrainFrame.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFAD26382CE323D58F08BF66 /* Pods_NetrainFrame.framework */; };
331B5525251AEF7300FFFC5C /* MainCoordinator.m in Sources */ = {isa = PBXBuildFile; fileRef = 331B5524251AEF7300FFFC5C /* MainCoordinator.m */; };
335609B7251B23E500628080 /* Target_LoginCoordinator.m in Sources */ = {isa = PBXBuildFile; fileRef = 335609B6251B23E500628080 /* Target_LoginCoordinator.m */; };
335609EA251B4D9900628080 /* CTMediator+MainCoordinatorActions.m in Sources */ = {isa = PBXBuildFile; fileRef = 335609E9251B4D9900628080 /* CTMediator+MainCoordinatorActions.m */; };
33560A01251B5AAF00628080 /* NRPasswordLoginRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33560A00251B5AAF00628080 /* NRPasswordLoginRequest.m */; };
33560A05251B5C3500628080 /* NRBaseRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33560A04251B5C3500628080 /* NRBaseRequest.m */; };
335F6A5E25184A5D0083A571 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 335F6A5D25184A5D0083A571 /* AppDelegate.m */; };
335F6A6725184A5D0083A571 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 335F6A6525184A5D0083A571 /* Main.storyboard */; };
335F6A6925184A5E0083A571 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 335F6A6825184A5E0083A571 /* Assets.xcassets */; };
335F6A6C25184A5E0083A571 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 335F6A6A25184A5E0083A571 /* LaunchScreen.storyboard */; };
335F6A6F25184A5E0083A571 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 335F6A6E25184A5E0083A571 /* main.m */; };
335F6AC8251895660083A571 /* Placeholder3 in Resources */ = {isa = PBXBuildFile; fileRef = 335F6ABD251895660083A571 /* Placeholder3 */; };
335F6ACA251895660083A571 /* Placeholder5 in Resources */ = {isa = PBXBuildFile; fileRef = 335F6AC1251895660083A571 /* Placeholder5 */; };
335F6ACB251895660083A571 /* Placeholder6 in Resources */ = {isa = PBXBuildFile; fileRef = 335F6AC3251895660083A571 /* Placeholder6 */; };
335F6ACC251895660083A571 /* Placeholder7 in Resources */ = {isa = PBXBuildFile; fileRef = 335F6AC5251895660083A571 /* Placeholder7 */; };
335F6AD125189B130083A571 /* AppDelegate+AppService.m in Sources */ = {isa = PBXBuildFile; fileRef = 335F6AD025189B130083A571 /* AppDelegate+AppService.m */; };
335F6B1D2518ADA10083A571 /* Placeholder11 in Resources */ = {isa = PBXBuildFile; fileRef = 335F6B142518ADA10083A571 /* Placeholder11 */; };
335F6B1E2518ADA10083A571 /* Placeholder12 in Resources */ = {isa = PBXBuildFile; fileRef = 335F6B162518ADA10083A571 /* Placeholder12 */; };
335F6B1F2518ADA10083A571 /* Placeholder13 in Resources */ = {isa = PBXBuildFile; fileRef = 335F6B182518ADA10083A571 /* Placeholder13 */; };
335F6B202518ADA10083A571 /* Placeholder10 in Resources */ = {isa = PBXBuildFile; fileRef = 335F6B1A2518ADA10083A571 /* Placeholder10 */; };
335F6B212518ADA10083A571 /* Placeholder9 in Resources */ = {isa = PBXBuildFile; fileRef = 335F6B1C2518ADA10083A571 /* Placeholder9 */; };
335F6B272518ADD30083A571 /* BaseRequestAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = 335F6B262518ADD30083A571 /* BaseRequestAPI.m */; };
33A1D2802519D8D100824CB8 /* NRLoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 33A1D27F2519D8D100824CB8 /* NRLoginViewController.m */; };
33A1D2832519D8EB00824CB8 /* NRLogin.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 33A1D2822519D8EB00824CB8 /* NRLogin.storyboard */; };
33A1D28A2519E50C00824CB8 /* QMUIConfigurationTemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = 33A1D2892519E50C00824CB8 /* QMUIConfigurationTemplate.m */; };
33A1D28F2519E8AD00824CB8 /* NRRegisterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 33A1D28E2519E8AD00824CB8 /* NRRegisterViewController.m */; };
33A1D2942519EB5100824CB8 /* NRCommonViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 33A1D2932519EB5100824CB8 /* NRCommonViewController.m */; };
33E97960251B5D8100437015 /* NRVerifyCodeRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E9795F251B5D8100437015 /* NRVerifyCodeRequest.m */; };
33E97964251B5D9500437015 /* NRRegisterRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E97963251B5D9400437015 /* NRRegisterRequest.m */; };
33E97968251B5E8B00437015 /* NRServerTimeRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E97967251B5E8B00437015 /* NRServerTimeRequest.m */; };
33E9796C251B5FA500437015 /* NRLoginKeyRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E9796B251B5FA500437015 /* NRLoginKeyRequest.m */; };
33E97970251B601700437015 /* NRLoginLogic.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E9796F251B601700437015 /* NRLoginLogic.m */; };
33E97975251B618700437015 /* NRVerifyCodeLoginRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E97974251B618700437015 /* NRVerifyCodeLoginRequest.m */; };
33E97993251C476300437015 /* NRBaseModelAgent.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E97992251C476300437015 /* NRBaseModelAgent.m */; };
33E9799E251C498700437015 /* NRGlobalUrlModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E9799D251C498700437015 /* NRGlobalUrlModel.m */; };
33E979A1251C4B7900437015 /* BaseUrlConfig.json in Resources */ = {isa = PBXBuildFile; fileRef = 33E979A0251C4B7900437015 /* BaseUrlConfig.json */; };
33E979A6251C659800437015 /* NSMutableArray+Safe.m in Sources */ = {isa = PBXBuildFile; fileRef = 33E979A5251C659800437015 /* NSMutableArray+Safe.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
331B5523251AEF7300FFFC5C /* MainCoordinator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MainCoordinator.h; sourceTree = "<group>"; };
331B5524251AEF7300FFFC5C /* MainCoordinator.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MainCoordinator.m; sourceTree = "<group>"; };
335609B5251B23E500628080 /* Target_LoginCoordinator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Target_LoginCoordinator.h; sourceTree = "<group>"; };
335609B6251B23E500628080 /* Target_LoginCoordinator.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Target_LoginCoordinator.m; sourceTree = "<group>"; };
335609E8251B4D9900628080 /* CTMediator+MainCoordinatorActions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CTMediator+MainCoordinatorActions.h"; sourceTree = "<group>"; };
335609E9251B4D9900628080 /* CTMediator+MainCoordinatorActions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CTMediator+MainCoordinatorActions.m"; sourceTree = "<group>"; };
335609FF251B5AAF00628080 /* NRPasswordLoginRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRPasswordLoginRequest.h; sourceTree = "<group>"; };
33560A00251B5AAF00628080 /* NRPasswordLoginRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRPasswordLoginRequest.m; sourceTree = "<group>"; };
33560A03251B5C3500628080 /* NRBaseRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRBaseRequest.h; sourceTree = "<group>"; };
33560A04251B5C3500628080 /* NRBaseRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRBaseRequest.m; sourceTree = "<group>"; };
335F6A5925184A5D0083A571 /* NetrainFrame.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetrainFrame.app; sourceTree = BUILT_PRODUCTS_DIR; };
335F6A5C25184A5D0083A571 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
335F6A5D25184A5D0083A571 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
335F6A6625184A5D0083A571 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
335F6A6825184A5E0083A571 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
335F6A6B25184A5E0083A571 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
335F6A6D25184A5E0083A571 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
......@@ -38,7 +64,6 @@
335F6ABD251895660083A571 /* Placeholder3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Placeholder3; sourceTree = "<group>"; };
335F6AC1251895660083A571 /* Placeholder5 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Placeholder5; sourceTree = "<group>"; };
335F6AC3251895660083A571 /* Placeholder6 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Placeholder6; sourceTree = "<group>"; };
335F6AC5251895660083A571 /* Placeholder7 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Placeholder7; sourceTree = "<group>"; };
335F6ACF25189B130083A571 /* AppDelegate+AppService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AppDelegate+AppService.h"; sourceTree = "<group>"; };
335F6AD025189B130083A571 /* AppDelegate+AppService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "AppDelegate+AppService.m"; sourceTree = "<group>"; };
335F6ADA25189D100083A571 /* PrefixHeader.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = "<group>"; };
......@@ -47,13 +72,38 @@
335F6B182518ADA10083A571 /* Placeholder13 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Placeholder13; sourceTree = "<group>"; };
335F6B1A2518ADA10083A571 /* Placeholder10 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Placeholder10; sourceTree = "<group>"; };
335F6B1C2518ADA10083A571 /* Placeholder9 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Placeholder9; sourceTree = "<group>"; };
335F6B252518ADD30083A571 /* BaseRequestAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BaseRequestAPI.h; sourceTree = "<group>"; };
335F6B262518ADD30083A571 /* BaseRequestAPI.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BaseRequestAPI.m; sourceTree = "<group>"; };
335F6B2A2518AF170083A571 /* ThirdMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThirdMacros.h; sourceTree = "<group>"; };
335F6B2B2518AF170083A571 /* FontAndColorMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontAndColorMacros.h; sourceTree = "<group>"; };
335F6B2C2518AF170083A571 /* URLMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = URLMacros.h; sourceTree = "<group>"; };
335F6B2D2518AF170083A571 /* NotificationMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NotificationMacros.h; sourceTree = "<group>"; };
335F6B2E2518AF170083A571 /* UtilsMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UtilsMacros.h; sourceTree = "<group>"; };
33A1D27E2519D8D100824CB8 /* NRLoginViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRLoginViewController.h; sourceTree = "<group>"; };
33A1D27F2519D8D100824CB8 /* NRLoginViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRLoginViewController.m; sourceTree = "<group>"; };
33A1D2822519D8EB00824CB8 /* NRLogin.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = NRLogin.storyboard; sourceTree = "<group>"; };
33A1D2882519E50C00824CB8 /* QMUIConfigurationTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QMUIConfigurationTemplate.h; sourceTree = "<group>"; };
33A1D2892519E50C00824CB8 /* QMUIConfigurationTemplate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QMUIConfigurationTemplate.m; sourceTree = "<group>"; };
33A1D28D2519E8AD00824CB8 /* NRRegisterViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRRegisterViewController.h; sourceTree = "<group>"; };
33A1D28E2519E8AD00824CB8 /* NRRegisterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRRegisterViewController.m; sourceTree = "<group>"; };
33A1D2922519EB5100824CB8 /* NRCommonViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRCommonViewController.h; sourceTree = "<group>"; };
33A1D2932519EB5100824CB8 /* NRCommonViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRCommonViewController.m; sourceTree = "<group>"; };
33E9795E251B5D8100437015 /* NRVerifyCodeRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRVerifyCodeRequest.h; sourceTree = "<group>"; };
33E9795F251B5D8100437015 /* NRVerifyCodeRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRVerifyCodeRequest.m; sourceTree = "<group>"; };
33E97962251B5D9400437015 /* NRRegisterRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRRegisterRequest.h; sourceTree = "<group>"; };
33E97963251B5D9400437015 /* NRRegisterRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRRegisterRequest.m; sourceTree = "<group>"; };
33E97966251B5E8B00437015 /* NRServerTimeRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRServerTimeRequest.h; sourceTree = "<group>"; };
33E97967251B5E8B00437015 /* NRServerTimeRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRServerTimeRequest.m; sourceTree = "<group>"; };
33E9796A251B5FA500437015 /* NRLoginKeyRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRLoginKeyRequest.h; sourceTree = "<group>"; };
33E9796B251B5FA500437015 /* NRLoginKeyRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRLoginKeyRequest.m; sourceTree = "<group>"; };
33E9796E251B601700437015 /* NRLoginLogic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRLoginLogic.h; sourceTree = "<group>"; };
33E9796F251B601700437015 /* NRLoginLogic.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRLoginLogic.m; sourceTree = "<group>"; };
33E97973251B618700437015 /* NRVerifyCodeLoginRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRVerifyCodeLoginRequest.h; sourceTree = "<group>"; };
33E97974251B618700437015 /* NRVerifyCodeLoginRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRVerifyCodeLoginRequest.m; sourceTree = "<group>"; };
33E97991251C476300437015 /* NRBaseModelAgent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRBaseModelAgent.h; sourceTree = "<group>"; };
33E97992251C476300437015 /* NRBaseModelAgent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRBaseModelAgent.m; sourceTree = "<group>"; };
33E9799C251C498700437015 /* NRGlobalUrlModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NRGlobalUrlModel.h; sourceTree = "<group>"; };
33E9799D251C498700437015 /* NRGlobalUrlModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NRGlobalUrlModel.m; sourceTree = "<group>"; };
33E979A0251C4B7900437015 /* BaseUrlConfig.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = BaseUrlConfig.json; sourceTree = "<group>"; };
33E979A5251C659800437015 /* NSMutableArray+Safe.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableArray+Safe.m"; sourceTree = "<group>"; };
49664D4BB9E25240F6B2F0A9 /* Pods-NetrainFrame.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NetrainFrame.release.xcconfig"; path = "Target Support Files/Pods-NetrainFrame/Pods-NetrainFrame.release.xcconfig"; sourceTree = "<group>"; };
AFAD26382CE323D58F08BF66 /* Pods_NetrainFrame.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NetrainFrame.framework; sourceTree = BUILT_PRODUCTS_DIR; };
DCF21838657E8CF2B8988B38 /* Pods-NetrainFrame.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NetrainFrame.debug.xcconfig"; path = "Target Support Files/Pods-NetrainFrame/Pods-NetrainFrame.debug.xcconfig"; sourceTree = "<group>"; };
......@@ -71,6 +121,66 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
331B5522251AEF5700FFFC5C /* Coordinator */ = {
isa = PBXGroup;
children = (
331B5523251AEF7300FFFC5C /* MainCoordinator.h */,
331B5524251AEF7300FFFC5C /* MainCoordinator.m */,
335609E8251B4D9900628080 /* CTMediator+MainCoordinatorActions.h */,
335609E9251B4D9900628080 /* CTMediator+MainCoordinatorActions.m */,
);
path = Coordinator;
sourceTree = "<group>";
};
335609B4251B23D100628080 /* Coordinator */ = {
isa = PBXGroup;
children = (
335609B5251B23E500628080 /* Target_LoginCoordinator.h */,
335609B6251B23E500628080 /* Target_LoginCoordinator.m */,
);
path = Coordinator;
sourceTree = "<group>";
};
335609F8251B54FF00628080 /* Controllers */ = {
isa = PBXGroup;
children = (
33A1D27E2519D8D100824CB8 /* NRLoginViewController.h */,
33A1D27F2519D8D100824CB8 /* NRLoginViewController.m */,
33A1D28D2519E8AD00824CB8 /* NRRegisterViewController.h */,
33A1D28E2519E8AD00824CB8 /* NRRegisterViewController.m */,
33A1D2822519D8EB00824CB8 /* NRLogin.storyboard */,
);
path = Controllers;
sourceTree = "<group>";
};
335609FB251B554200628080 /* Logic */ = {
isa = PBXGroup;
children = (
33E9796E251B601700437015 /* NRLoginLogic.h */,
33E9796F251B601700437015 /* NRLoginLogic.m */,
);
path = Logic;
sourceTree = "<group>";
};
335609FC251B59D400628080 /* Service */ = {
isa = PBXGroup;
children = (
335609FF251B5AAF00628080 /* NRPasswordLoginRequest.h */,
33560A00251B5AAF00628080 /* NRPasswordLoginRequest.m */,
33E97973251B618700437015 /* NRVerifyCodeLoginRequest.h */,
33E97974251B618700437015 /* NRVerifyCodeLoginRequest.m */,
33E9796A251B5FA500437015 /* NRLoginKeyRequest.h */,
33E9796B251B5FA500437015 /* NRLoginKeyRequest.m */,
33E97966251B5E8B00437015 /* NRServerTimeRequest.h */,
33E97967251B5E8B00437015 /* NRServerTimeRequest.m */,
33E9795E251B5D8100437015 /* NRVerifyCodeRequest.h */,
33E9795F251B5D8100437015 /* NRVerifyCodeRequest.m */,
33E97962251B5D9400437015 /* NRRegisterRequest.h */,
33E97963251B5D9400437015 /* NRRegisterRequest.m */,
);
path = Service;
sourceTree = "<group>";
};
335F6A5025184A5D0083A571 = {
isa = PBXGroup;
children = (
......@@ -119,7 +229,6 @@
335F6AAF251893AD0083A571 /* Supporting Files */ = {
isa = PBXGroup;
children = (
335F6A6525184A5D0083A571 /* Main.storyboard */,
335F6A6825184A5E0083A571 /* Assets.xcassets */,
335F6A6A25184A5E0083A571 /* LaunchScreen.storyboard */,
335F6A6D25184A5E0083A571 /* Info.plist */,
......@@ -132,7 +241,10 @@
335F6AB8251895660083A571 /* Base */ = {
isa = PBXGroup;
children = (
335F6B242518ADD30083A571 /* BaseRequestApi */,
33E97990251C45AD00437015 /* BaseModelAgent */,
331B5522251AEF5700FFFC5C /* Coordinator */,
33A1D2912519EB2400824CB8 /* Controllers */,
335F6B242518ADD30083A571 /* BaseRequest */,
);
path = Base;
sourceTree = "<group>";
......@@ -185,7 +297,8 @@
335F6AC4251895660083A571 /* Utils */ = {
isa = PBXGroup;
children = (
335F6AC5251895660083A571 /* Placeholder7 */,
33E979A4251C658900437015 /* SafeArray */,
33A1D2872519E50C00824CB8 /* QMUIConfigurationTemplate */,
);
path = Utils;
sourceTree = "<group>";
......@@ -242,22 +355,64 @@
path = Controller;
sourceTree = "<group>";
};
335F6B242518ADD30083A571 /* BaseRequestApi */ = {
335F6B242518ADD30083A571 /* BaseRequest */ = {
isa = PBXGroup;
children = (
335F6B252518ADD30083A571 /* BaseRequestAPI.h */,
335F6B262518ADD30083A571 /* BaseRequestAPI.m */,
33560A03251B5C3500628080 /* NRBaseRequest.h */,
33560A04251B5C3500628080 /* NRBaseRequest.m */,
);
path = BaseRequestApi;
path = BaseRequest;
sourceTree = "<group>";
};
33A1D27C2519C11E00824CB8 /* Login */ = {
isa = PBXGroup;
children = (
335609FC251B59D400628080 /* Service */,
335609FB251B554200628080 /* Logic */,
335609B4251B23D100628080 /* Coordinator */,
335609F8251B54FF00628080 /* Controllers */,
);
path = Login;
sourceTree = "<group>";
};
33A1D2872519E50C00824CB8 /* QMUIConfigurationTemplate */ = {
isa = PBXGroup;
children = (
33A1D2882519E50C00824CB8 /* QMUIConfigurationTemplate.h */,
33A1D2892519E50C00824CB8 /* QMUIConfigurationTemplate.m */,
);
path = QMUIConfigurationTemplate;
sourceTree = "<group>";
};
33A1D2912519EB2400824CB8 /* Controllers */ = {
isa = PBXGroup;
children = (
33A1D2922519EB5100824CB8 /* NRCommonViewController.h */,
33A1D2932519EB5100824CB8 /* NRCommonViewController.m */,
);
path = Controllers;
sourceTree = "<group>";
};
33E97990251C45AD00437015 /* BaseModelAgent */ = {
isa = PBXGroup;
children = (
33E97991251C476300437015 /* NRBaseModelAgent.h */,
33E97992251C476300437015 /* NRBaseModelAgent.m */,
33E9799C251C498700437015 /* NRGlobalUrlModel.h */,
33E9799D251C498700437015 /* NRGlobalUrlModel.m */,
33E979A0251C4B7900437015 /* BaseUrlConfig.json */,
);
path = BaseModelAgent;
sourceTree = "<group>";
};
33E979A4251C658900437015 /* SafeArray */ = {
isa = PBXGroup;
children = (
33E979A5251C659800437015 /* NSMutableArray+Safe.m */,
);
path = SafeArray;
sourceTree = "<group>";
};
AF101A8647B6D432ED4BF085 /* Pods */ = {
isa = PBXGroup;
children = (
......@@ -303,6 +458,7 @@
335F6A5125184A5D0083A571 /* Project object */ = {
isa = PBXProject;
attributes = {
CLASSPREFIX = NR;
LastUpgradeCheck = 1200;
TargetAttributes = {
335F6A5825184A5D0083A571 = {
......@@ -338,9 +494,9 @@
335F6A6925184A5E0083A571 /* Assets.xcassets in Resources */,
335F6B202518ADA10083A571 /* Placeholder10 in Resources */,
335F6B212518ADA10083A571 /* Placeholder9 in Resources */,
33E979A1251C4B7900437015 /* BaseUrlConfig.json in Resources */,
33A1D2832519D8EB00824CB8 /* NRLogin.storyboard in Resources */,
335F6B1D2518ADA10083A571 /* Placeholder11 in Resources */,
335F6ACC251895660083A571 /* Placeholder7 in Resources */,
335F6A6725184A5D0083A571 /* Main.storyboard in Resources */,
335F6ACB251895660083A571 /* Placeholder6 in Resources */,
335F6ACA251895660083A571 /* Placeholder5 in Resources */,
335F6B1F2518ADA10083A571 /* Placeholder13 in Resources */,
......@@ -397,24 +553,33 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
33E97964251B5D9500437015 /* NRRegisterRequest.m in Sources */,
335609B7251B23E500628080 /* Target_LoginCoordinator.m in Sources */,
335F6AD125189B130083A571 /* AppDelegate+AppService.m in Sources */,
335F6B272518ADD30083A571 /* BaseRequestAPI.m in Sources */,
33E97993251C476300437015 /* NRBaseModelAgent.m in Sources */,
335609EA251B4D9900628080 /* CTMediator+MainCoordinatorActions.m in Sources */,
33A1D28A2519E50C00824CB8 /* QMUIConfigurationTemplate.m in Sources */,
33E97968251B5E8B00437015 /* NRServerTimeRequest.m in Sources */,
33560A01251B5AAF00628080 /* NRPasswordLoginRequest.m in Sources */,
33A1D2942519EB5100824CB8 /* NRCommonViewController.m in Sources */,
33E97960251B5D8100437015 /* NRVerifyCodeRequest.m in Sources */,
33E9799E251C498700437015 /* NRGlobalUrlModel.m in Sources */,
33E9796C251B5FA500437015 /* NRLoginKeyRequest.m in Sources */,
335F6A5E25184A5D0083A571 /* AppDelegate.m in Sources */,
33E97975251B618700437015 /* NRVerifyCodeLoginRequest.m in Sources */,
33E979A6251C659800437015 /* NSMutableArray+Safe.m in Sources */,
33A1D2802519D8D100824CB8 /* NRLoginViewController.m in Sources */,
33A1D28F2519E8AD00824CB8 /* NRRegisterViewController.m in Sources */,
33E97970251B601700437015 /* NRLoginLogic.m in Sources */,
335F6A6F25184A5E0083A571 /* main.m in Sources */,
33560A05251B5C3500628080 /* NRBaseRequest.m in Sources */,
331B5525251AEF7300FFFC5C /* MainCoordinator.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
335F6A6525184A5D0083A571 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
335F6A6625184A5D0083A571 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
335F6A6A25184A5E0083A571 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
......
......@@ -6,7 +6,6 @@
//
#import "AppDelegate.h"
@interface AppDelegate (AppService)
//初始化 window
......
......@@ -6,19 +6,17 @@
//
#import "AppDelegate+AppService.h"
#import "NRLoginViewController.h"
#import "MainCoordinator.h"
@implementation AppDelegate (AppService)
#pragma mark ————— 初始化window —————
-(void)initWindow{
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.backgroundColor = UIColor.whiteColor;
self.window.rootViewController = UIViewController.new;
[self.window makeKeyAndVisible];
[[UIButton appearance] setExclusiveTouch:YES];
if (@available(iOS 11.0, *)){
[[UIScrollView appearance] setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
}
self.coordinator = [[MainCoordinator alloc] initWithWindow:self.window];
[self.coordinator start];
}
......
......@@ -6,10 +6,13 @@
//
#import <UIKit/UIKit.h>
@class MainCoordinator;
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property(strong, nonatomic) UIWindow *window;
@property(strong, nonatomic) MainCoordinator *coordinator;
@end
{
"product": {
"kDomain" : "api.docker.naiterui.com/",
"kHost" : "ad",
"kSwagger" : "emr",
"kMHost" : "recommend",
"kH5Path" : "",
"kChat" : "yun",
"kHHost" : "im",
"kTHost" : "push",
"kH5Zip" : "",
"kH5_envir" : "1",
"useSSL" : 1,
},
"developer": {
}
}
//
// NRBaseModelAgent.h
// NetrainFrame
//
// Created by Gin on 2020/9/24.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NRBaseModelAgent : NSObject
/**
* Quick way to create Agent
*
* @return instance of JHModelAgent
*/
+ (instancetype)agent;
/**
* Create Model instance from Json Data
*
* @param modelClass maybe any class.
* @param json Json data. Should be a NSArray or a NSDictionary.
*
* @return A NSArray contains the Model instances.
*/
- (NSArray *)createModel:(Class)modelClass fromJson:(id)json;
/**
* Create Json data from a JHModel.
*
* @param model Should be derived from JHModel.
*
* @return Json data.(NSDictionary)
*/
- (NSDictionary *)createJsonFromModel:(NSObject *)model;
/**
* Create Json data from a JHModel.
*
* @param modelArray A NSArray contains models. Models Should be derived from JHModel.
*
* @return Json data.(NSArray)
*/
- (NSArray *)createJsonArrayFromModel:(NSArray *)modelArray;
@end
NS_ASSUME_NONNULL_END
//
// NRBaseModelAgent.m
// NetrainFrame
//
// Created by Gin on 2020/9/24.
//
#import "NRBaseModelAgent.h"
@implementation NRBaseModelAgent
+ (instancetype)agent {
return [[NRBaseModelAgent alloc] init];
}
#pragma mark - json to model
- (NSArray *)createModel:(Class)modelClass fromJson:(id)json {
NSArray *result = nil;
if ([json isKindOfClass:[NSString class]]) {
result = [NSArray yy_modelArrayWithClass:modelClass json:json];
} else if ([json isKindOfClass:[NSDictionary class]]) {
id model = [modelClass yy_modelWithDictionary:json];
if (model) {
result = @[model];
} else {
NSLog(@"Fail to create model");
}
} else {
NSLog(@"Not json data.");
}
return result;
}
- (NSDictionary *)createJsonFromModel:(NSObject *)model {
NSDictionary *result = [model yy_modelToJSONObject];
if (![result isKindOfClass:[NSDictionary class]]) {
NSLog(@"Fail to get Json data.");
}
return result;
}
- (NSArray *)createJsonArrayFromModel:(NSArray *)modelArray {
NSArray *result = [modelArray yy_modelToJSONObject];
if (![result isKindOfClass:[NSArray class]]) {
NSLog(@"Fail to get Json data.");
}
return result;
}
@end
//
// NRGlobalUrlModel.h
// NetrainFrame
//
// Created by Gin on 2020/9/24.
//
#import <Foundation/Foundation.h>
typedef enum : NSUInteger {
AppServer_Developer,
AppServer_Product,
} AppServer;
NS_ASSUME_NONNULL_BEGIN
@interface NRGlobalUrlModel : NSObject
+(NRGlobalUrlModel *)sharedInstance;
@property(nonatomic, assign) AppServer appServer;
@property(nonatomic, strong) NSString *kHost;
@property(nonatomic, strong) NSString *kSwagger;
@property(nonatomic, strong) NSString *kMHost;
@property(nonatomic, strong) NSString *kH5Path;
@property(nonatomic, strong) NSString *kChat;
@property(nonatomic, strong) NSString *kHHost;
@property(nonatomic, strong) NSString *kTHost;
@property(nonatomic, strong) NSString *kH5Version;
@property(nonatomic, strong) NSString *kH5Zip;
@property(nonatomic, strong) NSString *kH5Environmental;
@end
NS_ASSUME_NONNULL_END
//
// NRGlobalUrlModel.m
// NetrainFrame
//
// Created by Gin on 2020/9/24.
//
#import "NRGlobalUrlModel.h"
@interface URLModel : NSObject
@property(nonatomic, copy) NSString *kDomain;
@property(nonatomic, copy) NSString *kHost;
@property(nonatomic, copy) NSString *kSwagger;
@property(nonatomic, copy) NSString *kMHost;
@property(nonatomic, copy) NSString *kH5Path;
@property(nonatomic, copy) NSString *kChat;
@property(nonatomic, copy) NSString *kHHost;
@property(nonatomic, copy) NSString *kTHost;
@property(nonatomic, copy) NSString *kH5Zip;
@property(nonatomic, copy) NSString *kH5_envir;
@property(nonatomic, assign) BOOL useSSL;
@end
@implementation URLModel
@end
@implementation NRGlobalUrlModel
+ (NRGlobalUrlModel *)sharedInstance {
static NRGlobalUrlModel *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (!sharedInstance) {
sharedInstance = [[self alloc] init];
[sharedInstance cofigureAppServer];
}
});
return sharedInstance;
}
- (void)cofigureAppServer{
NSString *path = [[NSBundle mainBundle] pathForResource:@"BaseUrlConfig" ofType:@"json"];
if (path == nil) {
NSAssert(NO, @"出错了!");
}
NSString *str = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
NSDictionary *urlDict = [str yy_modelToJSONObject];
URLModel *urlModel = [[URLModel alloc] init];
if(self.appServer == ProductSever){
urlModel = [[[NRBaseModelAgent agent] createModel:[URLModel class] fromJson:urlDict[@"product"]] objectAtIndex:0];
}else{
urlModel = [[[NRBaseModelAgent agent] createModel:[URLModel class] fromJson:urlDict[@"developer"]] objectAtIndex:0];
}
if(urlModel){
self.kHost = [NSString stringWithFormat:@"%@%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain,urlModel.kHost];
self.kSwagger = [NSString stringWithFormat:@"%@%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain,urlModel.kSwagger];
self.kMHost = [NSString stringWithFormat:@"%@%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain,urlModel.kMHost];
self.kH5Path = [NSString stringWithFormat:@"%@%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain,urlModel.kH5Path];
self.kChat = [NSString stringWithFormat:@"%@%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain,urlModel.kChat];
self.kHHost = [NSString stringWithFormat:@"%@%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain,urlModel.kHHost];
self.kTHost = [NSString stringWithFormat:@"%@%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain,urlModel.kTHost];
self.kH5Version = @"1.0";
self.kH5Zip = [NSString stringWithFormat:@"%@%@",urlModel.useSSL?@"https://":@"http://",urlModel.kDomain];
self.kH5Environmental = urlModel.kH5_envir;
}
}
@end
//
// BaseRequestAPI.h
// NRBaseRequest.h
// NetrainFrame
//
// Created by Gin on 2020/9/21.
// Created by Gin on 2020/9/23.
//
#import <YTKNetwork/YTKNetwork.h>
/**
///环境Url
#import "NRGlobalUrlModel.h"
/*
接口请求基类,所有请求必须继承此类
这里采用的是YTKNetwork网络库,中大型APP专用,可满足所有网络需求
学习地址:https://github.com/yuantiku/YTKNetwork
*/
@interface BaseRequestAPI : YTKBaseRequest
NS_ASSUME_NONNULL_BEGIN
@interface NRBaseRequest : YTKBaseRequest
//自定义属性值
@property(nonatomic,assign)BOOL isSuccess;//是否成功
@property (nonatomic,copy) NSString * message;//服务器返回的信息
@property (nonatomic,copy) NSDictionary * result;//服务器返回的数据 已解密
- (void)startWithCompletionBlock:(void (^)(NRBaseRequest *request, NSString *error))block;
@end
NS_ASSUME_NONNULL_END
//
// NRBaseRequest.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
#import "NRGlobalUrlModel.h"
#define kBaseApiOtherError @"服务器错误,请稍后再试"
#define kSuccHttpCode 0
@implementation NRBaseRequest
- (void)dealloc {
NSLog(@"dealloc %@", [NSString stringWithUTF8String:class_getName([self class])]);
}
- (NSString *)baseUrl {
return [NRGlobalUrlModel sharedInstance].kHost;
}
-(BOOL)statusCodeValidator{
return YES;
}
- (BOOL)ignoreCache {
return YES;
}
- (YTKRequestMethod)requestMethod {
return YTKRequestMethodPOST;
}
//- (BaseHttpModel *)httpModel {
// if (!_httpModel) {
// NSArray *arr = [[BookModelAgent agent] createModel:[BaseHttpModel class] fromJson:self.responseJSONObject];
// _httpModel = [arr objectAtIndexSafely:0];
// }
//
// return _httpModel;
//}
//- (BOOL)isSucc {
// BaseHttpModel *httpModel = self.httpModel;
// return httpModel && httpModel.errcode == kSuccHttpCode;
//}
//- (NSString *)errorMsg {
// BaseHttpModel *httpModel = self.httpModel;
// return httpModel.errmsg.length > 0 ? httpModel.errmsg : kBaseApiOtherError;
//}
#pragma mark ————— 如果是加密方式传输,自定义request —————
-(NSURLRequest *)buildCustomUrlRequest{
return nil;
}
- (void)startWithCompletionBlock:(void (^)(NRBaseRequest *request, NSString *error))block {
__weak __typeof(self) weakSelf = self;
[self startWithCompletionBlockWithSuccess:^(__kindof YTKBaseRequest *_Nonnull request) {
if (!block) {
return;
}
__strong typeof(weakSelf) strongSelf = weakSelf;
// if ([strongSelf isSucc]) {
// block(strongSelf, nil);
// }
// else {
// block(strongSelf, [strongSelf errorMsg]);
// }
} failure:^(__kindof YTKBaseRequest *_Nonnull request) {
if (!block) {
return;
}
__strong typeof(weakSelf) strongSelf = weakSelf;
block(strongSelf, request.error.userInfo[NSLocalizedDescriptionKey] ?: kBaseApiOtherError);
}];
}
@end
//
// BaseRequestAPI.h
// NetrainFrame
//
// Created by Gin on 2020/9/21.
//
#import "BaseRequestAPI.h"
@implementation BaseRequestAPI
-(instancetype)init{
self = [super init];
if (self) {
}
return self;
}
#pragma mark ————— 自定义数据 —————
- (NSString *)message {
if (self.error) {
return self.error.localizedDescription;
}
NSString *message = [NSString stringWithFormat:@"%@",self.result[@"codemsg"]];
return message;
}
- (NSString *)code {
NSString *code = [NSString stringWithFormat:@"%@",self.result[@"code"]];
return code;
}
- (BOOL)isSuccess {
NSString *code = [self code];
BOOL isSuccess = NO;
if ([code isEqualToString:@"0"]) {
isSuccess = YES;
}
return isSuccess;
}
#pragma mark ————— 定义返回数据格式,若是加密要用HTTP接受 —————
-(YTKResponseSerializerType)responseSerializerType {
return YTKResponseSerializerTypeJSON;
}
#pragma mark ————— 默认请求方式 POST —————
-(YTKRequestMethod)requestMethod{
return YTKRequestMethodPOST;
}
#pragma mark ————— 请求失败过滤器 —————
-(void)requestFailedFilter{
//失败处理器
}
#pragma mark ————— 请求成功过滤器 —————
-(void)requestCompleteFilter{
self.result = self.responseJSONObject;
}
#pragma mark ————— 非加密时也要传输的头部内容 也可能不需要,暂时保留 —————
-(NSDictionary<NSString *,NSString *> *)requestHeaderFieldValueDictionary{
//header部分
return @{};
}
#pragma mark ————— 如果是加密方式传输,自定义request —————
-(NSURLRequest *)buildCustomUrlRequest{
return nil;
}
@end
//
// NRCommonViewController.h
// NetrainFrame
//
// Created by Gin on 2020/9/22.
//
#import <QMUIKit/QMUIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface NRCommonViewController : QMUICommonViewController
+(instancetype)instantiateWithStoryboardName:(NSString *)storyboardName;
@end
NS_ASSUME_NONNULL_END
//
// NRCommonViewController.m
// NetrainFrame
//
// Created by Gin on 2020/9/22.
//
#import "NRCommonViewController.h"
@interface NRCommonViewController ()
@end
@implementation NRCommonViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
+(instancetype)instantiateWithStoryboardName:(NSString *)storyboardName{
NSString *fullName = NSStringFromClass(self);
NSString *className = [fullName componentsSeparatedByString:@"."].lastObject;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:[NSBundle mainBundle]];
return [storyboard instantiateViewControllerWithIdentifier:className];
}
- (BOOL)shouldCustomizeNavigationBarTransitionIfHideable {
return YES;
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
//
// CTMediator+MainCoordinatorActions.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import <CTMediator/CTMediator.h>
NS_ASSUME_NONNULL_BEGIN
@interface CTMediator (MainCoordinatorActions)
- (UIViewController *)CTMediator_viewControllerForLoginCoordinator;
@end
NS_ASSUME_NONNULL_END
//
// CTMediator+MainCoordinatorActions.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "CTMediator+MainCoordinatorActions.h"
NSString * const kCTMediatorTargetLoginCoordinator = @"LoginCoordinator";
NSString * const kCTMediatorActionLoginCoordinatorRootController = @"LoginCoordinatorRootController";
@implementation CTMediator (MainCoordinatorActions)
- (UIViewController *)CTMediator_viewControllerForLoginCoordinator{
UIViewController *viewController = [self performTarget:kCTMediatorTargetLoginCoordinator
action:kCTMediatorActionLoginCoordinatorRootController
params:nil
shouldCacheTarget:NO
];
if (viewController) {
// view controller 交付出去之后,可以由外界选择是push还是present
return viewController;
} else {
// 这里处理异常场景,具体如何处理取决于产品
return [[UINavigationController alloc] init];
}
}
@end
//
// MainCoordinator.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface MainCoordinator : NSObject
- (instancetype)initWithWindow:(UIWindow *)window;
- (void)start;
@end
NS_ASSUME_NONNULL_END
//
// MainCoordinator.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "MainCoordinator.h"
#import "CTMediator+MainCoordinatorActions.h"
@interface MainCoordinator()
@property(nonatomic, weak) UIWindow *window;
@property(nonatomic, strong) NSMutableArray *childCoordinators;
@end
@implementation MainCoordinator
- (instancetype)initWithWindow:(UIWindow *)window
{
self = [super init];
if (self) {
self.window = window;
}
return self;
}
-(void)start{
BOOL isLogin = YES;
if(isLogin){
[self showLogin];
}else{
[self showLogin];
}
}
-(void)close:(NSObject *)loginCoordinator{
[self.childCoordinators removeObject:loginCoordinator];
[self showNew];
}
- (void)showLogin{
UIViewController *viewController = [[CTMediator sharedInstance] CTMediator_viewControllerForLoginCoordinator];
self.window.rootViewController = viewController;
[self.window makeKeyAndVisible];
}
-(void)showNew{
// UITabBarController *navigationController = [[UITabBarController alloc] init];
// NewCoordinator *newCoordinator = [[NewCoordinator alloc] initWithNavigationController:navigationController];
// [newCoordinator start];
//
// [self.childCoordinators addObject:newCoordinator];
//
// self.window.rootViewController = navigationController;
// [self.window makeKeyAndVisible];
}
- (NSMutableArray *)childCoordinators {
if (!_childCoordinators) {
self.childCoordinators = [NSMutableArray array];
}
return _childCoordinators;
}
@end
......@@ -12,6 +12,27 @@
#define FontAndColorMacros_h
#pragma mark - 颜色区
#pragma 颜色
///主题文字色,当前为蓝色(部分标签的颜色,跟项目主题色相似)
#define UIColorThemeColor [UIColor qmui_colorWithHexString:@"009AFF"]
///主题边框色,当前为浅蓝(部分标签边框的颜色,跟项目主题色相似)
#define UIColorThemeBorderColor [UIColor qmui_colorWithHexString:@"58BDFF"]
///主题线颜色,当前为灰色(分隔线的颜色)
#define UIColorThemeLineColor [UIColor qmui_colorWithHexString:@"F5F5F5"]
///主题提示文字颜色(输入框提示文字的颜色,比如:请务必上传医生头像)
#define UIColorThemePlaceholderColor [UIColor qmui_colorWithHexString:@"989898"]
///主题输入文字颜色(输入框输入文字的颜色)
#define UIColorThemeInputColor [UIColor qmui_colorWithHexString:@"171717"]
///主题黑色按钮颜色(部分按钮的颜色,类似获取验证码按钮)
#define UIColorThemeButtonBlackColor [UIColor qmui_colorWithHexString:@"444444"]
///部分页面灰色底色(部分页面的底色,大部分为白色)
#define UIColorThemePageBgGrayColor [UIColor qmui_colorWithHexString:@"f7f7f7"]
///导航栏标题颜色(导航栏标题颜色)
#define UIColorThemeNavTitleColor [UIColor qmui_colorWithHexString:@"151515"]
///详情文字颜色(详情内容的文字颜色,比如处方详情里编号、分发的文字颜色)
#define UIColorThemeDetailsTextColor [UIColor qmui_colorWithHexString:@"727272"]
///提示警告文字颜色(警告颜色,比如输入框的错误提示)
#define UIColorThemeWarningTextColor [UIColor qmui_colorWithHexString:@"D70C19"]
#pragma mark - 字号区
......
......@@ -114,11 +114,11 @@
//单例化一个类
#define SINGLETON_FOR_HEADER(className) \
\
+ (className *)shared##className;
+ (className *)sharedInstance;
#define SINGLETON_FOR_CLASS(className) \
\
+ (className *)shared##className { \
+ (className *)sharedInstance { \
static className *shared##className = nil; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
......
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17125"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Login View Controller-->
<scene sceneID="FPP-0e-dPZ">
<objects>
<viewController storyboardIdentifier="NRLoginViewController" id="lEQ-vc-MoR" customClass="NRLoginViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="r66-52-jhc"/>
<viewControllerLayoutGuide type="bottom" id="gAA-d4-x0P"/>
</layoutGuides>
<view key="view" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="NvT-cF-ABB">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="login_appicon" translatesAutoresizingMaskIntoConstraints="NO" id="A7P-WW-CGm">
<rect key="frame" x="96" y="107" width="222" height="43.5"/>
<constraints>
<constraint firstAttribute="width" secondItem="A7P-WW-CGm" secondAttribute="height" multiplier="51:10" id="dtv-sU-DwP"/>
</constraints>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vKo-i7-J49">
<rect key="frame" x="0.0" y="150.5" width="414" height="745.5"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="wyh-Ns-Hqe">
<rect key="frame" x="62" y="99" width="290" height="40"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="OHq-WP-oWX">
<rect key="frame" x="0.0" y="0.0" width="145" height="40"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" selected="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1G8-sj-soR">
<rect key="frame" x="0.0" y="0.0" width="145" height="32"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
<state key="normal" title="验证码登录">
<color key="titleColor" red="0.58039215690000001" green="0.58039215690000001" blue="0.58039215690000001" alpha="1" colorSpace="calibratedRGB"/>
</state>
<state key="selected">
<color key="titleColor" red="0.0" green="0.60392156860000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="verificationLogin:" destination="lEQ-vc-MoR" eventType="touchUpInside" id="O6g-Vi-eDT"/>
</connections>
</button>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="login_bottomarc" translatesAutoresizingMaskIntoConstraints="NO" id="ucu-at-F6A">
<rect key="frame" x="59.5" y="33" width="26" height="7"/>
</imageView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="ucu-at-F6A" firstAttribute="centerX" secondItem="OHq-WP-oWX" secondAttribute="centerX" id="5tn-Xm-V0d"/>
<constraint firstAttribute="bottom" secondItem="ucu-at-F6A" secondAttribute="bottom" id="ceS-RZ-kUG"/>
<constraint firstItem="1G8-sj-soR" firstAttribute="top" secondItem="OHq-WP-oWX" secondAttribute="top" id="e5s-zW-yBB"/>
<constraint firstAttribute="trailing" secondItem="1G8-sj-soR" secondAttribute="trailing" id="eHQ-9m-96n"/>
<constraint firstItem="1G8-sj-soR" firstAttribute="leading" secondItem="OHq-WP-oWX" secondAttribute="leading" id="rCu-BR-53S"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Obh-pX-TO3">
<rect key="frame" x="145" y="0.0" width="145" height="40"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vM0-wb-1QU">
<rect key="frame" x="0.0" y="0.0" width="145" height="32"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
<state key="normal" title="账号密码登录">
<color key="titleColor" red="0.58039215690000001" green="0.58039215690000001" blue="0.58039215690000001" alpha="1" colorSpace="calibratedRGB"/>
</state>
<state key="selected">
<color key="titleColor" red="0.0" green="0.60392156860000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="passwdLogin:" destination="lEQ-vc-MoR" eventType="touchUpInside" id="dYA-Du-tko"/>
</connections>
</button>
<imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="login_bottomarc" translatesAutoresizingMaskIntoConstraints="NO" id="gGi-77-IJJ">
<rect key="frame" x="59.5" y="33" width="26" height="7"/>
</imageView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="gGi-77-IJJ" firstAttribute="centerX" secondItem="Obh-pX-TO3" secondAttribute="centerX" id="0dn-lR-UCq"/>
<constraint firstItem="vM0-wb-1QU" firstAttribute="top" secondItem="Obh-pX-TO3" secondAttribute="top" id="6yu-93-gqt"/>
<constraint firstItem="vM0-wb-1QU" firstAttribute="leading" secondItem="Obh-pX-TO3" secondAttribute="leading" id="7kU-8G-6mo"/>
<constraint firstAttribute="trailing" secondItem="vM0-wb-1QU" secondAttribute="trailing" id="EGT-wt-bHi"/>
<constraint firstAttribute="bottom" secondItem="gGi-77-IJJ" secondAttribute="bottom" id="SC7-3R-Ul2"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="OHq-WP-oWX" secondAttribute="bottom" id="3zy-Sa-DFm"/>
<constraint firstItem="OHq-WP-oWX" firstAttribute="leading" secondItem="wyh-Ns-Hqe" secondAttribute="leading" id="Eul-c5-GkM"/>
<constraint firstAttribute="height" constant="40" id="OjD-8v-oLd"/>
<constraint firstAttribute="trailing" secondItem="Obh-pX-TO3" secondAttribute="trailing" id="Qys-Bs-TZK"/>
<constraint firstItem="Obh-pX-TO3" firstAttribute="leading" secondItem="OHq-WP-oWX" secondAttribute="trailing" id="TOX-Nk-1dP"/>
<constraint firstItem="Obh-pX-TO3" firstAttribute="top" secondItem="wyh-Ns-Hqe" secondAttribute="top" id="YmU-LS-Km6"/>
<constraint firstAttribute="bottom" secondItem="Obh-pX-TO3" secondAttribute="bottom" id="gIW-D5-tHf"/>
<constraint firstItem="OHq-WP-oWX" firstAttribute="top" secondItem="wyh-Ns-Hqe" secondAttribute="top" id="j40-2E-gij"/>
<constraint firstItem="Obh-pX-TO3" firstAttribute="width" secondItem="OHq-WP-oWX" secondAttribute="width" id="yDE-fQ-tya"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="vae-3O-euL" userLabel="账号">
<rect key="frame" x="32" y="157" width="350" height="47"/>
<subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="请输入手机号码" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="PcG-Ci-lFt" customClass="QMUITextField">
<rect key="frame" x="19" y="0.0" width="212" height="47"/>
<color key="textColor" red="0.090196078430000007" green="0.090196078430000007" blue="0.090196078430000007" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<textInputTraits key="textInputTraits" keyboardType="numberPad"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="maximumTextLength">
<integer key="value" value="11"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textField>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0dh-8W-io8">
<rect key="frame" x="248" y="7.5" width="90" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="90" id="6jj-Au-gza"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<state key="normal" title="获取验证码">
<color key="titleColor" red="0.44705882349999998" green="0.44705882349999998" blue="0.44705882349999998" alpha="1" colorSpace="calibratedRGB"/>
</state>
<connections>
<action selector="getVerification:" destination="lEQ-vc-MoR" eventType="touchUpInside" id="Vxt-4J-ryq"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="PcG-Ci-lFt" firstAttribute="leading" secondItem="vae-3O-euL" secondAttribute="leading" constant="19" id="57a-HW-rLf"/>
<constraint firstItem="PcG-Ci-lFt" firstAttribute="top" secondItem="vae-3O-euL" secondAttribute="top" id="Bqt-bD-hwf"/>
<constraint firstItem="0dh-8W-io8" firstAttribute="centerY" secondItem="vae-3O-euL" secondAttribute="centerY" id="D1Q-QT-qMV"/>
<constraint firstAttribute="bottom" secondItem="PcG-Ci-lFt" secondAttribute="bottom" id="WcH-7m-bg3"/>
<constraint firstAttribute="height" constant="47" id="buP-aL-9Pv"/>
<constraint firstItem="0dh-8W-io8" firstAttribute="leading" secondItem="PcG-Ci-lFt" secondAttribute="trailing" constant="17" id="fSA-bt-SZr"/>
<constraint firstAttribute="trailing" secondItem="0dh-8W-io8" secondAttribute="trailing" constant="12" id="pNV-hs-YEz"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<real key="value" value="23.5"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="L5M-FD-5JA" userLabel="密码">
<rect key="frame" x="32" y="215" width="350" height="47"/>
<subviews>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Nw5-2b-6cL" userLabel="eyes">
<rect key="frame" x="315" y="8.5" width="23" height="30"/>
<constraints>
<constraint firstAttribute="width" constant="23" id="O5o-kC-Ww6"/>
<constraint firstAttribute="width" secondItem="Nw5-2b-6cL" secondAttribute="height" multiplier="17:22" id="kOf-yd-8xn"/>
</constraints>
<state key="normal" image="login_eyes_close"/>
<state key="selected" image="login_eyes_open"/>
<connections>
<action selector="showPassword:" destination="lEQ-vc-MoR" eventType="touchUpInside" id="Paa-cY-VBD"/>
</connections>
</button>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="请输入验证码" textAlignment="natural" minimumFontSize="17" clearButtonMode="whileEditing" translatesAutoresizingMaskIntoConstraints="NO" id="rNJ-md-dUV" customClass="QMUITextField">
<rect key="frame" x="19" y="0.0" width="279" height="47"/>
<color key="textColor" red="0.094117647060000004" green="0.18823529410000001" blue="0.16078431369999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<textInputTraits key="textInputTraits" secureTextEntry="YES"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="maximumTextLength">
<integer key="value" value="16"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</textField>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="rNJ-md-dUV" firstAttribute="top" secondItem="L5M-FD-5JA" secondAttribute="top" id="65X-zK-NSZ"/>
<constraint firstAttribute="trailing" secondItem="Nw5-2b-6cL" secondAttribute="trailing" constant="12" id="CME-mQ-nEb"/>
<constraint firstItem="Nw5-2b-6cL" firstAttribute="leading" secondItem="rNJ-md-dUV" secondAttribute="trailing" constant="17" id="MO0-XL-iHY"/>
<constraint firstItem="rNJ-md-dUV" firstAttribute="leading" secondItem="L5M-FD-5JA" secondAttribute="leading" constant="19" id="Srb-0l-mmT"/>
<constraint firstAttribute="bottom" secondItem="rNJ-md-dUV" secondAttribute="bottom" id="bRY-wu-6d5"/>
<constraint firstAttribute="height" constant="47" id="ebT-ho-afS"/>
<constraint firstItem="Nw5-2b-6cL" firstAttribute="centerY" secondItem="L5M-FD-5JA" secondAttribute="centerY" id="jgc-9x-VQP"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<real key="value" value="23.5"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
<button opaque="NO" contentMode="scaleToFill" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0Pb-k4-iRd">
<rect key="frame" x="25" y="287" width="364" height="61"/>
<constraints>
<constraint firstAttribute="height" constant="61" id="hsk-bA-ZVT"/>
</constraints>
<fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
<inset key="titleEdgeInsets" minX="0.0" minY="0.0" maxX="0.0" maxY="8"/>
<state key="normal" title="登录" backgroundImage="common_button_bgView_available"/>
<state key="disabled" backgroundImage="common_button_bgView_notavailable"/>
<connections>
<action selector="loginBtnClick:" destination="lEQ-vc-MoR" eventType="touchUpInside" id="ybp-d8-st9"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="usa-iv-mOu">
<rect key="frame" x="135" y="356" width="144" height="30"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="trailing" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="RM9-io-zhF">
<rect key="frame" x="0.0" y="0.0" width="62" height="30"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<state key="normal" title="快速注册">
<color key="titleColor" red="0.0" green="0.60392156860000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<segue destination="h8n-sm-Z0M" kind="push" id="9nW-H0-Bk4"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2wm-Ty-33d">
<rect key="frame" x="72" y="7.5" width="1" height="15"/>
<color key="backgroundColor" red="0.1843137255" green="0.69411764710000001" blue="1" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" constant="1" id="0wk-R7-Hp5"/>
<constraint firstAttribute="height" constant="15" id="qya-Aq-zRl"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="nEz-Fz-pun">
<rect key="frame" x="82" y="0.0" width="62" height="30"/>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<state key="normal" title="忘记密码">
<color key="titleColor" red="0.0" green="0.60392156860000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="2wm-Ty-33d" firstAttribute="leading" secondItem="RM9-io-zhF" secondAttribute="trailing" constant="10" id="3U9-bz-nqd"/>
<constraint firstItem="RM9-io-zhF" firstAttribute="top" secondItem="usa-iv-mOu" secondAttribute="top" id="RVM-E3-QWz"/>
<constraint firstAttribute="bottom" secondItem="nEz-Fz-pun" secondAttribute="bottom" id="V26-Zx-hIt"/>
<constraint firstItem="RM9-io-zhF" firstAttribute="leading" secondItem="usa-iv-mOu" secondAttribute="leading" id="W43-LE-nbp"/>
<constraint firstItem="nEz-Fz-pun" firstAttribute="width" secondItem="RM9-io-zhF" secondAttribute="width" id="WHV-TJ-300"/>
<constraint firstItem="nEz-Fz-pun" firstAttribute="leading" secondItem="2wm-Ty-33d" secondAttribute="trailing" constant="9" id="al1-yj-AbP"/>
<constraint firstItem="nEz-Fz-pun" firstAttribute="top" secondItem="usa-iv-mOu" secondAttribute="top" id="b4b-2p-QYg"/>
<constraint firstAttribute="bottom" secondItem="2wm-Ty-33d" secondAttribute="bottom" constant="7.5" id="hnu-f0-a5L"/>
<constraint firstAttribute="bottom" secondItem="RM9-io-zhF" secondAttribute="bottom" id="kQE-fU-dxW"/>
<constraint firstAttribute="trailing" secondItem="nEz-Fz-pun" secondAttribute="trailing" id="oAi-JS-UsK"/>
<constraint firstItem="2wm-Ty-33d" firstAttribute="top" secondItem="usa-iv-mOu" secondAttribute="top" constant="7.5" id="qSr-EJ-oqO"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="0Pb-k4-iRd" firstAttribute="leading" secondItem="vKo-i7-J49" secondAttribute="leading" constant="25" id="3wt-Bv-fBs"/>
<constraint firstAttribute="trailing" secondItem="0Pb-k4-iRd" secondAttribute="trailing" constant="25" id="6uV-fe-jhJ"/>
<constraint firstAttribute="trailing" secondItem="wyh-Ns-Hqe" secondAttribute="trailing" constant="62" id="7bO-2z-q2I"/>
<constraint firstItem="vae-3O-euL" firstAttribute="leading" secondItem="vKo-i7-J49" secondAttribute="leading" constant="32" id="BWa-qY-Tb3"/>
<constraint firstItem="L5M-FD-5JA" firstAttribute="top" secondItem="vae-3O-euL" secondAttribute="bottom" constant="11" id="ISY-vG-m1s"/>
<constraint firstItem="0Pb-k4-iRd" firstAttribute="top" secondItem="L5M-FD-5JA" secondAttribute="bottom" constant="25" id="Krx-of-IZt"/>
<constraint firstItem="wyh-Ns-Hqe" firstAttribute="leading" secondItem="vKo-i7-J49" secondAttribute="leading" constant="62" id="ZM6-tH-VEH"/>
<constraint firstItem="usa-iv-mOu" firstAttribute="centerX" secondItem="vKo-i7-J49" secondAttribute="centerX" id="ZqT-5w-aCP"/>
<constraint firstItem="L5M-FD-5JA" firstAttribute="leading" secondItem="vKo-i7-J49" secondAttribute="leading" constant="32" id="hi1-rP-DcD"/>
<constraint firstItem="vae-3O-euL" firstAttribute="top" secondItem="wyh-Ns-Hqe" secondAttribute="bottom" constant="18" id="iRC-Kh-EiF"/>
<constraint firstAttribute="trailing" secondItem="vae-3O-euL" secondAttribute="trailing" constant="32" id="mXh-7i-ihN"/>
<constraint firstItem="usa-iv-mOu" firstAttribute="top" secondItem="0Pb-k4-iRd" secondAttribute="bottom" constant="8" id="oeR-4p-ILc"/>
<constraint firstAttribute="trailing" secondItem="L5M-FD-5JA" secondAttribute="trailing" constant="32" id="ozq-UH-ROj"/>
<constraint firstItem="wyh-Ns-Hqe" firstAttribute="top" secondItem="vKo-i7-J49" secondAttribute="top" constant="99" id="qCr-Nh-3Lj"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="A7P-WW-CGm" firstAttribute="centerX" secondItem="NvT-cF-ABB" secondAttribute="centerX" id="1KK-iG-7iz"/>
<constraint firstItem="vKo-i7-J49" firstAttribute="leading" secondItem="NvT-cF-ABB" secondAttribute="leading" id="EB1-0e-m9a"/>
<constraint firstItem="vKo-i7-J49" firstAttribute="top" secondItem="A7P-WW-CGm" secondAttribute="bottom" id="F1V-hN-PWW"/>
<constraint firstItem="A7P-WW-CGm" firstAttribute="top" secondItem="NvT-cF-ABB" secondAttribute="top" constant="107" id="Rhg-Ua-KPy"/>
<constraint firstAttribute="bottom" secondItem="vKo-i7-J49" secondAttribute="bottom" id="TVq-yr-Lvo"/>
<constraint firstItem="A7P-WW-CGm" firstAttribute="leading" secondItem="NvT-cF-ABB" secondAttribute="leading" constant="96" id="Wuk-Hd-dQS"/>
<constraint firstAttribute="trailing" secondItem="vKo-i7-J49" secondAttribute="trailing" id="gDL-rm-gdw"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="EOF-av-wOX"/>
<connections>
<outlet property="accountView" destination="vae-3O-euL" id="7kb-6L-2ax"/>
<outlet property="forgetAndRegisterDividingLine" destination="2wm-Ty-33d" id="ldA-Pg-rnU"/>
<outlet property="forgetAndRegisterView" destination="usa-iv-mOu" id="vyL-5D-Ujm"/>
<outlet property="forgetPwdButton" destination="nEz-Fz-pun" id="OHz-hx-pW6"/>
<outlet property="loginButton" destination="0Pb-k4-iRd" id="vQg-UI-jfN"/>
<outlet property="passwdBtnBottomArc" destination="gGi-77-IJJ" id="q1A-gC-idc"/>
<outlet property="passwdField" destination="rNJ-md-dUV" id="Owv-a1-hcA"/>
<outlet property="passwdLogBtn" destination="vM0-wb-1QU" id="ETO-nV-Uzf"/>
<outlet property="passwordView" destination="L5M-FD-5JA" id="hz4-0A-s8z"/>
<outlet property="phoneNumberField" destination="PcG-Ci-lFt" id="tzH-Mk-yrg"/>
<outlet property="registerButton" destination="RM9-io-zhF" id="e9E-LE-ebP"/>
<outlet property="showPwdBtn" destination="Nw5-2b-6cL" id="521-Wh-bg2"/>
<outlet property="verificationBtn" destination="0dh-8W-io8" id="ih3-NO-boV"/>
<outlet property="verificationBtnBottomArc" destination="ucu-at-F6A" id="Xbg-R5-pWf"/>
<outlet property="verificationLogBtn" destination="1G8-sj-soR" id="IB5-AM-eds"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="CPF-Af-3DD" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-565" y="-96"/>
</scene>
<!--Register View Controller-->
<scene sceneID="sDY-5k-ocr">
<objects>
<viewController storyboardIdentifier="NRRegisterViewController" id="h8n-sm-Z0M" customClass="NRRegisterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="5dx-nC-obY"/>
<viewControllerLayoutGuide type="bottom" id="8YR-t7-0xR"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="zaq-4J-1KU">
<rect key="frame" x="0.0" y="0.0" width="414" height="842"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<navigationItem key="navigationItem" id="dbh-Jw-NKP"/>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="G5m-J7-4Gf" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="238" y="-135"/>
</scene>
</scenes>
<resources>
<image name="common_button_bgView_available" width="324" height="61"/>
<image name="common_button_bgView_notavailable" width="324" height="61"/>
<image name="login_appicon" width="153" height="30"/>
<image name="login_bottomarc" width="26" height="7"/>
<image name="login_eyes_close" width="17" height="10"/>
<image name="login_eyes_open" width="17" height="10"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
//
// NRLoginViewController.h
// NetrainFrame
//
// Created by Gin on 2020/9/22.
//
#import "NRCommonViewController.h"
@class MainCoordinator;
NS_ASSUME_NONNULL_BEGIN
@interface NRLoginViewController : NRCommonViewController
@property(weak, nonatomic) MainCoordinator *coordinator;
@end
NS_ASSUME_NONNULL_END
//
// NRLoginViewController.m
// NetrainFrame
//
// Created by Gin on 2020/9/22.
//
#import "NRLoginViewController.h"
#import "NRLoginLogic.h"
typedef NS_ENUM(NSUInteger, UserSelectLoginMode) {
passswdLogin = 10, //密码登录
verificationLogin, //验证码登录
};
@interface NRLoginViewController ()<QMUITextFieldDelegate>
@property (weak, nonatomic) IBOutlet QMUITextField *phoneNumberField;
@property (weak, nonatomic) IBOutlet QMUITextField *passwdField;
@property (weak, nonatomic) IBOutlet UIButton *showPwdBtn;
@property (weak, nonatomic) IBOutlet UIButton *loginButton;
@property (weak, nonatomic) IBOutlet UIButton *verificationBtn;
@property (weak, nonatomic) IBOutlet UIImageView *verificationBtnBottomArc;
@property (weak, nonatomic) IBOutlet UIButton *passwdLogBtn;
@property (weak, nonatomic) IBOutlet UIImageView *passwdBtnBottomArc;
@property (weak, nonatomic) IBOutlet UIButton *verificationLogBtn;
@property (assign, nonatomic) UserSelectLoginMode loginMode;
@property (strong,nonatomic) NSDate *resignBackgroundDate;
@property (assign,nonatomic) int timeout;
@property (strong,nonatomic) NSTimer* countDownTimer;
@property (weak, nonatomic) IBOutlet UIView *forgetAndRegisterView;
@property (weak, nonatomic) IBOutlet UIView *accountView;
@property (weak, nonatomic) IBOutlet UIButton *registerButton;
@property (weak, nonatomic) IBOutlet UIView *forgetAndRegisterDividingLine;
@property (weak, nonatomic) IBOutlet UIButton *forgetPwdButton;
@property (weak, nonatomic) IBOutlet UIView *passwordView;
///Logic
@property(strong, nonatomic) NRLoginLogic *loginLogic;
@end
#define kAccountMaxLength 11 //手机号长度限制
#define kPassswordMaxLength 16 //登录密码长度最大限制
#define kPassswordMinLength 9 //登录密码长度最小限制
#define kVerifyCodeMaxLength 4 //验证码长度限制
@implementation NRLoginViewController
-(BOOL)preferredNavigationBarHidden{
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self configSubviews];
// Do any additional setup after loading the view.
}
-(void)initSubviews{
[super initSubviews];
self.accountView.layer.borderColor = UIColorThemeLineColor.CGColor;
self.passwordView.layer.borderColor = UIColorThemeLineColor.CGColor;
self.accountView.layer.borderWidth = 1;
self.passwordView.layer.borderWidth = 1;
[self.registerButton setTitleColor:UIColorThemeColor forState:UIControlStateNormal];
[self.forgetPwdButton setTitleColor:UIColorThemeColor forState:UIControlStateNormal];
[self.forgetAndRegisterDividingLine setBackgroundColor:UIColorThemeBorderColor];
[self.passwdLogBtn setTitleColor:UIColorThemeColor forState:UIControlStateSelected];
[self.verificationLogBtn setTitleColor:UIColorThemeColor forState:UIControlStateSelected];
[self.verificationBtn setTitleColor:UIColorThemeButtonBlackColor forState:UIControlStateNormal];
}
-(void)configSubviews{
self.loginMode = verificationLogin;
self.passwdField.maximumTextLength = (self.loginMode == passswdLogin)? kPassswordMaxLength : kVerifyCodeMaxLength;
self.passwdField.keyboardType = self.loginMode == passswdLogin? UIKeyboardTypeNumbersAndPunctuation : UIKeyboardTypeNumberPad;
self.phoneNumberField.delegate = self;
self.passwdField.delegate = self;
}
#pragma mark -- QMUITextFieldDelegate
-(void)textFieldDidBeginEditing:(UITextField *)textField{
if(textField == self.phoneNumberField){
self.accountView.layer.borderColor = UIColorThemeBorderColor.CGColor;
}else{
self.passwordView.layer.borderColor=UIColorThemeBorderColor.CGColor;
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
[self checkLoginStatus];
return YES;
}
-(void)textFieldDidEndEditing:(UITextField *)textField{
if(textField == self.phoneNumberField){
self.accountView.layer.borderColor = UIColorThemeLineColor.CGColor;
}else{
self.passwordView.layer.borderColor=UIColorThemeLineColor.CGColor;
}
}
#pragma mark -- IBAction
///显示密码
- (IBAction)showPassword:(id)sender {
UIButton *btn = (UIButton *)sender;
btn.selected = !btn.selected;
self.passwdField.secureTextEntry = btn.selected ? NO : YES;
}
///点击登录
- (IBAction)loginBtnClick:(id)sender {
if(self.loginMode == verificationLogin){
[self.loginLogic verifyCodeLoginAction];
}else{
[self.loginLogic passwordLoginAction];
}
}
///获取验证码
- (IBAction)getVerification:(id)sender {
[self.loginLogic getVerifyCodeAction:self.phoneNumberField.text];
}
///密码登录
- (IBAction)passwdLogin:(id)sender {
[self.phoneNumberField becomeFirstResponder];
self.passwdField.text = @"";
self.passwdField.placeholder = @"请输入密码";
self.verificationBtn.hidden = YES;
self.showPwdBtn.hidden = NO;
self.passwdLogBtn.selected = YES;
self.passwdBtnBottomArc.hidden = NO;
self.verificationLogBtn.selected = NO;
self.verificationBtnBottomArc.hidden = YES;
self.passwdField.maximumTextLength = kPassswordMaxLength;
self.loginMode = passswdLogin;
self.passwdField.secureTextEntry = YES;
self.passwdField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
[self checkLoginStatus];
}
///验证码登录
- (IBAction)verificationLogin:(id)sender {
[self.phoneNumberField becomeFirstResponder];
self.passwdField.text = @"";
self.passwdField.placeholder = @"请输入验证码";
self.verificationBtn.hidden = NO;
self.showPwdBtn.hidden = YES;
self.passwdLogBtn.selected = NO;
self.passwdBtnBottomArc.hidden = YES;
self.verificationLogBtn.selected = YES;
self.verificationBtnBottomArc.hidden = NO;
self.passwdField.maximumTextLength = kVerifyCodeMaxLength;
self.loginMode = verificationLogin;
self.passwdField.keyboardType = UIKeyboardTypeNumberPad;
self.passwdField.secureTextEntry = NO;
[self checkLoginStatus];
}
#pragma mark -- private method
//按钮状态随文本变化而变化
- (void)checkLoginStatus{
if (self.loginMode == verificationLogin) {
if(self.passwdField.text.length == kVerifyCodeMaxLength && self.phoneNumberField.text.length == kAccountMaxLength) {
self.loginButton.enabled = YES;
}else{
if(self.loginButton.isEnabled){
self.loginButton.enabled = NO;
}
}
}else{
if(self.passwdField.text.length >= kPassswordMinLength && self.passwdField.text.length <= kPassswordMaxLength && self.phoneNumberField.text.length == kAccountMaxLength) {
self.loginButton.enabled = YES;
}
else{
if(self.loginButton.isEnabled){
self.loginButton.enabled = NO;
}
}
}
}
-(NRLoginLogic *)loginLogic{
if(!_loginLogic){
_loginLogic = [[NRLoginLogic alloc] init];
}
return _loginLogic;
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
//
// NRRegisterViewController.h
// NetrainFrame
//
// Created by Gin on 2020/9/22.
//
#import "NRCommonViewController.h"
NS_ASSUME_NONNULL_BEGIN
@interface NRRegisterViewController : NRCommonViewController
@end
NS_ASSUME_NONNULL_END
//
// NRRegisterViewController.m
// NetrainFrame
//
// Created by Gin on 2020/9/22.
//
#import "NRRegisterViewController.h"
@interface NRRegisterViewController ()
@end
@implementation NRRegisterViewController
- (BOOL)preferredNavigationBarHidden {
return NO;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
-(void)dealloc{
NSLog(@"register delloc");
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
//
// NRLoginCoordinator.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Target_LoginCoordinator : NSObject
- (UIViewController *)Action_LoginCoordinatorRootController:(NSDictionary *)params;
@end
NS_ASSUME_NONNULL_END
//
// NRLoginCoordinator.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "Target_LoginCoordinator.h"
#import "NRLoginViewController.h"
@interface Target_LoginCoordinator()
@property(nonatomic, weak) UINavigationController *navigationController;
@end
@implementation Target_LoginCoordinator
- (UIViewController *)Action_LoginCoordinatorRootController:(NSDictionary *)params{
NRLoginViewController *vc = [NRLoginViewController instantiateWithStoryboardName:@"NRLogin"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:vc];
return navigationController;
}
@end
//
// NRLoginLogic.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
@protocol NRLoginLogicDelegate <NSObject>
@optional
/**
数据加载开始
*/
-(void)requestDataStarted;
/**
数据加载完成
*/
-(void)requestDataCompleted;
@end
NS_ASSUME_NONNULL_BEGIN
@interface NRLoginLogic : NRBaseRequest
@property(nonatomic,weak)id<NRLoginLogicDelegate> delegagte;
- (void)getVerifyCodeAction:(NSString *)phoneNumber;
- (void)verifyCodeLoginAction;
- (void)passwordLoginAction;
@end
NS_ASSUME_NONNULL_END
//
// NRLoginLogic.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRLoginLogic.h"
#import "NRPasswordLoginRequest.h"
#import "NRServerTimeRequest.h"
#import "NRVerifyCodeRequest.h"
@implementation NRLoginLogic
- (void)getVerifyCodeAction:(NSString *)phoneNumber{
NRServerTimeRequest *servertimeRequest = [[NRServerTimeRequest alloc] init];
[servertimeRequest startWithCompletionBlock:^(NRBaseRequest * _Nonnull request, NSString * _Nonnull error) {
if (!error) {
if (self.delegagte && [self.delegagte respondsToSelector:@selector(requestDataCompleted)]) {
[self.delegagte requestDataCompleted];
}
}
}];
}
- (void)verifyCodeLoginAction{
}
- (void)passwordLoginAction{
}
@end
//
// NRLoginKeyRequest.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface NRLoginKeyRequest : NRBaseRequest
@end
NS_ASSUME_NONNULL_END
//
// NRLoginKeyRequest.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRLoginKeyRequest.h"
@implementation NRLoginKeyRequest
-(NSString *)requestUrl{
return @"/login/genLoginKey";
}
@end
//
// NRLoginRequest.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface NRPasswordLoginRequest : NRBaseRequest
@end
NS_ASSUME_NONNULL_END
//
// NRLoginRequest.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRPasswordLoginRequest.h"
@implementation NRPasswordLoginRequest
-(NSString *)requestUrl{
return @"/login";
}
@end
//
// NRRegisterRequest.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface NRRegisterRequest : NRBaseRequest
@end
NS_ASSUME_NONNULL_END
//
// NRRegisterRequest.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRRegisterRequest.h"
@implementation NRRegisterRequest
@end
//
// NRServerTimeRequest.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface NRServerTimeRequest : NRBaseRequest
@end
NS_ASSUME_NONNULL_END
//
// NRServerTimeRequest.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRServerTimeRequest.h"
@implementation NRServerTimeRequest
-(NSString *)requestUrl{
return @"/time.jsp";
}
@end
//
// NRVerifyCodeLoginRequest.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface NRVerifyCodeLoginRequest : NRBaseRequest
@end
NS_ASSUME_NONNULL_END
//
// NRVerifyCodeLoginRequest.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRVerifyCodeLoginRequest.h"
@implementation NRVerifyCodeLoginRequest
-(NSString *)requestUrl{
return @"/login/validLogin";
}
-(id)requestArgument{
return @{};
}
@end
//
// NRVerifyCodeRequest.h
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRBaseRequest.h"
NS_ASSUME_NONNULL_BEGIN
@interface NRVerifyCodeRequest : NRBaseRequest
@property(nonatomic, copy) NSString *phoneNumber;
@end
NS_ASSUME_NONNULL_END
//
// NRVerifyCodeRequest.m
// NetrainFrame
//
// Created by Gin on 2020/9/23.
//
#import "NRVerifyCodeRequest.h"
@implementation NRVerifyCodeRequest
-(NSString *)requestUrl{
return @"/sendSms";
}
@end
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.000",
"green" : "0.000",
"red" : "0.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.000",
"green" : "0.000",
"red" : "0.000"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "分组@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "分组@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "分组@2x(1).png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "分组@3x(1).png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "分组 2@2x(1).png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "分组 2@3x(1).png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "路径@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "路径@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "btn_psw_invisible@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "btn_psw_invisible@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "btn_psw_available@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "btn_psw_available@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "login_password_delete@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "login_password_delete@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
\ No newline at end of file
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "椭圆形@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "椭圆形@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "分组 2@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "分组 2@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
......@@ -14,6 +14,10 @@
#import "ThirdMacros.h"
#import "NotificationMacros.h"
///Model解析
#import "NRBaseModelAgent.h"
//第三方
#import <Masonry.h>
#import <YYModel.h>
......
/**
* Tencent is pleased to support the open source community by making QMUI_iOS available.
* Copyright (C) 2016-2020 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
//
// QMUIConfigurationTemplate.h
//
// Created by QMUI Team on 15/3/29.
//
#import <Foundation/Foundation.h>
#import <QMUIKit/QMUIKit.h>
/**
* QMUIConfigurationTemplate 是一份配置表,用于配合 QMUIConfiguration 来管理整个 App 的全局样式,使用方式:
* 在 QMUI 项目代码的文件夹里找到 QMUIConfigurationTemplate 目录,把里面所有文件复制到自己项目里,保证能被编译到即可,不需要在某些地方 import,也不需要手动运行。
*
* @warning 更新 QMUIKit 的版本时,请留意 Release Log 里是否有提醒更新配置表,请尽量保持自己项目里的配置表与 QMUIKit 里的配置表一致,避免遗漏新的属性。
* @warning 配置表的 class 名必须以 QMUIConfigurationTemplate 开头,并且实现 <QMUIConfigurationTemplateProtocol>,因为这两者是 QMUI 识别该 NSObject 是否为一份配置表的条件。
* @warning QMUI 2.3.0 之后,配置表改为自动运行,不需要再在某个地方手动运行了。
*/
@interface QMUIConfigurationTemplate : NSObject <QMUIConfigurationTemplateProtocol>
@end
/**
* Tencent is pleased to support the open source community by making QMUI_iOS available.
* Copyright (C) 2016-2020 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
//
// QMUIConfigurationTemplate.m
// qmui
//
// Created by QMUI Team on 15/3/29.
//
#import "QMUIConfigurationTemplate.h"
#import <QMUIKit/QMUIKit.h>
@implementation QMUIConfigurationTemplate
#pragma mark - <QMUIConfigurationTemplateProtocol>
- (void)applyConfigurationTemplate {
// === 修改配置值 === //
#pragma mark - Global Color
QMUICMI.clearColor = UIColorMakeWithRGBA(255, 255, 255, 0); // UIColorClear : 透明色
QMUICMI.whiteColor = UIColorMake(255, 255, 255); // UIColorWhite : 白色(不用 [UIColor whiteColor] 是希望保持颜色空间为 RGB)
QMUICMI.blackColor = UIColorMake(0, 0, 0); // UIColorBlack : 黑色(不用 [UIColor blackColor] 是希望保持颜色空间为 RGB)
QMUICMI.grayColor = UIColorMake(179, 179, 179); // UIColorGray : 最常用的灰色
QMUICMI.grayDarkenColor = UIColorMake(163, 163, 163); // UIColorGrayDarken : 深一点的灰色
QMUICMI.grayLightenColor = UIColorMake(198, 198, 198); // UIColorGrayLighten : 浅一点的灰色
QMUICMI.redColor = UIColorMake(250, 58, 58); // UIColorRed : 红色
QMUICMI.greenColor = UIColorMake(159, 214, 97); // UIColorGreen : 绿色
QMUICMI.blueColor = UIColorMake(49, 189, 243); // UIColorBlue : 蓝色
QMUICMI.yellowColor = UIColorMake(255, 207, 71); // UIColorYellow : 黄色
QMUICMI.linkColor = UIColorMake(56, 116, 171); // UIColorLink : 文字链接颜色
QMUICMI.disabledColor = UIColorGray; // UIColorDisabled : 全局 disabled 的颜色,一般用于 UIControl 等控件
QMUICMI.backgroundColor = nil; // UIColorForBackground : 界面背景色,默认用于 QMUICommonViewController.view 的背景色
QMUICMI.maskDarkColor = UIColorMakeWithRGBA(0, 0, 0, .35f); // UIColorMask : 深色的背景遮罩,默认用于 QMAlertController、QMUIDialogViewController 等弹出控件的遮罩
QMUICMI.maskLightColor = UIColorMakeWithRGBA(255, 255, 255, .5f); // UIColorMaskWhite : 浅色的背景遮罩,QMUIKit 里默认没用到,只是占个位
QMUICMI.separatorColor = UIColorMake(222, 224, 226); // UIColorSeparator : 全局默认的分割线颜色,默认用于列表分隔线颜色、UIView (QMUIBorder) 分隔线颜色
QMUICMI.separatorDashedColor = UIColorMake(17, 17, 17); // UIColorSeparatorDashed : 全局默认的虚线分隔线的颜色,默认 QMUIKit 暂时没用到
QMUICMI.placeholderColor = UIColorMake(196, 200, 208); // UIColorPlaceholder,全局的输入框的 placeholder 颜色,默认用于 QMUITextField、QMUITextView,不影响系统 UIKit 的输入框
// 测试用的颜色
QMUICMI.testColorRed = UIColorMakeWithRGBA(255, 0, 0, .3);
QMUICMI.testColorGreen = UIColorMakeWithRGBA(0, 255, 0, .3);
QMUICMI.testColorBlue = UIColorMakeWithRGBA(0, 0, 255, .3);
#pragma mark - UIControl
QMUICMI.controlHighlightedAlpha = 0.5f; // UIControlHighlightedAlpha : UIControl 系列控件在 highlighted 时的 alpha,默认用于 QMUIButton、 QMUINavigationTitleView
QMUICMI.controlDisabledAlpha = 0.5f; // UIControlDisabledAlpha : UIControl 系列控件在 disabled 时的 alpha,默认用于 QMUIButton
#pragma mark - UIButton
QMUICMI.buttonHighlightedAlpha = UIControlHighlightedAlpha; // ButtonHighlightedAlpha : QMUIButton 在 highlighted 时的 alpha,不影响系统的 UIButton
QMUICMI.buttonDisabledAlpha = UIControlDisabledAlpha; // ButtonDisabledAlpha : QMUIButton 在 disabled 时的 alpha,不影响系统的 UIButton
QMUICMI.buttonTintColor = UIColorBlue; // ButtonTintColor : QMUIButton 默认的 tintColor,不影响系统的 UIButton
QMUICMI.ghostButtonColorBlue = UIColorBlue; // GhostButtonColorBlue : QMUIGhostButtonColorBlue 的颜色
QMUICMI.ghostButtonColorRed = UIColorRed; // GhostButtonColorRed : QMUIGhostButtonColorRed 的颜色
QMUICMI.ghostButtonColorGreen = UIColorGreen; // GhostButtonColorGreen : QMUIGhostButtonColorGreen 的颜色
QMUICMI.ghostButtonColorGray = UIColorGray; // GhostButtonColorGray : QMUIGhostButtonColorGray 的颜色
QMUICMI.ghostButtonColorWhite = UIColorWhite; // GhostButtonColorWhite : QMUIGhostButtonColorWhite 的颜色
QMUICMI.fillButtonColorBlue = UIColorBlue; // FillButtonColorBlue : QMUIFillButtonColorBlue 的颜色
QMUICMI.fillButtonColorRed = UIColorRed; // FillButtonColorRed : QMUIFillButtonColorRed 的颜色
QMUICMI.fillButtonColorGreen = UIColorGreen; // FillButtonColorGreen : QMUIFillButtonColorGreen 的颜色
QMUICMI.fillButtonColorGray = UIColorGray; // FillButtonColorGray : QMUIFillButtonColorGray 的颜色
QMUICMI.fillButtonColorWhite = UIColorWhite; // FillButtonColorWhite : QMUIFillButtonColorWhite 的颜色
#pragma mark - TextInput
QMUICMI.textFieldTextColor = nil; // TextFieldTextColor : QMUITextField、QMUITextView 的 textColor,不影响 UIKit 的输入框
QMUICMI.textFieldTintColor = nil; // TextFieldTintColor : QMUITextField、QMUITextView 的 tintColor,不影响 UIKit 的输入框
QMUICMI.textFieldTextInsets = UIEdgeInsetsMake(0, 7, 0, 7); // TextFieldTextInsets : QMUITextField 的内边距,不影响 UITextField
QMUICMI.keyboardAppearance = UIKeyboardAppearanceDefault; // KeyboardAppearance : UITextView、UITextField、UISearchBar 的 keyboardAppearance
#pragma mark - UISwitch
QMUICMI.switchOnTintColor = nil; // SwitchOnTintColor : UISwitch 打开时的背景色(除了圆点外的其他颜色)
QMUICMI.switchOffTintColor = nil; // SwitchOffTintColor : UISwitch 关闭时的背景色(除了圆点外的其他颜色)
QMUICMI.switchTintColor = nil; // SwitchTintColor : UISwitch 关闭时的周围边框颜色
QMUICMI.switchThumbTintColor = nil; // SwitchThumbTintColor : UISwitch 中间的操控圆点的颜色
#pragma mark - NavigationBar
QMUICMI.navBarHighlightedAlpha = 0.2f; // NavBarHighlightedAlpha : QMUINavigationButton 在 highlighted 时的 alpha
QMUICMI.navBarDisabledAlpha = 0.2f; // NavBarDisabledAlpha : QMUINavigationButton 在 disabled 时的 alpha
QMUICMI.navBarButtonFont = nil; // NavBarButtonFont : QMUINavigationButtonTypeNormal 和 UINavigationBar 上的 UIBarButtonItem 的字体
QMUICMI.navBarButtonFontBold = nil; // NavBarButtonFontBold : QMUINavigationButtonTypeBold 的字体
QMUICMI.navBarBackgroundImage = nil; // NavBarBackgroundImage : UINavigationBar 的背景图
QMUICMI.navBarShadowImage = nil; // NavBarShadowImage : UINavigationBar.shadowImage,也即导航栏底部那条分隔线,配合 NavBarShadowImageColor 使用。
QMUICMI.navBarShadowImageColor = nil; // NavBarShadowImageColor : UINavigationBar.shadowImage 的颜色,如果为 nil,则使用 NavBarShadowImage 的值,如果 NavBarShadowImage 也为 nil,则使用系统默认的分隔线。如果不为 nil,而 NavBarShadowImage 为 nil,则自动创建一张 1px 高的图并将其设置为 NavBarShadowImageColor 的颜色然后设置上去,如果 NavBarShadowImage 不为 nil 且 renderingMode 不为 UIImageRenderingModeAlwaysOriginal,则将 NavBarShadowImage 设置为 NavBarShadowImageColor 的颜色然后设置上去。
QMUICMI.navBarBarTintColor = nil; // NavBarBarTintColor : UINavigationBar.barTintColor,也即背景色
QMUICMI.navBarStyle = UIBarStyleDefault; // NavBarStyle : UINavigationBar 的 barStyle
QMUICMI.navBarTintColor = nil; // NavBarTintColor : QMUINavigationController.navigationBar 的 tintColor,也即导航栏上面的按钮颜色,由于 tintColor 不支持 appearance,所以这里只支持 QMUINavigationController
QMUICMI.navBarTitleColor = nil; // NavBarTitleColor : UINavigationBar 的标题颜色,以及 QMUINavigationTitleView 的默认文字颜色
QMUICMI.navBarTitleFont = nil; // NavBarTitleFont : UINavigationBar 的标题字体,以及 QMUINavigationTitleView 的默认字体
QMUICMI.navBarLargeTitleColor = nil; // NavBarLargeTitleColor : UINavigationBar 在大标题模式下的标题颜色,仅在 iOS 11 之后才有效
QMUICMI.navBarLargeTitleFont = nil; // NavBarLargeTitleFont : UINavigationBar 在大标题模式下的标题字体,仅在 iOS 11 之后才有效
QMUICMI.navBarBackButtonTitlePositionAdjustment = UIOffsetZero; // NavBarBarBackButtonTitlePositionAdjustment : 导航栏返回按钮的文字偏移
QMUICMI.sizeNavBarBackIndicatorImageAutomatically = YES; // SizeNavBarBackIndicatorImageAutomatically : 是否要自动调整 NavBarBackIndicatorImage 的 size 为 (13, 21)
QMUICMI.navBarBackIndicatorImage = nil; // NavBarBackIndicatorImage : 导航栏的返回按钮的图片,图片尺寸建议为(13, 21),否则最终的图片位置无法与系统原生的位置保持一致
QMUICMI.navBarCloseButtonImage = [UIImage qmui_imageWithShape:QMUIImageShapeNavClose size:CGSizeMake(16, 16) tintColor:NavBarTintColor]; // NavBarCloseButtonImage : QMUINavigationButton 用到的 × 的按钮图片
QMUICMI.navBarLoadingMarginRight = 3; // NavBarLoadingMarginRight : QMUINavigationTitleView 里左边 loading 的右边距
QMUICMI.navBarAccessoryViewMarginLeft = 5; // NavBarAccessoryViewMarginLeft : QMUINavigationTitleView 里右边 accessoryView 的左边距
QMUICMI.navBarActivityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;// NavBarActivityIndicatorViewStyle : QMUINavigationTitleView 里左边 loading 的主题
QMUICMI.navBarAccessoryViewTypeDisclosureIndicatorImage = [[UIImage qmui_imageWithShape:QMUIImageShapeTriangle size:CGSizeMake(8, 5) tintColor:nil] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; // NavBarAccessoryViewTypeDisclosureIndicatorImage : QMUINavigationTitleView 右边箭头的图片
#pragma mark - TabBar
QMUICMI.tabBarBackgroundImage = nil; // TabBarBackgroundImage : UITabBar 的背景图
QMUICMI.tabBarBarTintColor = nil; // TabBarBarTintColor : UITabBar 的 barTintColor,如果需要看到磨砂效果则应该提供半透明的色值
QMUICMI.tabBarShadowImageColor = nil; // TabBarShadowImageColor : UITabBar 的 shadowImage 的颜色,会自动创建一张 1px 高的图片
QMUICMI.tabBarStyle = UIBarStyleDefault; // TabBarStyle : UITabBar 的 barStyle
QMUICMI.tabBarItemTitleFont = nil; // TabBarItemTitleFont : UITabBarItem 的标题字体
QMUICMI.tabBarItemTitleColor = nil; // TabBarItemTitleColor : 未选中的 UITabBarItem 的标题颜色
QMUICMI.tabBarItemTitleColorSelected = nil; // TabBarItemTitleColorSelected : 选中的 UITabBarItem 的标题颜色
QMUICMI.tabBarItemImageColor = nil; // TabBarItemImageColor : UITabBarItem 未选中时的图片颜色
QMUICMI.tabBarItemImageColorSelected = nil; // TabBarItemImageColorSelected : UITabBarItem 选中时的图片颜色
#pragma mark - Toolbar
QMUICMI.toolBarHighlightedAlpha = 0.4f; // ToolBarHighlightedAlpha : QMUIToolbarButton 在 highlighted 状态下的 alpha
QMUICMI.toolBarDisabledAlpha = 0.4f; // ToolBarDisabledAlpha : QMUIToolbarButton 在 disabled 状态下的 alpha
QMUICMI.toolBarTintColor = nil; // ToolBarTintColor : UIToolbar 的 tintColor,以及 QMUIToolbarButton normal 状态下的文字颜色
QMUICMI.toolBarTintColorHighlighted = [ToolBarTintColor colorWithAlphaComponent:ToolBarHighlightedAlpha]; // ToolBarTintColorHighlighted : QMUIToolbarButton 在 highlighted 状态下的文字颜色
QMUICMI.toolBarTintColorDisabled = [ToolBarTintColor colorWithAlphaComponent:ToolBarDisabledAlpha]; // ToolBarTintColorDisabled : QMUIToolbarButton 在 disabled 状态下的文字颜色
QMUICMI.toolBarBackgroundImage = nil; // ToolBarBackgroundImage : UIToolbar 的背景图
QMUICMI.toolBarBarTintColor = nil; // ToolBarBarTintColor : UIToolbar 的 tintColor
QMUICMI.toolBarShadowImageColor = nil; // ToolBarShadowImageColor : UIToolbar 的 shadowImage 的颜色,会自动创建一张 1px 高的图片
QMUICMI.toolBarStyle = UIBarStyleDefault; // ToolBarStyle : UIToolbar 的 barStyle
QMUICMI.toolBarButtonFont = nil; // ToolBarButtonFont : QMUIToolbarButton 的字体
#pragma mark - SearchBar
QMUICMI.searchBarTextFieldBackgroundImage = nil; // SearchBarTextFieldBackgroundImage : QMUISearchBar 里的文本框的背景图,图片高度会决定输入框的高度
QMUICMI.searchBarTextFieldBorderColor = nil; // SearchBarTextFieldBorderColor : QMUISearchBar 里的文本框的边框颜色
QMUICMI.searchBarTextFieldCornerRadius = 2.0; // SearchBarTextFieldCornerRadius : QMUISearchBar 里的文本框的圆角大小,-1 表示圆角大小为输入框高度的一半
QMUICMI.searchBarBackgroundImage = nil; // SearchBarBackgroundImage : 搜索框的背景图,如果需要设置底部分隔线的颜色也请绘制到图片里
QMUICMI.searchBarTintColor = nil; // SearchBarTintColor : QMUISearchBar 的 tintColor,也即上面的操作控件的主题色
QMUICMI.searchBarTextColor = nil; // SearchBarTextColor : QMUISearchBar 里的文本框的文字颜色
QMUICMI.searchBarPlaceholderColor = UIColorPlaceholder; // SearchBarPlaceholderColor : QMUISearchBar 里的文本框的 placeholder 颜色
QMUICMI.searchBarFont = nil; // SearchBarFont : QMUISearchBar 里的文本框的文字字体及 placeholder 的字体
QMUICMI.searchBarSearchIconImage = nil; // SearchBarSearchIconImage : QMUISearchBar 里的放大镜 icon
QMUICMI.searchBarClearIconImage = nil; // SearchBarClearIconImage : QMUISearchBar 里的文本框输入文字时右边的清空按钮的图片
#pragma mark - Plain TableView
QMUICMI.tableViewEstimatedHeightEnabled = YES; // TableViewEstimatedHeightEnabled : 是否要开启全局 UITableView 的 estimatedRow(Section/Footer)Height
QMUICMI.tableViewBackgroundColor = nil; // TableViewBackgroundColor : Plain 类型的 QMUITableView 的背景色颜色
QMUICMI.tableSectionIndexColor = nil; // TableSectionIndexColor : 列表右边的字母索引条的文字颜色
QMUICMI.tableSectionIndexBackgroundColor = nil; // TableSectionIndexBackgroundColor : 列表右边的字母索引条的背景色
QMUICMI.tableSectionIndexTrackingBackgroundColor = nil; // TableSectionIndexTrackingBackgroundColor : 列表右边的字母索引条在选中时的背景色
QMUICMI.tableViewSeparatorColor = UIColorSeparator; // TableViewSeparatorColor : 列表的分隔线颜色
QMUICMI.tableViewCellNormalHeight = UITableViewAutomaticDimension; // TableViewCellNormalHeight : QMUITableView 的默认 cell 高度
QMUICMI.tableViewCellTitleLabelColor = nil; // TableViewCellTitleLabelColor : QMUITableViewCell 的 textLabel 的文字颜色
QMUICMI.tableViewCellDetailLabelColor = nil; // TableViewCellDetailLabelColor : QMUITableViewCell 的 detailTextLabel 的文字颜色
QMUICMI.tableViewCellBackgroundColor = nil; // TableViewCellBackgroundColor : QMUITableViewCell 的背景色
QMUICMI.tableViewCellSelectedBackgroundColor = UIColorMake(238, 239, 241); // TableViewCellSelectedBackgroundColor : QMUITableViewCell 点击时的背景色
QMUICMI.tableViewCellWarningBackgroundColor = UIColorYellow; // TableViewCellWarningBackgroundColor : QMUITableViewCell 用于表示警告时的背景色,备用
QMUICMI.tableViewCellDisclosureIndicatorImage = nil; // TableViewCellDisclosureIndicatorImage : QMUITableViewCell 当 accessoryType 为 UITableViewCellAccessoryDisclosureIndicator 时的箭头的图片
QMUICMI.tableViewCellCheckmarkImage = nil; // TableViewCellCheckmarkImage : QMUITableViewCell 当 accessoryType 为 UITableViewCellAccessoryCheckmark 时的打钩的图片
QMUICMI.tableViewCellDetailButtonImage = nil; // TableViewCellDetailButtonImage : QMUITableViewCell 当 accessoryType 为 UITableViewCellAccessoryDetailButton 或 UITableViewCellAccessoryDetailDisclosureButton 时右边的 i 按钮图片
QMUICMI.tableViewCellSpacingBetweenDetailButtonAndDisclosureIndicator = 12; // TableViewCellSpacingBetweenDetailButtonAndDisclosureIndicator : 列表 cell 右边的 i 按钮和向右箭头之间的间距(仅当两者都使用了自定义图片并且同时显示时才生效)
QMUICMI.tableViewSectionHeaderBackgroundColor = UIColorMake(244, 244, 244); // TableViewSectionHeaderBackgroundColor : Plain 类型的 QMUITableView sectionHeader 的背景色
QMUICMI.tableViewSectionFooterBackgroundColor = UIColorMake(244, 244, 244); // TableViewSectionFooterBackgroundColor : Plain 类型的 QMUITableView sectionFooter 的背景色
QMUICMI.tableViewSectionHeaderFont = UIFontBoldMake(12); // TableViewSectionHeaderFont : Plain 类型的 QMUITableView sectionHeader 里的文字字体
QMUICMI.tableViewSectionFooterFont = UIFontBoldMake(12); // TableViewSectionFooterFont : Plain 类型的 QMUITableView sectionFooter 里的文字字体
QMUICMI.tableViewSectionHeaderTextColor = UIColorGrayDarken; // TableViewSectionHeaderTextColor : Plain 类型的 QMUITableView sectionHeader 里的文字颜色
QMUICMI.tableViewSectionFooterTextColor = UIColorGray; // TableViewSectionFooterTextColor : Plain 类型的 QMUITableView sectionFooter 里的文字颜色
QMUICMI.tableViewSectionHeaderAccessoryMargins = UIEdgeInsetsMake(0, 15, 0, 0); // TableViewSectionHeaderAccessoryMargins : Plain 类型的 QMUITableView sectionHeader accessoryView 的间距
QMUICMI.tableViewSectionFooterAccessoryMargins = UIEdgeInsetsMake(0, 15, 0, 0); // TableViewSectionFooterAccessoryMargins : Plain 类型的 QMUITableView sectionFooter accessoryView 的间距
QMUICMI.tableViewSectionHeaderContentInset = UIEdgeInsetsMake(4, 15, 4, 15); // TableViewSectionHeaderContentInset : Plain 类型的 QMUITableView sectionHeader 里的内容的 padding
QMUICMI.tableViewSectionFooterContentInset = UIEdgeInsetsMake(4, 15, 4, 15); // TableViewSectionFooterContentInset : Plain 类型的 QMUITableView sectionFooter 里的内容的 padding
#pragma mark - Grouped TableView
QMUICMI.tableViewGroupedBackgroundColor = nil; // TableViewGroupedBackgroundColor : Grouped 类型的 QMUITableView 的背景色
QMUICMI.tableViewGroupedSeparatorColor = TableViewSeparatorColor; // TableViewGroupedSeparatorColor : Grouped 类型的 QMUITableView 分隔线颜色
QMUICMI.tableViewGroupedCellTitleLabelColor = TableViewCellTitleLabelColor; // TableViewGroupedCellTitleLabelColor : Grouped 类型的 QMUITableView cell 里的标题颜色
QMUICMI.tableViewGroupedCellDetailLabelColor = TableViewCellDetailLabelColor; // TableViewGroupedCellDetailLabelColor : Grouped 类型的 QMUITableView cell 里的副标题颜色
QMUICMI.tableViewGroupedCellBackgroundColor = TableViewCellBackgroundColor; // TableViewGroupedCellBackgroundColor : Grouped 类型的 QMUITableView cell 背景色
QMUICMI.tableViewGroupedCellSelectedBackgroundColor = TableViewCellSelectedBackgroundColor; // TableViewGroupedCellSelectedBackgroundColor : Grouped 类型的 QMUITableView cell 点击时的背景色
QMUICMI.tableViewGroupedCellWarningBackgroundColor = TableViewCellWarningBackgroundColor; // tableViewGroupedCellWarningBackgroundColor : Grouped 类型的 QMUITableView cell 在提醒状态下的背景色
QMUICMI.tableViewGroupedSectionHeaderFont = UIFontMake(12); // TableViewGroupedSectionHeaderFont : Grouped 类型的 QMUITableView sectionHeader 里的文字字体
QMUICMI.tableViewGroupedSectionFooterFont = UIFontMake(12); // TableViewGroupedSectionFooterFont : Grouped 类型的 QMUITableView sectionFooter 里的文字字体
QMUICMI.tableViewGroupedSectionHeaderTextColor = UIColorGrayDarken; // TableViewGroupedSectionHeaderTextColor : Grouped 类型的 QMUITableView sectionHeader 里的文字颜色
QMUICMI.tableViewGroupedSectionFooterTextColor = UIColorGray; // TableViewGroupedSectionFooterTextColor : Grouped 类型的 QMUITableView sectionFooter 里的文字颜色
QMUICMI.tableViewGroupedSectionHeaderAccessoryMargins = UIEdgeInsetsMake(0, 15, 0, 0); // TableViewGroupedSectionHeaderAccessoryMargins : Grouped 类型的 QMUITableView sectionHeader accessoryView 的间距
QMUICMI.tableViewGroupedSectionFooterAccessoryMargins = UIEdgeInsetsMake(0, 15, 0, 0); // TableViewGroupedSectionFooterAccessoryMargins : Grouped 类型的 QMUITableView sectionFooter accessoryView 的间距
QMUICMI.tableViewGroupedSectionHeaderDefaultHeight = UITableViewAutomaticDimension; // TableViewGroupedSectionHeaderDefaultHeight : Grouped 类型的 QMUITableView sectionHeader 的默认高度(也即没使用自定义的 sectionHeaderView 时的高度),注意如果不需要间距,请用 CGFLOAT_MIN
QMUICMI.tableViewGroupedSectionFooterDefaultHeight = UITableViewAutomaticDimension; // TableViewGroupedSectionFooterDefaultHeight : Grouped 类型的 QMUITableView sectionFooter 的默认高度(也即没使用自定义的 sectionFooterView 时的高度),注意如果不需要间距,请用 CGFLOAT_MIN
QMUICMI.tableViewGroupedSectionHeaderContentInset = UIEdgeInsetsMake(16, 15, 8, 15); // TableViewGroupedSectionHeaderContentInset : Grouped 类型的 QMUITableView sectionHeader 里的内容的 padding
QMUICMI.tableViewGroupedSectionFooterContentInset = UIEdgeInsetsMake(8, 15, 2, 15); // TableViewGroupedSectionFooterContentInset : Grouped 类型的 QMUITableView sectionFooter 里的内容的 padding
#pragma mark - InsetGrouped TableView
QMUICMI.tableViewInsetGroupedCornerRadius = 10; // TableViewInsetGroupedCornerRadius : InsetGrouped 类型的 UITableView 内 cell 的圆角值
QMUICMI.tableViewInsetGroupedHorizontalInset = PreferredValueForVisualDevice(20, 15); // TableViewInsetGroupedHorizontalInset: InsetGrouped 类型的 UITableView 内的左右缩进值
QMUICMI.tableViewInsetGroupedBackgroundColor = TableViewGroupedBackgroundColor; // TableViewInsetGroupedBackgroundColor : InsetGrouped 类型的 UITableView 的背景色
QMUICMI.tableViewInsetGroupedSeparatorColor = TableViewGroupedSeparatorColor; // TableViewInsetGroupedSeparatorColor : InsetGrouped 类型的 QMUITableView 分隔线颜色
QMUICMI.tableViewInsetGroupedCellTitleLabelColor = TableViewGroupedCellTitleLabelColor; // TableViewInsetGroupedCellTitleLabelColor : InsetGrouped 类型的 QMUITableView cell 里的标题颜色
QMUICMI.tableViewInsetGroupedCellDetailLabelColor = TableViewGroupedCellDetailLabelColor; // TableViewInsetGroupedCellDetailLabelColor : InsetGrouped 类型的 QMUITableView cell 里的副标题颜色
QMUICMI.tableViewInsetGroupedCellBackgroundColor = TableViewGroupedCellBackgroundColor; // TableViewInsetGroupedCellBackgroundColor : InsetGrouped 类型的 QMUITableView cell 背景色
QMUICMI.tableViewInsetGroupedCellSelectedBackgroundColor = TableViewGroupedCellSelectedBackgroundColor; // TableViewInsetGroupedCellSelectedBackgroundColor : InsetGrouped 类型的 QMUITableView cell 点击时的背景色
QMUICMI.tableViewInsetGroupedCellWarningBackgroundColor = TableViewGroupedCellWarningBackgroundColor; // TableViewInsetGroupedCellWarningBackgroundColor : InsetGrouped 类型的 QMUITableView cell 在提醒状态下的背景色
QMUICMI.tableViewInsetGroupedSectionHeaderFont = TableViewGroupedSectionHeaderFont; // TableViewInsetGroupedSectionHeaderFont : InsetGrouped 类型的 QMUITableView sectionHeader 里的文字字体
QMUICMI.tableViewInsetGroupedSectionFooterFont = TableViewInsetGroupedSectionHeaderFont; // TableViewInsetGroupedSectionFooterFont : InsetGrouped 类型的 QMUITableView sectionFooter 里的文字字体
QMUICMI.tableViewInsetGroupedSectionHeaderTextColor = TableViewGroupedSectionHeaderTextColor; // TableViewInsetGroupedSectionHeaderTextColor : InsetGrouped 类型的 QMUITableView sectionHeader 里的文字颜色
QMUICMI.tableViewInsetGroupedSectionFooterTextColor = TableViewInsetGroupedSectionHeaderTextColor; // TableViewInsetGroupedSectionFooterTextColor : InsetGrouped 类型的 QMUITableView sectionFooter 里的文字颜色
QMUICMI.tableViewInsetGroupedSectionHeaderAccessoryMargins = TableViewGroupedSectionHeaderAccessoryMargins; // TableViewInsetGroupedSectionHeaderAccessoryMargins : InsetGrouped 类型的 QMUITableView sectionHeader accessoryView 的间距
QMUICMI.tableViewInsetGroupedSectionFooterAccessoryMargins = TableViewInsetGroupedSectionHeaderAccessoryMargins; // TableViewInsetGroupedSectionFooterAccessoryMargins : InsetGrouped 类型的 QMUITableView sectionFooter accessoryView 的间距
QMUICMI.tableViewInsetGroupedSectionHeaderDefaultHeight = TableViewGroupedSectionHeaderDefaultHeight; // TableViewInsetGroupedSectionHeaderDefaultHeight : InsetGrouped 类型的 QMUITableView sectionHeader 的默认高度(也即没使用自定义的 sectionHeaderView 时的高度),注意如果不需要间距,请用 CGFLOAT_MIN
QMUICMI.tableViewInsetGroupedSectionFooterDefaultHeight = TableViewGroupedSectionFooterDefaultHeight; // TableViewInsetGroupedSectionFooterDefaultHeight : InsetGrouped 类型的 QMUITableView sectionFooter 的默认高度(也即没使用自定义的 sectionFooterView 时的高度),注意如果不需要间距,请用 CGFLOAT_MIN
QMUICMI.tableViewInsetGroupedSectionHeaderContentInset = TableViewGroupedSectionHeaderContentInset; // TableViewInsetGroupedSectionHeaderContentInset : InsetGrouped 类型的 QMUITableView sectionHeader 里的内容的 padding
QMUICMI.tableViewInsetGroupedSectionFooterContentInset = TableViewInsetGroupedSectionHeaderContentInset; // TableViewInsetGroupedSectionFooterContentInset : InsetGrouped 类型的 QMUITableView sectionFooter 里的内容的 padding
#pragma mark - UIWindowLevel
QMUICMI.windowLevelQMUIAlertView = UIWindowLevelAlert - 4.0; // UIWindowLevelQMUIAlertView : QMUIModalPresentationViewController、QMUIPopupContainerView 里使用的 UIWindow 的 windowLevel
QMUICMI.windowLevelQMUIConsole = 1; // UIWindowLevelQMUIConsole : QMUIConsole 内部的 UIWindow 的 windowLevel
#pragma mark - QMUILog
QMUICMI.shouldPrintDefaultLog = YES; // ShouldPrintDefaultLog : 是否允许输出 QMUILogLevelDefault 级别的 log
QMUICMI.shouldPrintInfoLog = YES; // ShouldPrintInfoLog : 是否允许输出 QMUILogLevelInfo 级别的 log
QMUICMI.shouldPrintWarnLog = YES; // ShouldPrintInfoLog : 是否允许输出 QMUILogLevelWarn 级别的 log
#pragma mark - QMUIBadge
QMUICMI.badgeBackgroundColor = UIColorRed; // BadgeBackgroundColor : QMUIBadge 上的未读数的背景色
QMUICMI.badgeTextColor = UIColorWhite; // BadgeTextColor : QMUIBadge 上的未读数的文字颜色
QMUICMI.badgeFont = UIFontBoldMake(11); // BadgeFont : QMUIBadge 上的未读数的字体
QMUICMI.badgeContentEdgeInsets = UIEdgeInsetsMake(2, 4, 2, 4); // BadgeContentEdgeInsets : QMUIBadge 上的未读数与圆圈之间的 padding
QMUICMI.badgeOffset = CGPointMake(-9, 11); // BadgeOffset : QMUIBadge 上的未读数相对于目标 view 右上角的偏移
QMUICMI.badgeOffsetLandscape = CGPointMake(-9, 6); // BadgeOffsetLandscape : QMUIBadge 上的未读数在横屏下相对于目标 view 右上角的偏移
BeginIgnoreDeprecatedWarning
QMUICMI.badgeCenterOffset = CGPointMake(14, -10); // BadgeCenterOffset : QMUIBadge 未读数相对于目标 view 中心的偏移
QMUICMI.badgeCenterOffsetLandscape = CGPointMake(16, -7); // BadgeCenterOffsetLandscape : QMUIBadge 未读数在横屏下相对于目标 view 中心的偏移
EndIgnoreDeprecatedWarning
QMUICMI.updatesIndicatorColor = UIColorRed; // UpdatesIndicatorColor : QMUIBadge 上的未读红点的颜色
QMUICMI.updatesIndicatorSize = CGSizeMake(7, 7); // UpdatesIndicatorSize : QMUIBadge 上的未读红点的大小
QMUICMI.updatesIndicatorOffset = CGPointMake(4, UpdatesIndicatorSize.height);// UpdatesIndicatorOffset : QMUIBadge 未读红点相对于目标 view 右上角的偏移
QMUICMI.updatesIndicatorOffsetLandscape = UpdatesIndicatorOffset; // UpdatesIndicatorOffsetLandscape : QMUIBadge 未读红点在横屏下相对于目标 view 右上角的偏移
BeginIgnoreDeprecatedWarning
QMUICMI.updatesIndicatorCenterOffset = CGPointMake(14, -10); // UpdatesIndicatorCenterOffset : QMUIBadge 未读红点相对于目标 view 中心的偏移
QMUICMI.updatesIndicatorCenterOffsetLandscape = CGPointMake(14, -10); // UpdatesIndicatorCenterOffsetLandscape : QMUIBadge 未读红点在横屏下相对于目标 view 中心点的偏移
EndIgnoreDeprecatedWarning
#pragma mark - Others
QMUICMI.automaticCustomNavigationBarTransitionStyle = NO; // AutomaticCustomNavigationBarTransitionStyle : 界面 push/pop 时是否要自动根据两个界面的 barTintColor/backgroundImage/shadowImage 的样式差异来决定是否使用自定义的导航栏效果
QMUICMI.supportedOrientationMask = UIInterfaceOrientationMaskAll; // SupportedOrientationMask : 默认支持的横竖屏方向
QMUICMI.automaticallyRotateDeviceOrientation = NO; // AutomaticallyRotateDeviceOrientation : 是否在界面切换或 viewController.supportedOrientationMask 发生变化时自动旋转屏幕
QMUICMI.statusbarStyleLightInitially = NO; // StatusbarStyleLightInitially : 默认的状态栏内容是否使用白色,默认为 NO,在 iOS 13 下会自动根据是否 Dark Mode 而切换样式,iOS 12 及以前则为黑色
QMUICMI.needsBackBarButtonItemTitle = YES; // NeedsBackBarButtonItemTitle : 全局是否需要返回按钮的 title,不需要则只显示一个返回image
QMUICMI.hidesBottomBarWhenPushedInitially = NO; // HidesBottomBarWhenPushedInitially : QMUICommonViewController.hidesBottomBarWhenPushed 的初始值,默认为 NO,以保持与系统默认值一致,但通常建议改为 YES,因为一般只有 tabBar 首页那几个界面要求为 NO
QMUICMI.preventConcurrentNavigationControllerTransitions = YES; // PreventConcurrentNavigationControllerTransitions : 自动保护 QMUINavigationController 在上一次 push/pop 尚未结束的时候就进行下一次 push/pop 的行为,避免产生 crash
QMUICMI.navigationBarHiddenInitially = NO; // NavigationBarHiddenInitially : QMUINavigationControllerDelegate preferredNavigationBarHidden 的初始值,默认为NO
QMUICMI.shouldFixTabBarTransitionBugInIPhoneX = NO; // ShouldFixTabBarTransitionBugInIPhoneX : 是否需要自动修复 iOS 11 下,iPhone X 的设备在 push 界面时,tabBar 会瞬间往上跳的 bug
QMUICMI.shouldFixTabBarButtonBugForAll = NO; // ShouldFixTabBarButtonBugForAll : 是否要对 iOS 12.1.1 及以后的版本也修复手势返回时 tabBarButton 布局错误的 bug(issue #410),默认为 NO
QMUICMI.shouldFixTabBarSafeAreaInsetsBug = NO; // ShouldFixTabBarSafeAreaInsetsBug : 是否要对 iOS 11 及以后的版本修复当存在 UITabBar 时,UIScrollView 的 inset.bottom 可能错误的 bug(issue #218 #934),默认为 YES
QMUICMI.shouldFixSearchBarMaskViewLayoutBug = NO; // ShouldFixSearchBarMaskViewLayoutBug : 是否自动修复 UISearchController.searchBar 被当作 tableHeaderView 使用时可能出现的布局 bug(issue #950)
QMUICMI.shouldPrintQMUIWarnLogToConsole = IS_DEBUG; // ShouldPrintQMUIWarnLogToConsole : 是否在出现 QMUILogWarn 时自动把这些 log 以 QMUIConsole 的方式显示到设备屏幕上
QMUICMI.sendAnalyticsToQMUITeam = YES; // SendAnalyticsToQMUITeam : 是否允许在 DEBUG 模式下上报 Bundle Identifier 和 Display Name 给 QMUI 统计用
QMUICMI.dynamicPreferredValueForIPad = NO; // DynamicPreferredValueForIPad : 当 iPad 处于 Slide Over 或 Split View 分屏模式下,宏 `PreferredValueForXXX` 是否把 iPad 视为某种屏幕宽度近似的 iPhone 来取值。
if (@available(iOS 13.0, *)) {
QMUICMI.ignoreKVCAccessProhibited = NO; // IgnoreKVCAccessProhibited : 是否全局忽略 iOS 13 对 KVC 访问 UIKit 私有属性的限制
QMUICMI.adjustScrollIndicatorInsetsByContentInsetAdjustment = NO; // AdjustScrollIndicatorInsetsByContentInsetAdjustment : 当将 UIScrollView.contentInsetAdjustmentBehavior 设为 UIScrollViewContentInsetAdjustmentNever 时,是否自动将 UIScrollView.automaticallyAdjustsScrollIndicatorInsets 设为 NO,以保证原本在 iOS 12 下的代码不用修改就能在 iOS 13 下正常控制滚动条的位置。
}
}
// QMUI 2.3.0 版本里,配置表新增这个方法,返回 YES 表示在 App 启动时要自动应用这份配置表。仅当你的 App 里存在多份配置表时,才需要把除默认配置表之外的其他配置表的返回值改为 NO。
- (BOOL)shouldApplyTemplateAutomatically {
return YES;
}
@end
//
// NSMutableArray+Safe.m
// method swizzling
//
// Created by bgcr on 2018/3/14.
// Copyright © 2018年 bgcr. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@implementation NSMutableArray (Safe)
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
id obj = [[self alloc] init];
[obj swizzleMethod:@selector(addObject:) withMethod:@selector(safeAddObject:)];
[obj swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(safeObjectAtIndex:)];
[obj swizzleMethod:@selector(objectAtIndexedSubscript:) withMethod:@selector(safeobjectAtIndexedSubscript:)];
[obj swizzleMethod:@selector(insertObject:atIndex:) withMethod:@selector(safeInsertObject:atIndex:)];
[obj swizzleMethod:@selector(removeObjectAtIndex:) withMethod:@selector(safeRemoveObjectAtIndex:)];
[obj swizzleMethod:@selector(replaceObjectAtIndex:withObject:) withMethod:@selector(safeReplaceObjectAtIndex:withObject:)];
[obj swizzleMethod:@selector(setObject:atIndexedSubscript:) withMethod:@selector(safesetObject:atIndexedSubscript:)];
});
}
- (id)safeobjectAtIndexedSubscript:(NSUInteger)idx{
if(idx<[self count]){
return [self safeobjectAtIndexedSubscript:idx];
}else{
NSLog(@"index is beyond bounds ");
}
return nil;
}
- (void)safeAddObject:(id)anObject
{
if (anObject) {
[self safeAddObject:anObject];
}else{
NSLog(@"obj is nil");
}
}
- (id)safeObjectAtIndex:(NSInteger)index
{
if(index<[self count]){
return [self safeObjectAtIndex:index];
}else{
NSLog(@"index is beyond bounds ");
}
return nil;
}
- (void)safeInsertObject:(id)anObject atIndex:(NSUInteger)index{
if (index > [self count]) {
NSLog(@"index is beyond bounds ");
}else if (anObject){
[self safeInsertObject:anObject atIndex:index];
}else{
NSLog(@"obj is nil");
}
}
- (void)safeRemoveObjectAtIndex:(NSUInteger)index{
if (index < [self count]) {
[self safeRemoveObjectAtIndex:index];
}else{
NSLog(@"index is beyond bounds ");
}
}
- (void)safesetObject:(id)obj atIndexedSubscript:(NSUInteger)idx{
if (idx < [self count]) {
if (obj) {
[self safesetObject:obj atIndexedSubscript:idx];
}else{
NSLog(@"obj is nil");
}
}else{
NSLog(@"index is beyond bounds ");
}
}
- (void)safeReplaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject{
if (index < [self count]) {
if (anObject) {
[self safeReplaceObjectAtIndex:index withObject:anObject];
}else{
NSLog(@"obj is nil");
}
}else{
NSLog(@"index is beyond bounds ");
}
}
- (void)swizzleMethod:(SEL)origSelector withMethod:(SEL)newSelector
{
Class class = [self class];
Method originalMethod = class_getInstanceMethod(class, origSelector);
Method swizzledMethod = class_getInstanceMethod(class, newSelector);
BOOL didAddMethod = class_addMethod(class,
origSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
newSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
@end
@implementation NSArray (Safe)
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
id obj = [[self alloc] init];
//__NSArrayI(多项) __NSArray0(0项) __NSSingleObjectArrayI(一项) 目前就这三个类 有新的再加
[obj swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(swizzleObjectAtIndexNSArrayI:) withClass:objc_getClass("__NSArrayI")];
[obj swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(swizzleObjectAtIndexNSArray0:) withClass:objc_getClass("__NSArray0")];
[obj swizzleMethod:@selector(objectAtIndex:) withMethod:@selector(swizzleObjectAtIndexNSSingleObjectArrayI:) withClass:objc_getClass("__NSSingleObjectArrayI")];
[obj swizzleMethod:@selector(objectAtIndexedSubscript:) withMethod:@selector(safeobjectAtIndexedSubscript:) withClass:objc_getClass("__NSArrayI")];
});
}
- (id)swizzleObjectAtIndexNSArrayI:(NSInteger)index{
if(index<[self count]){
return [self swizzleObjectAtIndexNSArrayI:index];
}else{
NSLog(@"index is beyond bounds ");
}
return nil;
}
- (id)swizzleObjectAtIndexNSArray0:(NSInteger)index{
if(index<[self count]){
return [self swizzleObjectAtIndexNSArray0:index];
}else{
NSLog(@"index is beyond bounds ");
}
return nil;
}
- (id)swizzleObjectAtIndexNSSingleObjectArrayI:(NSInteger)index{
if(index<[self count]){
return [self swizzleObjectAtIndexNSSingleObjectArrayI:index];
}else{
NSLog(@"index is beyond bounds ");
}
return nil;
}
- (id)safeobjectAtIndexedSubscript:(NSUInteger)idx{
if(idx<[self count]){
return [self safeobjectAtIndexedSubscript:idx];
}else{
NSLog(@"index is beyond bounds ");
}
return nil;
}
- (void)swizzleMethod:(SEL)origSelector withMethod:(SEL)newSelector withClass:(Class)class
{
Method originalMethod = class_getInstanceMethod(class, origSelector);
Method swizzledMethod = class_getInstanceMethod(class, newSelector);
BOOL didAddMethod = class_addMethod(class,
origSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
newSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
@end
......@@ -11,6 +11,7 @@ pod 'SVProgressHUD','2.2.5'
pod 'MJRefresh','3.4.3'
pod 'YTKNetwork','3.0.2'
pod 'QMUIKit','4.2.0'
pod "CTMediator",'44'
end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment