├── WKCrashManagerDemo ├── WKCrashManagerDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── wangkun.xcuserdatad │ │ │ ├── IDEFindNavigatorScopes.plist │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── wangkun.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── WKCrashManagerDemo │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── WKCrashManagerDemoTests │ ├── Info.plist │ └── WKCrashManagerDemoTests.m ├── WKCrashManagerDemoUITests │ ├── Info.plist │ └── WKCrashManagerDemoUITests.m └── WKCrashSDK │ ├── Container │ ├── NSArray+Safe.h │ ├── NSArray+Safe.m │ ├── NSDictionary+Safe.h │ ├── NSDictionary+Safe.m │ ├── NSMutableArray+Safe.h │ ├── NSMutableArray+Safe.m │ ├── NSMutableArray+SafeObjectAtIndex.h │ ├── NSMutableArray+SafeObjectAtIndex.m │ ├── NSMutableDictionary+Safe.h │ ├── NSMutableDictionary+Safe.m │ ├── NSMutableSet+Safe.h │ ├── NSMutableSet+Safe.m │ ├── NSSet+Safe.h │ └── NSSet+Safe.m │ ├── KVO │ ├── NSObject+SafeKVO.h │ └── NSObject+SafeKVO.m │ ├── MsgReceiver │ ├── NSObject+MsgReceiver.h │ ├── NSObject+MsgReceiver.m │ ├── WKMsgReceiver.h │ └── WKMsgReceiver.m │ ├── Notification │ ├── NSNotificationCenter+Safe.h │ └── NSNotificationCenter+Safe.m │ ├── Null │ ├── NSNull+Safe.h │ └── NSNull+Safe.m │ ├── Report │ ├── Tools │ │ ├── AppDelegate+visableVC.h │ │ ├── AppDelegate+visableVC.m │ │ ├── DeviceList.plist │ │ ├── DeviceUtil.h │ │ ├── DeviceUtil.m │ │ ├── UIViewExt.h │ │ ├── UIViewExt.m │ │ ├── WKBaseVC.h │ │ ├── WKBaseVC.m │ │ ├── WKNavView.h │ │ └── WKNavView.m │ ├── UI │ │ ├── WKCrashClassCell.h │ │ ├── WKCrashClassCell.m │ │ ├── WKCrashClassListVC.h │ │ ├── WKCrashClassListVC.m │ │ ├── WKCrashListCell.h │ │ ├── WKCrashListCell.m │ │ ├── WKCrashListVC.h │ │ ├── WKCrashListVC.m │ │ ├── WKCrashTypeListVC.h │ │ ├── WKCrashTypeListVC.m │ │ └── WKHeader.h │ ├── WKCrashReport.h │ └── WKCrashReport.m │ ├── String │ ├── NSMutableString+Safe.h │ ├── NSMutableString+Safe.m │ ├── NSString+Safe.h │ └── NSString+Safe.m │ ├── Timer │ ├── NSTimer+Safe.h │ └── NSTimer+Safe.m │ ├── WKCrashManager.h │ ├── WKCrashManager.m │ ├── WKHeader.h │ ├── WKSwizzle.h │ └── Zombie │ ├── NSObject+WKZombie.h │ ├── NSObject+WKZombie.mm │ ├── WKZombieManager.h │ └── WKZombieManager.m ├── WKRestoreSceneDemo ├── README.MD ├── WKRestoreSceneDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── wangkun.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── wangkun.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── WKRestoreSceneDemo │ ├── AppDelegate+visableVC.h │ ├── AppDelegate+visableVC.m │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── UIViewController+RestoreScene.h │ ├── UIViewController+RestoreScene.m │ ├── ViewController.h │ ├── ViewController.m │ ├── WKClassManager.h │ ├── WKClassManager.m │ ├── WKClassMethodModel.h │ ├── WKClassMethodModel.m │ ├── WKClassPropertyModel.h │ ├── WKClassPropertyModel.m │ ├── WKRestoreSceneManager.h │ ├── WKRestoreSceneManager.m │ └── main.m ├── WKRestoreSceneDemoTests │ ├── Info.plist │ └── WKRestoreSceneDemoTests.m └── WKRestoreSceneDemoUITests │ ├── Info.plist │ └── WKRestoreSceneDemoUITests.m ├── WKStepMaskViewDemo ├── GuideView │ ├── WKBaseView.h │ ├── WKBaseView.m │ ├── WKKMBaseGuideView.h │ ├── WKKMBaseGuideView.m │ ├── WKStepMaskGuideView.h │ └── WKStepMaskGuideView.m ├── README.MD ├── WKStepMaskViewDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── wangkun.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── wangkun.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── WKStepMaskViewDemo │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── StepMaskGuideView.h │ ├── StepMaskGuideView.m │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── WKStepMaskViewDemoTests │ ├── Info.plist │ └── WKStepMaskViewDemoTests.m └── WKStepMaskViewDemoUITests │ ├── Info.plist │ └── WKStepMaskViewDemoUITests.m ├── WKViewManager.podspec ├── WKViewManagerDemo ├── Podfile ├── Podfile.lock ├── Pods │ ├── Headers │ │ ├── Private │ │ │ └── Masonry │ │ │ │ ├── MASCompositeConstraint.h │ │ │ │ ├── MASConstraint+Private.h │ │ │ │ ├── MASConstraint.h │ │ │ │ ├── MASConstraintMaker.h │ │ │ │ ├── MASLayoutConstraint.h │ │ │ │ ├── MASUtilities.h │ │ │ │ ├── MASViewAttribute.h │ │ │ │ ├── MASViewConstraint.h │ │ │ │ ├── Masonry.h │ │ │ │ ├── NSArray+MASAdditions.h │ │ │ │ ├── NSArray+MASShorthandAdditions.h │ │ │ │ ├── NSLayoutConstraint+MASDebugAdditions.h │ │ │ │ ├── View+MASAdditions.h │ │ │ │ ├── View+MASShorthandAdditions.h │ │ │ │ └── ViewController+MASAdditions.h │ │ └── Public │ │ │ └── Masonry │ │ │ ├── MASCompositeConstraint.h │ │ │ ├── MASConstraint+Private.h │ │ │ ├── MASConstraint.h │ │ │ ├── MASConstraintMaker.h │ │ │ ├── MASLayoutConstraint.h │ │ │ ├── MASUtilities.h │ │ │ ├── MASViewAttribute.h │ │ │ ├── MASViewConstraint.h │ │ │ ├── Masonry.h │ │ │ ├── NSArray+MASAdditions.h │ │ │ ├── NSArray+MASShorthandAdditions.h │ │ │ ├── NSLayoutConstraint+MASDebugAdditions.h │ │ │ ├── View+MASAdditions.h │ │ │ ├── View+MASShorthandAdditions.h │ │ │ └── ViewController+MASAdditions.h │ ├── Manifest.lock │ ├── Masonry │ │ ├── LICENSE │ │ ├── Masonry │ │ │ ├── MASCompositeConstraint.h │ │ │ ├── MASCompositeConstraint.m │ │ │ ├── MASConstraint+Private.h │ │ │ ├── MASConstraint.h │ │ │ ├── MASConstraint.m │ │ │ ├── MASConstraintMaker.h │ │ │ ├── MASConstraintMaker.m │ │ │ ├── MASLayoutConstraint.h │ │ │ ├── MASLayoutConstraint.m │ │ │ ├── MASUtilities.h │ │ │ ├── MASViewAttribute.h │ │ │ ├── MASViewAttribute.m │ │ │ ├── MASViewConstraint.h │ │ │ ├── MASViewConstraint.m │ │ │ ├── Masonry.h │ │ │ ├── NSArray+MASAdditions.h │ │ │ ├── NSArray+MASAdditions.m │ │ │ ├── NSArray+MASShorthandAdditions.h │ │ │ ├── NSLayoutConstraint+MASDebugAdditions.h │ │ │ ├── NSLayoutConstraint+MASDebugAdditions.m │ │ │ ├── View+MASAdditions.h │ │ │ ├── View+MASAdditions.m │ │ │ ├── View+MASShorthandAdditions.h │ │ │ ├── ViewController+MASAdditions.h │ │ │ └── ViewController+MASAdditions.m │ │ └── README.md │ ├── Pods.xcodeproj │ │ ├── project.pbxproj │ │ └── xcuserdata │ │ │ └── wangkun.xcuserdatad │ │ │ └── xcschemes │ │ │ ├── Masonry.xcscheme │ │ │ ├── Pods-WKViewManagerDemo.xcscheme │ │ │ ├── Pods-WKViewManagerDemoTests.xcscheme │ │ │ ├── Pods-WKViewManagerDemoUITests.xcscheme │ │ │ └── xcschememanagement.plist │ └── Target Support Files │ │ ├── Masonry │ │ ├── Masonry-dummy.m │ │ ├── Masonry-prefix.pch │ │ └── Masonry.xcconfig │ │ ├── Pods-WKViewManagerDemo │ │ ├── Pods-WKViewManagerDemo-acknowledgements.markdown │ │ ├── Pods-WKViewManagerDemo-acknowledgements.plist │ │ ├── Pods-WKViewManagerDemo-dummy.m │ │ ├── Pods-WKViewManagerDemo-frameworks.sh │ │ ├── Pods-WKViewManagerDemo-resources.sh │ │ ├── Pods-WKViewManagerDemo.debug.xcconfig │ │ └── Pods-WKViewManagerDemo.release.xcconfig │ │ ├── Pods-WKViewManagerDemoTests │ │ ├── Pods-WKViewManagerDemoTests-acknowledgements.markdown │ │ ├── Pods-WKViewManagerDemoTests-acknowledgements.plist │ │ ├── Pods-WKViewManagerDemoTests-dummy.m │ │ ├── Pods-WKViewManagerDemoTests-frameworks.sh │ │ ├── Pods-WKViewManagerDemoTests-resources.sh │ │ ├── Pods-WKViewManagerDemoTests.debug.xcconfig │ │ └── Pods-WKViewManagerDemoTests.release.xcconfig │ │ └── Pods-WKViewManagerDemoUITests │ │ ├── Pods-WKViewManagerDemoUITests-acknowledgements.markdown │ │ ├── Pods-WKViewManagerDemoUITests-acknowledgements.plist │ │ ├── Pods-WKViewManagerDemoUITests-dummy.m │ │ ├── Pods-WKViewManagerDemoUITests-frameworks.sh │ │ ├── Pods-WKViewManagerDemoUITests-resources.sh │ │ ├── Pods-WKViewManagerDemoUITests.debug.xcconfig │ │ └── Pods-WKViewManagerDemoUITests.release.xcconfig ├── WKViewManagerDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── wangkun.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── wangkun.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── WKViewManagerDemo.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── wangkun.xcuserdatad │ │ └── UserInterfaceState.xcuserstate ├── WKViewManagerDemo │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── BaseView │ │ ├── KMDeallocBlockExecutor.h │ │ ├── KMDeallocBlockExecutor.m │ │ ├── NSObject+DealBlock.h │ │ ├── NSObject+DealBlock.m │ │ ├── UIViewController+ViewManager.h │ │ ├── UIViewController+ViewManager.m │ │ ├── WKBaseView.h │ │ ├── WKBaseView.m │ │ ├── WKPopBaseView.h │ │ ├── WKPopBaseView.m │ │ ├── WKViewManager.h │ │ └── WKViewManager.m │ ├── DetailPageVC.h │ ├── DetailPageVC.m │ ├── HomePageVC.h │ ├── HomePageVC.m │ ├── Info.plist │ ├── WKHeader.h │ ├── WKOtherView.h │ ├── WKOtherView.m │ ├── WKTestView.h │ ├── WKTestView.m │ ├── WKViewManagerHeader.h │ └── main.m ├── WKViewManagerDemoTests │ ├── Info.plist │ └── WKViewManagerDemoTests.m └── WKViewManagerDemoUITests │ ├── Info.plist │ └── WKViewManagerDemoUITests.m ├── exchangeSetter ├── exchangeSetter.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── wangkun.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── wangkun.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── exchangeSetter.xcscheme │ │ └── xcschememanagement.plist ├── exchangeSetter │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── KMDeallocBlockExecutor.h │ ├── KMDeallocBlockExecutor.m │ ├── NSObject+DataBase.h │ ├── NSObject+DataBase.m │ ├── NSObject+DealBlock.h │ ├── NSObject+DealBlock.m │ ├── UserModel.h │ ├── UserModel.m │ ├── ViewController.h │ ├── ViewController.m │ ├── WKClassManager.h │ ├── WKClassManager.m │ ├── WKClassMethodModel.h │ ├── WKClassMethodModel.m │ ├── WKClassPropertyModel.h │ ├── WKClassPropertyModel.m │ └── main.m ├── exchangeSetterTests │ ├── Info.plist │ └── exchangeSetterTests.m └── exchangeSetterUITests │ ├── Info.plist │ └── exchangeSetterUITests.m └── searchKeyChangeColor ├── README.MD ├── searchKeyChangeColor.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── wangkun.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── wangkun.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── searchKeyChangeColor ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── NSString+WKExtend.h ├── NSString+WKExtend.m ├── ViewController.h ├── ViewController.m ├── WKSearchStringManager.h ├── WKSearchStringManager.m └── main.m ├── searchKeyChangeColorTests ├── Info.plist └── searchKeyChangeColorTests.m └── searchKeyChangeColorUITests ├── Info.plist └── searchKeyChangeColorUITests.m /WKCrashManagerDemo/WKCrashManagerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemo.xcodeproj/project.xcworkspace/xcuserdata/wangkun.xcuserdatad/IDEFindNavigatorScopes.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemo.xcodeproj/project.xcworkspace/xcuserdata/wangkun.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WangKunKun/WKDemo/9915691c5fc1ff44b494fb7f91002252c5b6b714/WKCrashManagerDemo/WKCrashManagerDemo.xcodeproj/project.xcworkspace/xcuserdata/wangkun.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemo.xcodeproj/xcuserdata/wangkun.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemo.xcodeproj/xcuserdata/wangkun.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WKCrashManagerDemo.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WKCrashManagerDemo 4 | // 5 | // Created by wangkun on 2018/12/10. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // WKCrashManagerDemo 4 | // 5 | // Created by wangkun on 2018/12/10. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // WKCrashManagerDemo 4 | // 5 | // Created by wangkun on 2018/12/10. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // WKCrashManagerDemo 4 | // 5 | // Created by wangkun on 2018/12/10. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | self.title = @"主页"; 20 | // Do any additional setup after loading the view, typically from a nib. 21 | } 22 | - (IBAction)methodNotFountClick:(id)sender { 23 | 24 | UIView * v = self; 25 | UIView * new = [UIView new]; 26 | [v addSubview:new]; 27 | } 28 | 29 | - (IBAction)arrarAddNilClick:(id)sender { 30 | NSMutableArray * arr = [NSMutableArray array]; 31 | id a = nil; 32 | [arr addObject:a]; 33 | } 34 | 35 | - (IBAction)strAppendNilClick:(id)sender { 36 | NSMutableString * str = [NSMutableString string]; 37 | NSString * s = nil; 38 | [str appendString:s]; 39 | } 40 | 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WKCrashManagerDemo 4 | // 5 | // Created by wangkun on 2018/12/10. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemoTests/WKCrashManagerDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKCrashManagerDemoTests.m 3 | // WKCrashManagerDemoTests 4 | // 5 | // Created by wangkun on 2018/12/10. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WKCrashManagerDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation WKCrashManagerDemoTests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | } 20 | 21 | - (void)tearDown { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | - (void)testExample { 26 | // This is an example of a functional test case. 27 | // Use XCTAssert and related functions to verify your tests produce the correct results. 28 | } 29 | 30 | - (void)testPerformanceExample { 31 | // This is an example of a performance test case. 32 | [self measureBlock:^{ 33 | // Put the code you want to measure the time of here. 34 | }]; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashManagerDemoUITests/WKCrashManagerDemoUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKCrashManagerDemoUITests.m 3 | // WKCrashManagerDemoUITests 4 | // 5 | // Created by wangkun on 2018/12/10. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WKCrashManagerDemoUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation WKCrashManagerDemoUITests 16 | 17 | - (void)setUp { 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | 20 | // In UI tests it is usually best to stop immediately when a failure occurs. 21 | self.continueAfterFailure = NO; 22 | 23 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 24 | [[[XCUIApplication alloc] init] launch]; 25 | 26 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 27 | } 28 | 29 | - (void)tearDown { 30 | // Put teardown code here. This method is called after the invocation of each test method in the class. 31 | } 32 | 33 | - (void)testExample { 34 | // Use recording to get started writing UI tests. 35 | // Use XCTAssert and related functions to verify your tests produce the correct results. 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Container/NSArray+Safe.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Safe.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/5. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSArray (Safe) 12 | 13 | + (void)registerArrayCrash; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Container/NSDictionary+Safe.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+Safe.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/5. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDictionary (Safe) 12 | 13 | + (void)registerDictonaryCrash; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Container/NSDictionary+Safe.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+Safe.m 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/5. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "NSDictionary+Safe.h" 10 | #import "WKSwizzle.h" 11 | #import "NSObject+MsgReceiver.h" 12 | #import "WKCrashManager.h" 13 | @implementation NSDictionary (Safe) 14 | 15 | + (void)registerDictonaryCrash 16 | { 17 | swizzling_exchangeMethod(NSClassFromString(@"__NSPlaceholderDictionary"), @selector(initWithObjects:forKeys:count:), @selector(wksafe_initWithObjects:forKeys:count:)); 18 | } 19 | 20 | - (instancetype)wksafe_initWithObjects:(id _Nonnull const [])objects forKeys:(id _Nonnull const [])keys count:(NSUInteger)cnt 21 | { 22 | NSUInteger index = 0; 23 | id _Nonnull __unsafe_unretained newObjects[cnt]; 24 | id _Nonnull __unsafe_unretained newkeys[cnt]; 25 | for (int i = 0; i < cnt; i++) { 26 | id tmpItem = objects[i]; 27 | id tmpKey = keys[i]; 28 | if (tmpItem == nil || tmpKey == nil) { 29 | [self sendCrashInfoWithMsg:[NSString stringWithUTF8String:__func__] type:(WKCrashType_Container)]; 30 | continue; 31 | } 32 | newObjects[index] = objects[i]; 33 | newkeys[index] = keys[i]; 34 | index++; 35 | } 36 | 37 | return [self wksafe_initWithObjects:newObjects forKeys:newkeys count:index]; 38 | } 39 | 40 | 41 | @end 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Container/NSMutableArray+Safe.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableArray+Safe.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/5. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSMutableArray (Safe) 12 | 13 | + (void)registerMutableArrayCrash; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Container/NSMutableArray+SafeObjectAtIndex.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableArray+SafeObjectAtIndex.h 3 | // MKWeekly 4 | // 5 | // Created by wangkun on 2018/7/28. 6 | // Copyright © 2018年 zymk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSMutableArray (SafeObjectAtIndex) 12 | 13 | + (void)registerMutableArrayObjectAtIndex; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Container/NSMutableArray+SafeObjectAtIndex.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableArray+SafeObjectAtIndex.m 3 | // MKWeekly 4 | // 5 | // Created by wangkun on 2018/7/28. 6 | // Copyright © 2018年 zymk. All rights reserved. 7 | // 8 | 9 | #import "NSMutableArray+SafeObjectAtIndex.h" 10 | #import "WKSwizzle.h" 11 | #import "WKCrashManager.h" 12 | #import "NSObject+MsgReceiver.h" 13 | 14 | @implementation NSMutableArray (SafeObjectAtIndex) 15 | 16 | + (void)registerMutableArrayObjectAtIndex 17 | { 18 | swizzling_exchangeMethod(NSClassFromString(@"__NSArrayM"), @selector(objectAtIndex:), @selector(arrayM_objectAtIndex:)); 19 | 20 | } 21 | 22 | - (id)arrayM_objectAtIndex:(NSUInteger)index{ 23 | //思考会不会有内存泄漏 mrc 下 24 | @autoreleasepool { 25 | if(index < self.count){ 26 | return [self arrayM_objectAtIndex:index]; 27 | } 28 | [self sendCrashInfoWithMsg:[NSString stringWithUTF8String:__func__] type:(WKCrashType_Container)]; 29 | return nil; 30 | } 31 | } 32 | 33 | 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Container/NSMutableDictionary+Safe.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableDictionary+Safe.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/6. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSMutableDictionary (Safe) 12 | 13 | + (void)registerMutableDictionaryCrash; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Container/NSMutableDictionary+Safe.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableDictionary+Safe.m 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/6. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "NSMutableDictionary+Safe.h" 10 | #import "WKSwizzle.h" 11 | #import "NSObject+MsgReceiver.h" 12 | #import "WKCrashManager.h" 13 | @implementation NSMutableDictionary (Safe) 14 | 15 | + (void)registerMutableDictionaryCrash 16 | { 17 | 18 | swizzling_exchangeMethod(NSClassFromString(@"__NSDictionaryM"), @selector(setObject:forKey:), @selector(wksafe_setObject:forKey:)); 19 | swizzling_exchangeMethod(NSClassFromString(@"__NSDictionaryM"), @selector(setObject:forKeyedSubscript:), @selector(wksafe_setObject:forKeyedSubscript:)); 20 | swizzling_exchangeMethod(NSClassFromString(@"__NSDictionaryM"), @selector(removeObjectForKey:), @selector(wksafe_removeObjectForKey:)); 21 | 22 | } 23 | 24 | - (void)wksafe_setObject:(id)anObject forKey:(id)aKey 25 | { 26 | if (aKey && anObject) { 27 | [self wksafe_setObject:anObject forKey:aKey]; 28 | return; 29 | } 30 | // [self sendCrashInfoWithMsg:[NSString stringWithUTF8String:__func__] type:(WKCrashType_Container)]; 31 | 32 | } 33 | 34 | - (void)wksafe_setObject:(id)obj forKeyedSubscript:(id)key 35 | { 36 | if (key && obj) { 37 | [self wksafe_setObject:obj forKeyedSubscript:key]; 38 | return; 39 | } 40 | // [self sendCrashInfoWithMsg:[NSString stringWithUTF8String:__func__] type:(WKCrashType_Container)]; 41 | } 42 | 43 | - (void)wksafe_removeObjectForKey:(id)aKey 44 | { 45 | if (aKey) { 46 | [self wksafe_removeObjectForKey:aKey]; 47 | return; 48 | } 49 | [self sendCrashInfoWithMsg:[NSString stringWithUTF8String:__func__] type:(WKCrashType_Container)]; 50 | } 51 | 52 | @end 53 | 54 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Container/NSMutableSet+Safe.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableSet+Safe.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/6. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSMutableSet (Safe) 12 | + (void)registerMutableSetCrash; 13 | @end 14 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Container/NSMutableSet+Safe.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableSet+Safe.m 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/6. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "NSMutableSet+Safe.h" 10 | #import "WKSwizzle.h" 11 | #import "NSObject+MsgReceiver.h" 12 | #import "WKCrashManager.h" 13 | @implementation NSMutableSet (Safe) 14 | 15 | + (void)registerMutableSetCrash 16 | { 17 | swizzling_exchangeMethod(NSClassFromString(@"__NSSetM"), @selector(addObject:), @selector(wksafe_addObject:)); 18 | swizzling_exchangeMethod(NSClassFromString(@"__NSSetM"), @selector(removeObject:), @selector(wksafe_removeObject:)); 19 | } 20 | 21 | - (void)wksafe_removeObject:(id)object 22 | { 23 | if (object) { 24 | [self wksafe_removeObject:object]; 25 | } 26 | else 27 | { 28 | [self sendCrashInfoWithMsg:[NSString stringWithUTF8String:__func__] type:(WKCrashType_Container)]; 29 | } 30 | } 31 | -(void)wksafe_addObject:(id)object 32 | { 33 | if (object) { 34 | [self wksafe_addObject:object]; 35 | } 36 | else 37 | { 38 | [self sendCrashInfoWithMsg:[NSString stringWithUTF8String:__func__] type:(WKCrashType_Container)]; 39 | } 40 | } 41 | 42 | 43 | @end 44 | 45 | 46 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Container/NSSet+Safe.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSSet+Safe.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/6. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSSet (Safe) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Container/NSSet+Safe.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSSet+Safe.m 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/6. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "NSSet+Safe.h" 10 | 11 | @implementation NSSet (Safe) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/KVO/NSObject+SafeKVO.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+SafeKVO.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/7. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (SafeKVO) 12 | + (void)registerKVOCrash; 13 | @end 14 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/MsgReceiver/NSObject+MsgReceiver.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+MsgReceiver.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/4. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WKCrashReport.h" 11 | 12 | @interface NSObject (MsgReceiver) 13 | 14 | - (void)sendCrashInfoWithMsg:(NSString *)msg type:(WKCrashType)type; 15 | + (void)registerUnrecognizedSelectorCrash; 16 | @end 17 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/MsgReceiver/WKMsgReceiver.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKMsgReceiver.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/4. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WKMsgReceiver : NSObject 12 | 13 | + (instancetype)sharedMsgReceiver; 14 | - (BOOL)addFunc:(SEL)sel; 15 | + (BOOL)addClassFunc:(SEL)sel; 16 | @end 17 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/MsgReceiver/WKMsgReceiver.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKMsgReceiver.m 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/4. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "WKMsgReceiver.h" 10 | #import 11 | 12 | 13 | int commonFunc(id target, SEL cmd, ...) { 14 | return 0; 15 | } 16 | 17 | static BOOL __addMethod(Class clazz, SEL sel) { 18 | NSString *selName = NSStringFromSelector(sel); 19 | 20 | NSMutableString *tmpString = [[NSMutableString alloc] initWithFormat:@"%@", selName]; 21 | 22 | //有多少个冒号 就证明有多少个入参 23 | int count = (int)[tmpString replaceOccurrencesOfString:@":" 24 | withString:@"_" 25 | options:NSCaseInsensitiveSearch 26 | range:NSMakeRange(0, selName.length)]; 27 | //因为后续的参数 未使用,所以不在意对面参数 传入的是什么 返回值改为int 以及 参数改为id 28 | NSMutableString *val = [[NSMutableString alloc] initWithString:@"i@:"]; 29 | for (int i = 0; i < count; i++) { 30 | [val appendString:@"@"]; 31 | } 32 | const char *funcTypeEncoding = [val UTF8String]; 33 | return class_addMethod(clazz, sel, (IMP)commonFunc, funcTypeEncoding); 34 | } 35 | 36 | @implementation WKMsgReceiver 37 | 38 | + (instancetype)sharedMsgReceiver 39 | { 40 | static WKMsgReceiver * msgR = nil; 41 | static dispatch_once_t onceToken; 42 | dispatch_once(&onceToken, ^{ 43 | msgR = [WKMsgReceiver new]; 44 | }); 45 | return msgR; 46 | } 47 | 48 | - (BOOL)addFunc:(SEL)sel 49 | { 50 | return __addMethod([self class], sel); 51 | } 52 | 53 | + (BOOL)addClassFunc:(SEL)sel { 54 | Class metaClass = objc_getMetaClass(class_getName([self class])); 55 | return __addMethod(metaClass, sel); 56 | } 57 | @end 58 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Notification/NSNotificationCenter+Safe.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSNotificationCenter+Safe.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/7. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSNotificationCenter (Safe) 12 | + (void)registerNotificationCenterCrash; 13 | @end 14 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Notification/NSNotificationCenter+Safe.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSNotificationCenter+Safe.m 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/7. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "NSNotificationCenter+Safe.h" 10 | #import "WKSwizzle.h" 11 | #import "WKCrashManager.h" 12 | @interface WKNotifiProxy : NSObject 13 | 14 | 15 | @end 16 | 17 | @implementation WKNotifiProxy{ 18 | __strong NSMutableArray *_centers; 19 | __unsafe_unretained id _obs; 20 | } 21 | 22 | - (instancetype)initWithObserver:(id)obs { 23 | if (self = [super init]) { 24 | _obs = obs; 25 | _centers = @[].mutableCopy; 26 | } 27 | return self; 28 | } 29 | 30 | - (void)addCenter:(NSNotificationCenter*)center { 31 | if (center) { 32 | [_centers addObject:center]; 33 | } 34 | } 35 | 36 | - (void)dealloc { 37 | @autoreleasepool { 38 | for (NSNotificationCenter *center in _centers) { 39 | [center removeObserver:_obs]; 40 | } 41 | } 42 | } 43 | @end 44 | 45 | 46 | @implementation NSNotificationCenter (Safe) 47 | 48 | + (void)registerNotificationCenterCrash 49 | { 50 | swizzling_exchangeMethod([self class], @selector(addObserver:selector:name:object:), @selector(wksafe_addObserver:selector:name:object:)); 51 | } 52 | 53 | - (void)wksafe_addObserver:(id)observer selector:(SEL)aSelector name:(NSNotificationName)aName object:(id)anObject 54 | { 55 | [self wksafe_addObserver:observer selector:aSelector name:aName object:anObject]; 56 | addCenterForObserver(self, observer); 57 | } 58 | 59 | 60 | void addCenterForObserver(NSNotificationCenter *center ,id obs) { 61 | WKNotifiProxy *remover = nil; 62 | static char removerKey; 63 | @autoreleasepool { 64 | remover = objc_getAssociatedObject(obs, &removerKey); 65 | if (!remover) { 66 | remover = [[WKNotifiProxy alloc] initWithObserver:obs]; 67 | objc_setAssociatedObject(obs, &removerKey, remover, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 68 | } 69 | [remover addCenter:center]; 70 | } 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Null/NSNull+Safe.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSNull+Safe.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/7. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSNull (Safe) 12 | + (void)registerNullCrash; 13 | @end 14 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Null/NSNull+Safe.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSNull+Safe.m 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/7. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "NSNull+Safe.h" 10 | #import "WKSwizzle.h" 11 | #import "NSObject+MsgReceiver.h" 12 | @implementation NSNull (Safe) 13 | 14 | + (void)registerNullCrash 15 | { 16 | swizzling_exchangeMethod([self class], @selector(forwardingTargetForSelector:), @selector(wknullsafe_forwardingTargetForSelector:)); 17 | } 18 | 19 | - (id)wknullsafe_forwardingTargetForSelector:(SEL)aSelector 20 | { 21 | static NSArray * stubObjArr = nil; 22 | if (!stubObjArr) { 23 | stubObjArr = @[@"",@0,@[],@{}]; 24 | } 25 | for (id obj in stubObjArr) { 26 | if ([obj respondsToSelector:aSelector]) { 27 | WKCrashModel * model = [WKCrashModel new]; 28 | model.clasName = NSStringFromClass([self class]); 29 | model.msg = [NSString stringWithFormat:@"send %@'s method %@ to null",NSStringFromClass([obj class]),NSStringFromSelector(aSelector)]; 30 | model.threadStack = [NSThread callStackSymbols]; 31 | [WKCrashReport crashInfo:model type:(WKCrashType_Null)]; 32 | return obj; 33 | } 34 | } 35 | return [self wknullsafe_forwardingTargetForSelector:aSelector]; 36 | } 37 | 38 | @end 39 | 40 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Report/Tools/AppDelegate+visableVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate+visableVC.h 3 | // KanManHua 4 | // 5 | // Created by wangkun on 2017/9/25. 6 | // Copyright © 2017年 KanManHua. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | typedef void(^navClosure)(UINavigationController * nav); 11 | 12 | @interface AppDelegate (visableVC) 13 | 14 | + (UIViewController *)getVisableVC; 15 | + (void)getNavVCWithBlock:(navClosure)closure; 16 | 17 | 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Report/Tools/UIViewExt.h: -------------------------------------------------------------------------------- 1 | /* 2 | Erica Sadun, http://ericasadun.com 3 | iPhone Developer's Cookbook, 3.0 Edition 4 | BSD License, Use at your own risk 5 | */ 6 | 7 | 8 | #import 9 | #import 10 | #define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width) 11 | #define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height) 12 | #define SCREEN_MAX_LENGTH (MAX(SCREEN_WIDTH, SCREEN_HEIGHT)) 13 | #define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) 14 | #define IS_IPHONE_XANDGREATER (IS_IPHONE && SCREEN_MAX_LENGTH >= 812.0) 15 | 16 | #define STATUS_BAR_HEIGHT (IS_IPHONE_XANDGREATER ? 44.f : 20.f) 17 | #define TAB_BAR_HEIGHT (IS_IPHONE_XANDGREATER ? 83.f : 49.f) 18 | #define NAVIGATION_STATUS_HEIGHT (IS_IPHONE_XANDGREATER ? 88.f : 64.f) 19 | #define APPMainColor [UIColor redColor] 20 | #define HJTFont(_AAA) [UIFont systemFontOfSize:(_AAA)] 21 | CGPoint CGRectGetCenter(CGRect rect); 22 | CGRect CGRectMoveToCenter(CGRect rect, CGPoint center); 23 | 24 | @interface UIView (ViewFrameGeometry) 25 | @property CGPoint origin; 26 | @property CGSize size; 27 | 28 | @property (readonly) CGPoint bottomLeft; 29 | @property (readonly) CGPoint bottomRight; 30 | @property (readonly) CGPoint topRight; 31 | 32 | @property CGFloat height; 33 | @property CGFloat width; 34 | 35 | @property CGFloat top; 36 | @property CGFloat left; 37 | 38 | @property CGFloat bottom; 39 | @property CGFloat right; 40 | 41 | - (void) moveBy: (CGPoint) delta; 42 | - (void) scaleBy: (CGFloat) scaleFactor; 43 | - (void) fitInSize: (CGSize) aSize; 44 | 45 | - (void)setAnchorPointTo:(CGPoint)point; 46 | @end 47 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Report/Tools/WKBaseVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKBaseVCViewController.h 3 | // WKVCDeallocManagerDemo 4 | // 5 | // Created by wangkun on 2018/4/18. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WKNavView.h" 11 | #import "UIViewExt.h" 12 | @interface WKBaseVC : UIViewController 13 | 14 | @property (nonatomic, strong) WKNavView * nav; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Report/Tools/WKNavView.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKNavView.h 3 | // WKVCDeallocManagerDemo 4 | // 5 | // Created by wangkun on 2018/4/18. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WKHeader.h" 11 | 12 | @protocol WKNavViewDelegate 13 | 14 | @optional 15 | - (void)backItemClick; 16 | - (void)detailItemClick; 17 | 18 | @end 19 | @interface WKNavView : UIView 20 | 21 | @property (nonatomic, strong) NSString * title; 22 | @property (nonatomic, strong) NSString * backTitle; 23 | @property (nonatomic, strong) NSString * detailTitle; 24 | @property (nonatomic, weak ) id delegate; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Report/UI/WKCrashClassCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKCrashClassCell.h 3 | // MKWeekly 4 | // 5 | // Created by wangkun on 2018/7/8. 6 | // Copyright © 2018年 zymk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WKCrashClassCell : UITableViewCell 12 | 13 | @property (nonatomic, strong) UILabel * titleLabel; 14 | @property (nonatomic, strong) UILabel * countLabel; 15 | @property (nonatomic, strong) UILabel * timeLabel; 16 | 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Report/UI/WKCrashClassListVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKCrashClassListVC.h 3 | // MKWeekly 4 | // 5 | // Created by wangkun on 2018/7/8. 6 | // Copyright © 2018年 zymk. All rights reserved. 7 | // 8 | 9 | #import "WKBaseVC.h" 10 | 11 | @interface WKCrashClassListVC : WKBaseVC 12 | 13 | @property (nonatomic,strong) NSArray * dataSource; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Report/UI/WKCrashListCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKCrashListCell.h 3 | // MKWeekly 4 | // 5 | // Created by wangkun on 2018/7/8. 6 | // Copyright © 2018年 zymk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WKCrashListCell : UITableViewCell 12 | 13 | @property (nonatomic, strong) UILabel * titleLabel; 14 | @property (nonatomic, strong) UILabel * countLabel; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Report/UI/WKCrashListCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKCrashListCell.m 3 | // MKWeekly 4 | // 5 | // Created by wangkun on 2018/7/8. 6 | // Copyright © 2018年 zymk. All rights reserved. 7 | // 8 | 9 | #import "WKCrashListCell.h" 10 | #import "UIViewExt.h" 11 | @interface WKCrashListCell () 12 | 13 | 14 | 15 | @end 16 | 17 | @implementation WKCrashListCell 18 | 19 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 20 | { 21 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 22 | if (self) { 23 | [self configUI]; 24 | } 25 | return self; 26 | } 27 | 28 | - (void)configUI 29 | { 30 | 31 | [self.contentView addSubview:self.countLabel]; 32 | self.countLabel.frame = CGRectMake(SCREEN_WIDTH - 30 - 16, (100 - 25) / 2.f, 30, 25); 33 | 34 | [self.contentView addSubview:self.titleLabel]; 35 | self.titleLabel.frame = CGRectMake(16, 16, SCREEN_WIDTH - 30 - 16 - 16 - 10 , 100 - 16); 36 | UIView * line = [UIView new]; 37 | line.backgroundColor = APPMainColor; 38 | line.frame = CGRectMake(0, 100 - 0.5, SCREEN_WIDTH, 0.5); 39 | [self.contentView addSubview:line]; 40 | 41 | 42 | } 43 | 44 | - (UILabel *)countLabel 45 | { 46 | if (!_countLabel) { 47 | _countLabel = [UILabel new]; 48 | _countLabel.font = HJTFont(13); 49 | _countLabel.textAlignment = NSTextAlignmentRight; 50 | _countLabel.textColor = APPMainColor; 51 | } 52 | return _countLabel; 53 | } 54 | 55 | - (UILabel *)titleLabel 56 | { 57 | if (!_titleLabel) { 58 | _titleLabel = [UILabel new]; 59 | _titleLabel.font = HJTFont(16); 60 | _titleLabel.numberOfLines = 0; 61 | _titleLabel.textColor = APPMainColor; 62 | } 63 | return _titleLabel; 64 | } 65 | 66 | - (void)awakeFromNib { 67 | [super awakeFromNib]; 68 | // Initialization code 69 | } 70 | 71 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 72 | [super setSelected:selected animated:animated]; 73 | 74 | // Configure the view for the selected state 75 | } 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Report/UI/WKCrashListVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKCrashListVC.h 3 | // MKWeekly 4 | // 5 | // Created by wangkun on 2018/7/8. 6 | // Copyright © 2018年 zymk. All rights reserved. 7 | // 8 | 9 | #import "WKBaseVC.h" 10 | 11 | @interface WKCrashListVC : WKBaseVC 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Report/UI/WKCrashTypeListVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKCarshTypeListVC.h 3 | // MKWeekly 4 | // 5 | // Created by wangkun on 2018/7/8. 6 | // Copyright © 2018年 zymk. All rights reserved. 7 | // 8 | 9 | #import "WKBaseVC.h" 10 | 11 | @interface WKCrashTypeListVC : WKBaseVC 12 | 13 | @property (nonatomic, strong) NSDictionary * dataSource; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Report/UI/WKHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKHeader.h 3 | // WKVCDeallocManagerDemo 4 | // 5 | // Created by wangkun on 2018/4/18. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #ifndef WKHeader_h 10 | #define WKHeader_h 11 | #define WK_SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width) 12 | #define WK_SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height) 13 | #define WK_IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) 14 | #define WK_SCREEN_MAX_LENGTH (MAX(WK_SCREEN_WIDTH, WK_SCREEN_HEIGHT)) 15 | #define WK_IS_IPHONE_X (WK_IS_IPHONE && WK_SCREEN_MAX_LENGTH >= 812.0) 16 | #define WK_NAVIGATION_STATUS_HEIGHT (WK_IS_IPHONE_X ? 88.f : 64.f) 17 | 18 | #endif /* WKHeader_h */ 19 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Report/WKCrashReport.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKCrashReport.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/4. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef enum : NSUInteger { 12 | WKCrashType_UnrecognizedSelector = 0, 13 | WKCrashType_Container, 14 | WKCrashType_Timer, 15 | WKCrashType_KVO, 16 | WKCrashType_Null, 17 | WKCrashType_String, 18 | WKCrashType_Zombie, 19 | WKCrashType_NotificationCenter, 20 | } WKCrashType; 21 | 22 | //不同的crash 信息当有不同的侧重点,主要是类名,方法名,由于什么原因崩溃,对战信息 23 | @interface WKCrashModel : NSObject 24 | 25 | @property (nonatomic, strong) NSString * clasName; 26 | @property (nonatomic, strong) NSString * msg;//could be 方法名,或者其他 27 | @property (nonatomic, strong) NSArray * threadStack; 28 | @property (nonatomic, assign) NSTimeInterval time; 29 | @property (nonatomic, strong, readonly) NSString * deviceType; 30 | @property (nonatomic, strong, readonly) NSString * systemVersion; 31 | 32 | @end 33 | @protocol WKCrashReportDelegate 34 | 35 | - (void)handleCrashInfo:(WKCrashModel *)model type:(NSString *)type; 36 | 37 | @end 38 | 39 | @interface WKCrashReport : NSObject 40 | 41 | @property (nonatomic, weak ) id delegate; 42 | 43 | + (instancetype)sharedReport; 44 | 45 | + (void)crashInfo:(WKCrashModel *)model type:(WKCrashType)type; 46 | + (NSDictionary *)getCrashReportWithType:(WKCrashType)type; 47 | + (NSArray *)getAllCrashReport; 48 | + (NSString *)getPathKeyWithType:(WKCrashType)type; 49 | + (void)setWarnningTextWithType:(WKCrashType)type; 50 | + (NSArray *)decodeWithString:(NSString *)str; 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/String/NSMutableString+Safe.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableString+Safe.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/7. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSMutableString (Safe) 12 | 13 | + (void)registerMutableStringCrash; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/String/NSMutableString+Safe.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableString+Safe.m 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/7. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "NSMutableString+Safe.h" 10 | #import "WKSwizzle.h" 11 | #import "NSObject+MsgReceiver.h" 12 | #import "WKCrashManager.h" 13 | @implementation NSMutableString (Safe) 14 | 15 | + (void)registerMutableStringCrash 16 | { 17 | swizzling_exchangeMethod(NSClassFromString(@"__NSCFString"), @selector(appendString:), @selector(wksafe_appendString:)); 18 | swizzling_exchangeMethod(NSClassFromString(@"__NSCFString"), @selector(insertString:atIndex:), @selector(wksafe_insertString:atIndex:)); 19 | } 20 | 21 | - (void)wksafe_appendString:(NSString *)aString 22 | { 23 | if (aString) { 24 | [self wksafe_appendString:aString]; 25 | return; 26 | } 27 | [self sendCrashInfoWithMsg:[NSString stringWithUTF8String:__func__] type:(WKCrashType_String)]; 28 | } 29 | 30 | - (void)wksafe_insertString:(NSString *)aString atIndex:(NSUInteger)loc 31 | { 32 | if (aString && loc <= self.length) { 33 | [self wksafe_insertString:aString atIndex:loc]; 34 | return; 35 | } 36 | [self sendCrashInfoWithMsg:[NSString stringWithUTF8String:__func__] type:(WKCrashType_String)]; 37 | 38 | } 39 | @end 40 | 41 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/String/NSString+Safe.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Safe.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/7. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSString (Safe) 12 | 13 | + (void)registerStringCrash; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Timer/NSTimer+Safe.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSTimer+Safe.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/7. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSTimer (Safe) 12 | + (void)registerTimerCrash; 13 | @end 14 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/WKCrashManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKCrashManager.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | 13 | 14 | typedef NS_OPTIONS(NSUInteger, WKCrashRegisterType) { 15 | WKCrashRegisterType_None = 0, 16 | WKCrashRegisterType_UnrecognizedSelector = 1 << 1, 17 | WKCrashRegisterType_Container = 1 << 2, 18 | WKCrashRegisterType_Timer = 1 << 3, 19 | WKCrashRegisterType_KVO = 1 << 4, 20 | WKCrashRegisterType_Null = 1 << 5, 21 | WKCrashRegisterType_String = 1 << 6, 22 | WKCrashRegisterType_Zombie = 1 << 7, 23 | WKCrashRegisterType_NotificationCenter = 1 << 8, 24 | WKCrashRegisterType_All = (WKCrashRegisterType_UnrecognizedSelector | 25 | WKCrashRegisterType_Container | 26 | WKCrashRegisterType_Timer | 27 | WKCrashRegisterType_KVO | 28 | WKCrashRegisterType_Null | 29 | WKCrashRegisterType_String | 30 | WKCrashRegisterType_NotificationCenter) 31 | }; 32 | 33 | 34 | @interface WKCrashManager : NSObject 35 | 36 | + (instancetype)sharedCrashManager; 37 | + (void)regeisterCrashSDKWithType:(WKCrashRegisterType)type;//注册非僵尸crash 38 | + (void)regeisterZombieCrashWithClasses:(NSArray *)classes;//注册僵尸crash 需要传入数组 39 | @end 40 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/WKHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKHeader.h 3 | // WKVCDeallocManagerDemo 4 | // 5 | // Created by wangkun on 2018/4/18. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #ifndef WKHeader_h 10 | #define WKHeader_h 11 | #define WK_SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width) 12 | #define WK_SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height) 13 | #define WK_IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) 14 | #define WK_SCREEN_MAX_LENGTH (MAX(WK_SCREEN_WIDTH, WK_SCREEN_HEIGHT)) 15 | #define WK_IS_IPHONE_X (WK_IS_IPHONE && WK_SCREEN_MAX_LENGTH >= 812.0) 16 | #define WK_NAVIGATION_STATUS_HEIGHT (WK_IS_IPHONE_X ? 88.f : 64.f) 17 | 18 | #endif /* WKHeader_h */ 19 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/WKSwizzle.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKSwizzle.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/5. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #include 10 | 11 | 12 | static inline void swizzling_exchangeMethod(Class clazz, SEL originalSelector, SEL exchangeSelector) { 13 | 14 | Method originalMethod = class_getInstanceMethod(clazz, originalSelector); 15 | 16 | Method exchangeMethod = class_getInstanceMethod(clazz, exchangeSelector); 17 | if (class_addMethod(clazz, originalSelector, method_getImplementation(exchangeMethod), method_getTypeEncoding(exchangeMethod))) { 18 | class_replaceMethod(clazz, exchangeSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); 19 | }else{ 20 | method_exchangeImplementations(originalMethod, exchangeMethod); 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Zombie/NSObject+WKZombie.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Zombie.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/9. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (WKZombie) 12 | 13 | - (void)wkzombiesafe_dealloc; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Zombie/NSObject+WKZombie.mm: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Zombie.m 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/9. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "NSObject+WKZombie.h" 10 | #import 11 | #import 12 | #import "WKZombieManager.h" 13 | 14 | static NSInteger const maxCount = 100; 15 | static std::list instanceList; 16 | 17 | @implementation NSObject (WKZombie) 18 | 19 | - (void)wkzombiesafe_dealloc 20 | { 21 | 22 | NSArray * classArr = [WKZombieManager sharedZombieManager].zombieClassArr; 23 | Class selfClass = object_getClass(self); 24 | BOOL needProtect = NO; 25 | for (NSString *className in classArr) { 26 | Class clazz = objc_getClass([className UTF8String]); 27 | if (clazz == selfClass) { 28 | needProtect = YES; 29 | break; 30 | } 31 | } 32 | [classArr release]; 33 | if (needProtect) { 34 | NSString *className = NSStringFromClass(selfClass); 35 | NSString *zombieClassName = [@"WKZombie_" stringByAppendingString: className];//这一步很重要,动态生成类,如果被僵尸,则可以得知实际是哪个类产生了僵尸指针 导致崩溃 36 | Class zombieClass = NSClassFromString(zombieClassName); 37 | if(!zombieClass) { 38 | zombieClass = objc_allocateClassPair([WKZombieStub class], [zombieClassName UTF8String], 0); 39 | } 40 | objc_destructInstance(self);//销毁实例 相关信息 内存不释放 41 | object_setClass(self, zombieClass); 42 | instanceList.size(); 43 | if (instanceList.size() >= maxCount) { 44 | id object = instanceList.front(); 45 | instanceList.pop_front(); 46 | free(object); 47 | } 48 | instanceList.push_back(self); 49 | } 50 | else 51 | { 52 | [self wkzombiesafe_dealloc]; 53 | } 54 | 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Zombie/WKZombieManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKZombieManager.h 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/9. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | @interface WKZombieStub : NSObject 11 | 12 | @property (readwrite,assign,nonatomic) Class origClass; 13 | 14 | @end 15 | @interface WKZombieManager : NSObject 16 | 17 | @property (nonatomic, strong) NSMutableArray * zombieClassArr; 18 | + (instancetype)sharedZombieManager; 19 | + (void)registerZombieCrashWithClassArr:(NSArray *)classArr; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /WKCrashManagerDemo/WKCrashSDK/Zombie/WKZombieManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKZombieManager.m 3 | // OCHookWithLibffi 4 | // 5 | // Created by wangkun on 2018/7/9. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "WKZombieManager.h" 10 | #import "WKMsgReceiver.h" 11 | #import "WKSwizzle.h" 12 | #import "NSObject+WKZombie.h" 13 | #import "NSObject+MsgReceiver.h" 14 | @implementation WKZombieStub 15 | 16 | - (instancetype)init{ 17 | return self; 18 | } 19 | 20 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { 21 | 22 | 23 | [self sendCrashInfoWithMsg:[NSString stringWithFormat:@"- %@",NSStringFromSelector(aSelector)] type:(WKCrashType_Zombie)]; 24 | WKMsgReceiver *stub = [WKMsgReceiver sharedMsgReceiver]; 25 | [stub addFunc:aSelector]; 26 | return [[WKMsgReceiver class] instanceMethodSignatureForSelector:aSelector]; 27 | } 28 | 29 | - (void)forwardInvocation:(NSInvocation *)anInvocation { 30 | [anInvocation invokeWithTarget:[WKMsgReceiver sharedMsgReceiver]]; 31 | } 32 | 33 | @end 34 | 35 | @implementation WKZombieManager 36 | 37 | + (instancetype)sharedZombieManager 38 | { 39 | static WKZombieManager * zm = nil; 40 | static dispatch_once_t onceToken; 41 | dispatch_once(&onceToken, ^{ 42 | zm = [WKZombieManager new]; 43 | }); 44 | return zm; 45 | } 46 | 47 | - (NSMutableArray *)zombieClassArr 48 | { 49 | if (!_zombieClassArr) { 50 | _zombieClassArr = [NSMutableArray array]; 51 | } 52 | return _zombieClassArr; 53 | } 54 | 55 | 56 | + (void)registerZombieCrashWithClassArr:(NSArray *)classArr 57 | { 58 | WKZombieManager * zm = [WKZombieManager sharedZombieManager]; 59 | NSMutableArray * realArr = [NSMutableArray arrayWithArray:classArr]; 60 | for (NSString * className in classArr) { 61 | NSBundle * bundle = [NSBundle bundleForClass:NSClassFromString(className)]; 62 | if (bundle != [NSBundle mainBundle]) { 63 | [realArr removeObject:className]; 64 | } 65 | } 66 | zm.zombieClassArr = realArr; 67 | static dispatch_once_t onceToken; 68 | dispatch_once(&onceToken, ^{ 69 | swizzling_exchangeMethod([NSObject class], NSSelectorFromString(@"dealloc"), @selector(wkzombiesafe_dealloc)); 70 | }); 71 | } 72 | 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/README.MD: -------------------------------------------------------------------------------- 1 | #恢复现场功能Demo 2 | 3 | [详情介绍地址](https://www.jianshu.com/p/c7e5a02a454d) -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo.xcodeproj/project.xcworkspace/xcuserdata/wangkun.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WangKunKun/WKDemo/9915691c5fc1ff44b494fb7f91002252c5b6b714/WKRestoreSceneDemo/WKRestoreSceneDemo.xcodeproj/project.xcworkspace/xcuserdata/wangkun.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo.xcodeproj/xcuserdata/wangkun.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo.xcodeproj/xcuserdata/wangkun.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WKRestoreSceneDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/AppDelegate+visableVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate+visableVC.h 3 | // KanManHua 4 | // 5 | // Created by wangkun on 2017/9/25. 6 | // Copyright © 2017年 KanManHua. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate (visableVC) 12 | 13 | + (UIViewController *)getVisableVC; 14 | + (void)getNavVCWithBlock:(navClosure)closure; 15 | + (UIView *)getVisableView; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/AppDelegate+visableVC.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate+visableVC.m 3 | // KanManHua 4 | // 5 | // Created by wangkun on 2017/9/25. 6 | // Copyright © 2017年 KanManHua. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate+visableVC.h" 10 | 11 | @implementation AppDelegate (visableVC) 12 | 13 | + (UIViewController *)getVisableVC 14 | { 15 | AppDelegate * delegate = (AppDelegate *)[UIApplication sharedApplication].delegate; 16 | return [delegate getVisableVC]; 17 | } 18 | 19 | + (void)getNavVCWithBlock:(navClosure)closure 20 | { 21 | AppDelegate * delegate = (AppDelegate *)[UIApplication sharedApplication].delegate; 22 | [delegate getNavVCWithBlock:closure]; 23 | } 24 | 25 | + (UIView *)getVisableView 26 | { 27 | AppDelegate * delegate = (AppDelegate *)[UIApplication sharedApplication].delegate; 28 | return [delegate getVisableView]; 29 | } 30 | 31 | - (UIViewController *)getVisableVC 32 | { 33 | UIViewController * vc = self.window.rootViewController; 34 | while ([vc isKindOfClass:[UITabBarController class]]) { 35 | vc = ((UITabBarController *)vc).selectedViewController; 36 | } 37 | 38 | while ([vc isKindOfClass:[UINavigationController class]]) { 39 | vc = ((UINavigationController *)vc).visibleViewController; 40 | } 41 | 42 | while (vc.presentedViewController) { 43 | vc = vc.presentedViewController; 44 | } 45 | return vc; 46 | } 47 | 48 | - (UIView *)getVisableView 49 | { 50 | UIViewController * vc = [self getVisableVC]; 51 | while (vc.tabBarController) { 52 | vc = vc.tabBarController; 53 | } 54 | while (vc.navigationController) { 55 | vc = vc.navigationController; 56 | } 57 | while (vc.tabBarController) { 58 | vc = vc.tabBarController; 59 | } 60 | while (vc.navigationController) { 61 | vc = vc.navigationController; 62 | } 63 | return vc.view; 64 | } 65 | 66 | - (void)getNavVCWithBlock:(navClosure)closure 67 | { 68 | UIViewController * tmpVC = [self getVisableVC]; 69 | UINavigationController * navi = tmpVC.navigationController; 70 | if (navi) { 71 | closure(navi); 72 | } 73 | else 74 | { 75 | [navi dismissViewControllerAnimated:YES completion:^{ 76 | [self getNavVCWithBlock:closure]; 77 | }]; 78 | } 79 | } 80 | 81 | @end 82 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WKRestoreSceneDemo 4 | // 5 | // Created by wangkun on 2017/12/27. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | typedef void(^navClosure)(UINavigationController * nav); 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (strong, nonatomic) UIWindow *window; 15 | 16 | 17 | @end 18 | 19 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/UIViewController+RestoreScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+RestoreScene.h 3 | // KanManHua 4 | // 5 | // Created by wangkun on 2017/11/15. 6 | // Copyright © 2017年 KanManHua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIViewController (RestoreScene) 12 | + (NSArray *)restoreSceneKey; 13 | @end 14 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/UIViewController+RestoreScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+RestoreScene.m 3 | // KanManHua 4 | // 5 | // Created by wangkun on 2017/11/15. 6 | // Copyright © 2017年 KanManHua. All rights reserved. 7 | // 8 | 9 | #import "UIViewController+RestoreScene.h" 10 | 11 | @implementation UIViewController (RestoreScene) 12 | 13 | 14 | 15 | + (NSArray *)restoreSceneKey 16 | { 17 | return nil; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // WKRestoreSceneDemo 4 | // 5 | // Created by wangkun on 2017/12/27. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIViewController+RestoreScene.h" 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/WKClassManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKClassPropertyManager.h 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/4. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WKClassPropertyModel.h" 11 | #import "WKClassMethodModel.h" 12 | @interface WKClassManager : NSObject 13 | 14 | + (NSArray *)getClassPropertysWithClass:(Class)classs; 15 | + (NSArray *)getClassMethodsWithClass:(Class)classs; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/WKClassMethodModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKClassMethodModel.h 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/9. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @interface WKClassMethodModel : NSObject 12 | 13 | @property (nonatomic, strong) NSString * name; 14 | @property (nonatomic, assign) IMP oldIMP; 15 | @property (nonatomic, assign) Method method; 16 | + (instancetype)createClassMethodModelWithMethod:(Method)property; 17 | 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/WKClassMethodModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKClassMethodModel.m 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/9. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "WKClassMethodModel.h" 10 | 11 | @implementation WKClassMethodModel 12 | 13 | + (instancetype)createClassMethodModelWithMethod:(Method)method 14 | { 15 | WKClassMethodModel * model = [self new]; 16 | model.name = NSStringFromSelector(method_getName(method)); 17 | model.oldIMP = method_getImplementation(method); 18 | model.method = method; 19 | return model; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/WKClassPropertyModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKClassPropertyModel.h 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/4. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | typedef enum : NSUInteger { 13 | WKPropertyType_Object, 14 | WKPropertyType_CNumber, 15 | WKPropertyType_Unknown, 16 | } WKPropertyType; 17 | 18 | @interface WKClassPropertyModel : NSObject 19 | 20 | @property (nonatomic, strong) NSString * setterName; 21 | @property (nonatomic, strong) NSString * getterName; 22 | @property (nonatomic, strong) NSString * varName; 23 | @property (nonatomic, strong) NSString * typeName; 24 | @property (nonatomic, assign) WKPropertyType type; 25 | 26 | @property (nonatomic, strong) NSString * name; 27 | @property (nonatomic, assign) IMP oldsetterIMP; 28 | 29 | + (instancetype)createClassPropertyModelWithProperty:(objc_property_t)property; 30 | 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/WKRestoreSceneManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKRestoreSceneManager.h 3 | // KanManHua 4 | // 5 | // Created by wangkun on 2017/11/14. 6 | // Copyright © 2017年 KanManHua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WKRestoreSceneManager : NSObject 12 | 13 | + (instancetype)sharedRestoreSceneManager; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WKRestoreSceneDemo 4 | // 5 | // Created by wangkun on 2017/12/27. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemoTests/WKRestoreSceneDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKRestoreSceneDemoTests.m 3 | // WKRestoreSceneDemoTests 4 | // 5 | // Created by wangkun on 2017/12/27. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WKRestoreSceneDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation WKRestoreSceneDemoTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /WKRestoreSceneDemo/WKRestoreSceneDemoUITests/WKRestoreSceneDemoUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKRestoreSceneDemoUITests.m 3 | // WKRestoreSceneDemoUITests 4 | // 5 | // Created by wangkun on 2017/12/27. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WKRestoreSceneDemoUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation WKRestoreSceneDemoUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/GuideView/WKBaseView.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKBaseView.h 3 | // KanManHua 4 | // 5 | // Created by wangkun on 2017/11/8. 6 | // Copyright © 2017年 KanManHua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //优先级 为后续队列拓展做准备工作 12 | typedef enum : NSUInteger { 13 | WKBaseViewShowPriorityLow, 14 | WKBaseViewShowPriorityNormal, 15 | WKBaseViewShowPriorityHigh, 16 | } WKBaseViewShowPriority; 17 | 18 | @interface WKBaseView : UIView 19 | 20 | @property (nonatomic, strong) UIView * bgView; 21 | @property (nonatomic, assign) CGFloat animDuration; 22 | @property (nonatomic, weak, readonly) UIView * parentView; 23 | @property (nonatomic, assign) WKBaseViewShowPriority priority; 24 | 25 | /** 26 | 布局方法 子类 布局需复写 复写需先调用基类方法 27 | */ 28 | - (void)setInterFace; 29 | /** 30 | 执行出现和消失动画前会调用 若需要自定义动画 在此方法中设置改变后的动画属性对应值 动画时会自动调用 31 | 32 | @param isShow show or dismiss 33 | */ 34 | - (void)updateContentViewConstraint:(BOOL)isShow;//于此方法中调整布局 也达到消失动画 和 出现动画自定义 35 | 36 | //展示方法 基本 37 | - (void)dismiss; 38 | - (void)showInView:(UIView *)view isShow:(BOOL)flag; 39 | 40 | //展示在view上 过time秒后 自动隐藏 41 | - (void)showInView:(UIView *)view autoDismissAfterDelay:(NSTimeInterval)time; 42 | //周期方法 43 | - (void)viewWillShow; 44 | - (void)viewDidShow; 45 | - (void)viewWillDismiss; 46 | - (void)viewDidDismiss; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/GuideView/WKKMBaseGuideView.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKBaseGuideView.h 3 | // KanManHua 4 | // 5 | // Created by wangkun on 2017/9/13. 6 | // Copyright © 2017年 KanManHua. All rights reserved. 7 | // 8 | 9 | #import "WKBaseView.h" 10 | //view tag 特殊情况使用 11 | static CGFloat wkBaseGuideViewTag = 10088; 12 | 13 | @protocol WKKMBaseGuideViewDelegate 14 | 15 | - (void)didDismissWithView:(WKBaseView *)view; 16 | 17 | @end 18 | 19 | @interface WKKMBaseGuideView : WKBaseView 20 | @property (nonatomic, weak ) id delegate; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/GuideView/WKKMBaseGuideView.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKBaseGuideView.m 3 | // KanManHua 4 | // 5 | // Created by wangkun on 2017/9/13. 6 | // Copyright © 2017年 KanManHua. All rights reserved. 7 | // 8 | 9 | #import "WKKMBaseGuideView.h" 10 | @interface WKKMBaseGuideView () 11 | 12 | 13 | @property (nonatomic, weak) UINavigationController * nav; 14 | @property (nonatomic, assign) BOOL navLeftSwipEnableIsChanged;//是否认为改变过nav的左滑手势 15 | @end 16 | 17 | @implementation WKKMBaseGuideView 18 | 19 | /* 20 | // Only override drawRect: if you perform custom drawing. 21 | // An empty implementation adversely affects performance during animation. 22 | - (void)drawRect:(CGRect)rect { 23 | // Drawing code 24 | } 25 | */ 26 | 27 | 28 | #pragma mark 布局相关 29 | - (void)setInterFace 30 | { 31 | [super setInterFace]; 32 | 33 | _navLeftSwipEnableIsChanged = NO; 34 | 35 | self.alpha = 0; 36 | 37 | self.priority = WKBaseViewShowPriorityHigh; 38 | self.tag = wkBaseGuideViewTag; 39 | } 40 | 41 | 42 | 43 | #pragma mark 动画相关 44 | 45 | - (void)viewWillShow 46 | { 47 | [super viewWillShow]; 48 | //引导图模式期间 不支持左滑返回操作 49 | if ([[self.superview nextResponder] isKindOfClass:[UINavigationController class]]) { 50 | _nav = [self.superview nextResponder]; 51 | } 52 | if (_nav.interactivePopGestureRecognizer.enabled) { 53 | _navLeftSwipEnableIsChanged = YES;//记录是否改变, 54 | _nav.interactivePopGestureRecognizer.enabled = NO; 55 | } 56 | 57 | } 58 | 59 | - (void)viewWillDismiss 60 | { 61 | [super viewWillDismiss]; 62 | if (_navLeftSwipEnableIsChanged) {//改变过后 直接返回 63 | _nav.interactivePopGestureRecognizer.enabled = YES; 64 | } 65 | } 66 | 67 | - (void)viewDidDismiss 68 | { 69 | [super viewDidDismiss]; 70 | if (_delegate && [_delegate respondsToSelector:@selector(didDismissWithView:)]) { 71 | [_delegate didDismissWithView:self]; 72 | } 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/GuideView/WKStepMaskGuideView.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKStepMaskGuideView.h 3 | // MKWeekly 4 | // 5 | // Created by wangkun on 2018/3/26. 6 | // Copyright © 2018年 zymk. All rights reserved. 7 | // 8 | 9 | #import "WKKMBaseGuideView.h" 10 | 11 | 12 | #define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width) 13 | #define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height) 14 | 15 | @class WKStepMaskGuideView; 16 | 17 | //UIView 类目 用于控制布局 不同step时的指向性view的 wk_steptag 18 | @interface UIView (WKStepMaskGuideViewTag) 19 | 20 | @property (nonatomic, assign) NSInteger wk_stepTag; 21 | 22 | @end 23 | 24 | ///首先构建一个模型,圆角度 25 | @interface WKStepMaskModel : NSObject 26 | 27 | ///基于keywindow的frame 28 | @property (nonatomic, assign) CGRect frame; 29 | @property (nonatomic, strong) UIView * view; 30 | @property (nonatomic, assign) CGFloat cornerRadius; 31 | @property (nonatomic, assign) NSUInteger step; 32 | 33 | ///推荐使用此方法 计算好frame传入 34 | + (instancetype)creatModelWithFrame:(CGRect)frame cornerRadius:(CGFloat)cornerRadius step:(NSUInteger)step; 35 | ///推荐使用withframe方法初始化 如若传入view 只会取此view对应其俯视图的frame,如果布局层级过深可能会有差错。 36 | + (instancetype)creatModelWithView:(UIView *)view cornerRadius:(CGFloat)cornerRadius step:(NSUInteger)step; 37 | 38 | @end 39 | 40 | @protocol WKStepMaskGuideViewDelegate 41 | 42 | - (void)viewWillChangeWithStep:(NSUInteger)step view:(WKStepMaskGuideView *)view; 43 | 44 | @end 45 | 46 | @interface WKStepMaskGuideView : WKKMBaseGuideView 47 | 48 | @property (nonatomic, strong, readonly) NSMutableArray * views; 49 | @property (nonatomic, strong, readonly) NSMutableArray * rects; 50 | @property (nonatomic, strong, readonly) NSMutableArray * steps; 51 | 52 | @property (nonatomic, weak ) id delegate; 53 | ///models中的model的step可以无序,内部会进行排序,生成的views根据step排序 54 | - (instancetype)initWithModels:(NSArray *)models; 55 | 56 | 57 | ///子类覆写 58 | - (void)configInterFace; 59 | ///此方法 先调用与代理方法 willchange 60 | - (void)viewWillEnterNextStep:(NSUInteger)nextStep; 61 | - (void)viewDidEnterNextStep:(NSUInteger)nextStep; 62 | @end 63 | 64 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/README.MD: -------------------------------------------------------------------------------- 1 | #引导功能模板Demo 2 | 3 | [详情介绍地址](https://www.jianshu.com/p/53db67964f4d) -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemo.xcodeproj/project.xcworkspace/xcuserdata/wangkun.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WangKunKun/WKDemo/9915691c5fc1ff44b494fb7f91002252c5b6b714/WKStepMaskViewDemo/WKStepMaskViewDemo.xcodeproj/project.xcworkspace/xcuserdata/wangkun.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemo.xcodeproj/xcuserdata/wangkun.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WKStepMaskViewDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WKStepMaskViewDemo 4 | // 5 | // Created by wangkun on 2018/3/26. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // WKStepMaskViewDemo 4 | // 5 | // Created by wangkun on 2018/3/26. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemo/StepMaskGuideView.h: -------------------------------------------------------------------------------- 1 | // 2 | // StepMaskGuideView.h 3 | // WKStepMaskViewDemo 4 | // 5 | // Created by wangkun on 2018/3/26. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "WKStepMaskGuideView.h" 10 | 11 | @interface StepMaskGuideView : WKStepMaskGuideView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemo/StepMaskGuideView.m: -------------------------------------------------------------------------------- 1 | // 2 | // StepMaskGuideView.m 3 | // WKStepMaskViewDemo 4 | // 5 | // Created by wangkun on 2018/3/26. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "StepMaskGuideView.h" 10 | 11 | @interface StepMaskGuideView () 12 | 13 | @property (nonatomic, strong) UILabel * nextLabel; 14 | @property (nonatomic, strong) UILabel * finishLabel; 15 | 16 | @end 17 | 18 | @implementation StepMaskGuideView 19 | 20 | - (void)configInterFace 21 | { 22 | [self addSubview:self.nextLabel]; 23 | [self addSubview:self.finishLabel]; 24 | 25 | self.nextLabel.frame = CGRectMake(CGRectGetMinX(self.views.firstObject.frame), CGRectGetMaxY(self.views.firstObject.frame) + 10, 50, 18); 26 | self.nextLabel.wk_stepTag = self.views.firstObject.wk_stepTag;//必备 设置其需要与的view同时出现的steptag 27 | 28 | self.finishLabel.frame = CGRectMake(CGRectGetMinX(self.views.lastObject.frame), CGRectGetMaxY(self.views.lastObject.frame) + 10, 50, 18); 29 | self.finishLabel.wk_stepTag = self.views.lastObject.wk_stepTag; 30 | } 31 | 32 | - (UILabel *)nextLabel 33 | { 34 | if (!_nextLabel) { 35 | _nextLabel = [UILabel new]; 36 | _nextLabel.textColor = [UIColor whiteColor]; 37 | _nextLabel.font = [UIFont systemFontOfSize:15]; 38 | _nextLabel.text = @"下一步"; 39 | _nextLabel.textAlignment = NSTextAlignmentCenter; 40 | } 41 | return _nextLabel; 42 | } 43 | 44 | - (UILabel *)finishLabel 45 | { 46 | if (!_finishLabel) { 47 | _finishLabel = [UILabel new]; 48 | _finishLabel.textColor = [UIColor whiteColor]; 49 | _finishLabel.font = [UIFont systemFontOfSize:15]; 50 | _finishLabel.text = @"完成"; 51 | _finishLabel.textAlignment = NSTextAlignmentCenter; 52 | } 53 | return _finishLabel; 54 | } 55 | /* 56 | // Only override drawRect: if you perform custom drawing. 57 | // An empty implementation adversely affects performance during animation. 58 | - (void)drawRect:(CGRect)rect { 59 | // Drawing code 60 | } 61 | */ 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // WKStepMaskViewDemo 4 | // 5 | // Created by wangkun on 2018/3/26. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WKStepMaskViewDemo 4 | // 5 | // Created by wangkun on 2018/3/26. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemoTests/WKStepMaskViewDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKStepMaskViewDemoTests.m 3 | // WKStepMaskViewDemoTests 4 | // 5 | // Created by wangkun on 2018/3/26. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WKStepMaskViewDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation WKStepMaskViewDemoTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /WKStepMaskViewDemo/WKStepMaskViewDemoUITests/WKStepMaskViewDemoUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKStepMaskViewDemoUITests.m 3 | // WKStepMaskViewDemoUITests 4 | // 5 | // Created by wangkun on 2018/3/26. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WKStepMaskViewDemoUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation WKStepMaskViewDemoUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'WKViewManagerDemo' do 5 | # Uncomment the next line if you're using Swift or would like to use dynamic frameworks 6 | # use_frameworks! 7 | pod "Masonry" 8 | # Pods for WKViewManagerDemo 9 | 10 | target 'WKViewManagerDemoTests' do 11 | inherit! :search_paths 12 | # Pods for testing 13 | end 14 | 15 | target 'WKViewManagerDemoUITests' do 16 | inherit! :search_paths 17 | # Pods for testing 18 | end 19 | 20 | end 21 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Masonry (1.1.0) 3 | 4 | DEPENDENCIES: 5 | - Masonry 6 | 7 | SPEC REPOS: 8 | https://github.com/cocoapods/specs.git: 9 | - Masonry 10 | 11 | SPEC CHECKSUMS: 12 | Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 13 | 14 | PODFILE CHECKSUM: 9b8535c38dc31f59c05ab581fd3102bac1153a72 15 | 16 | COCOAPODS: 1.5.2 17 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/MASCompositeConstraint.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASCompositeConstraint.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/MASConstraint+Private.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASConstraint+Private.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/MASConstraint.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASConstraint.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/MASConstraintMaker.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASConstraintMaker.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/MASLayoutConstraint.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASLayoutConstraint.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/MASUtilities.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASUtilities.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/MASViewAttribute.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASViewAttribute.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/MASViewConstraint.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASViewConstraint.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/Masonry.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/Masonry.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/NSArray+MASAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/NSArray+MASAdditions.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/NSArray+MASShorthandAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/NSArray+MASShorthandAdditions.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/NSLayoutConstraint+MASDebugAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/NSLayoutConstraint+MASDebugAdditions.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/View+MASAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/View+MASAdditions.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/View+MASShorthandAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/View+MASShorthandAdditions.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Private/Masonry/ViewController+MASAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/ViewController+MASAdditions.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/MASCompositeConstraint.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASCompositeConstraint.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/MASConstraint+Private.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASConstraint+Private.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/MASConstraint.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASConstraint.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/MASConstraintMaker.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASConstraintMaker.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/MASLayoutConstraint.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASLayoutConstraint.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/MASUtilities.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASUtilities.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/MASViewAttribute.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASViewAttribute.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/MASViewConstraint.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/MASViewConstraint.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/Masonry.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/Masonry.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/NSArray+MASAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/NSArray+MASAdditions.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/NSArray+MASShorthandAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/NSArray+MASShorthandAdditions.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/NSLayoutConstraint+MASDebugAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/NSLayoutConstraint+MASDebugAdditions.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/View+MASAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/View+MASAdditions.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/View+MASShorthandAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/View+MASShorthandAdditions.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Headers/Public/Masonry/ViewController+MASAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../Masonry/Masonry/ViewController+MASAdditions.h -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Masonry (1.1.0) 3 | 4 | DEPENDENCIES: 5 | - Masonry 6 | 7 | SPEC REPOS: 8 | https://github.com/cocoapods/specs.git: 9 | - Masonry 10 | 11 | SPEC CHECKSUMS: 12 | Masonry: 678fab65091a9290e40e2832a55e7ab731aad201 13 | 14 | PODFILE CHECKSUM: 9b8535c38dc31f59c05ab581fd3102bac1153a72 15 | 16 | COCOAPODS: 1.5.2 17 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Masonry/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2012 Masonry Team - https://github.com/Masonry 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Masonry/Masonry/MASCompositeConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASCompositeConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASConstraint.h" 10 | #import "MASUtilities.h" 11 | 12 | /** 13 | * A group of MASConstraint objects 14 | */ 15 | @interface MASCompositeConstraint : MASConstraint 16 | 17 | /** 18 | * Creates a composite with a predefined array of children 19 | * 20 | * @param children child MASConstraints 21 | * 22 | * @return a composite constraint 23 | */ 24 | - (id)initWithChildren:(NSArray *)children; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Masonry/Masonry/MASConstraint+Private.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASConstraint+Private.h 3 | // Masonry 4 | // 5 | // Created by Nick Tymchenko on 29/04/14. 6 | // Copyright (c) 2014 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASConstraint.h" 10 | 11 | @protocol MASConstraintDelegate; 12 | 13 | 14 | @interface MASConstraint () 15 | 16 | /** 17 | * Whether or not to check for an existing constraint instead of adding constraint 18 | */ 19 | @property (nonatomic, assign) BOOL updateExisting; 20 | 21 | /** 22 | * Usually MASConstraintMaker but could be a parent MASConstraint 23 | */ 24 | @property (nonatomic, weak) id delegate; 25 | 26 | /** 27 | * Based on a provided value type, is equal to calling: 28 | * NSNumber - setOffset: 29 | * NSValue with CGPoint - setPointOffset: 30 | * NSValue with CGSize - setSizeOffset: 31 | * NSValue with MASEdgeInsets - setInsets: 32 | */ 33 | - (void)setLayoutConstantWithValue:(NSValue *)value; 34 | 35 | @end 36 | 37 | 38 | @interface MASConstraint (Abstract) 39 | 40 | /** 41 | * Sets the constraint relation to given NSLayoutRelation 42 | * returns a block which accepts one of the following: 43 | * MASViewAttribute, UIView, NSValue, NSArray 44 | * see readme for more details. 45 | */ 46 | - (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation; 47 | 48 | /** 49 | * Override to set a custom chaining behaviour 50 | */ 51 | - (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute; 52 | 53 | @end 54 | 55 | 56 | @protocol MASConstraintDelegate 57 | 58 | /** 59 | * Notifies the delegate when the constraint needs to be replaced with another constraint. For example 60 | * A MASViewConstraint may turn into a MASCompositeConstraint when an array is passed to one of the equality blocks 61 | */ 62 | - (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint; 63 | 64 | - (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute; 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Masonry/Masonry/MASLayoutConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASLayoutConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * When you are debugging or printing the constraints attached to a view this subclass 13 | * makes it easier to identify which constraints have been created via Masonry 14 | */ 15 | @interface MASLayoutConstraint : NSLayoutConstraint 16 | 17 | /** 18 | * a key to associate with this constraint 19 | */ 20 | @property (nonatomic, strong) id mas_key; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Masonry/Masonry/MASLayoutConstraint.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASLayoutConstraint.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASLayoutConstraint.h" 10 | 11 | @implementation MASLayoutConstraint 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Masonry/Masonry/MASViewAttribute.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASViewAttribute.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * An immutable tuple which stores the view and the related NSLayoutAttribute. 13 | * Describes part of either the left or right hand side of a constraint equation 14 | */ 15 | @interface MASViewAttribute : NSObject 16 | 17 | /** 18 | * The view which the reciever relates to. Can be nil if item is not a view. 19 | */ 20 | @property (nonatomic, weak, readonly) MAS_VIEW *view; 21 | 22 | /** 23 | * The item which the reciever relates to. 24 | */ 25 | @property (nonatomic, weak, readonly) id item; 26 | 27 | /** 28 | * The attribute which the reciever relates to 29 | */ 30 | @property (nonatomic, assign, readonly) NSLayoutAttribute layoutAttribute; 31 | 32 | /** 33 | * Convenience initializer. 34 | */ 35 | - (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute; 36 | 37 | /** 38 | * The designated initializer. 39 | */ 40 | - (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute; 41 | 42 | /** 43 | * Determine whether the layoutAttribute is a size attribute 44 | * 45 | * @return YES if layoutAttribute is equal to NSLayoutAttributeWidth or NSLayoutAttributeHeight 46 | */ 47 | - (BOOL)isSizeAttribute; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Masonry/Masonry/MASViewAttribute.m: -------------------------------------------------------------------------------- 1 | // 2 | // MASViewAttribute.m 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 21/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASViewAttribute.h" 10 | 11 | @implementation MASViewAttribute 12 | 13 | - (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute { 14 | self = [self initWithView:view item:view layoutAttribute:layoutAttribute]; 15 | return self; 16 | } 17 | 18 | - (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute { 19 | self = [super init]; 20 | if (!self) return nil; 21 | 22 | _view = view; 23 | _item = item; 24 | _layoutAttribute = layoutAttribute; 25 | 26 | return self; 27 | } 28 | 29 | - (BOOL)isSizeAttribute { 30 | return self.layoutAttribute == NSLayoutAttributeWidth 31 | || self.layoutAttribute == NSLayoutAttributeHeight; 32 | } 33 | 34 | - (BOOL)isEqual:(MASViewAttribute *)viewAttribute { 35 | if ([viewAttribute isKindOfClass:self.class]) { 36 | return self.view == viewAttribute.view 37 | && self.layoutAttribute == viewAttribute.layoutAttribute; 38 | } 39 | return [super isEqual:viewAttribute]; 40 | } 41 | 42 | - (NSUInteger)hash { 43 | return MAS_NSUINTROTATE([self.view hash], MAS_NSUINT_BIT / 2) ^ self.layoutAttribute; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Masonry/Masonry/MASViewConstraint.h: -------------------------------------------------------------------------------- 1 | // 2 | // MASViewConstraint.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import "MASViewAttribute.h" 10 | #import "MASConstraint.h" 11 | #import "MASLayoutConstraint.h" 12 | #import "MASUtilities.h" 13 | 14 | /** 15 | * A single constraint. 16 | * Contains the attributes neccessary for creating a NSLayoutConstraint and adding it to the appropriate view 17 | */ 18 | @interface MASViewConstraint : MASConstraint 19 | 20 | /** 21 | * First item/view and first attribute of the NSLayoutConstraint 22 | */ 23 | @property (nonatomic, strong, readonly) MASViewAttribute *firstViewAttribute; 24 | 25 | /** 26 | * Second item/view and second attribute of the NSLayoutConstraint 27 | */ 28 | @property (nonatomic, strong, readonly) MASViewAttribute *secondViewAttribute; 29 | 30 | /** 31 | * initialises the MASViewConstraint with the first part of the equation 32 | * 33 | * @param firstViewAttribute view.mas_left, view.mas_width etc. 34 | * 35 | * @return a new view constraint 36 | */ 37 | - (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute; 38 | 39 | /** 40 | * Returns all MASViewConstraints installed with this view as a first item. 41 | * 42 | * @param view A view to retrieve constraints for. 43 | * 44 | * @return An array of MASViewConstraints. 45 | */ 46 | + (NSArray *)installedConstraintsForView:(MAS_VIEW *)view; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Masonry/Masonry/Masonry.h: -------------------------------------------------------------------------------- 1 | // 2 | // Masonry.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 20/07/13. 6 | // Copyright (c) 2013 cloudling. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Masonry. 12 | FOUNDATION_EXPORT double MasonryVersionNumber; 13 | 14 | //! Project version string for Masonry. 15 | FOUNDATION_EXPORT const unsigned char MasonryVersionString[]; 16 | 17 | #import "MASUtilities.h" 18 | #import "View+MASAdditions.h" 19 | #import "View+MASShorthandAdditions.h" 20 | #import "ViewController+MASAdditions.h" 21 | #import "NSArray+MASAdditions.h" 22 | #import "NSArray+MASShorthandAdditions.h" 23 | #import "MASConstraint.h" 24 | #import "MASCompositeConstraint.h" 25 | #import "MASViewAttribute.h" 26 | #import "MASViewConstraint.h" 27 | #import "MASConstraintMaker.h" 28 | #import "MASLayoutConstraint.h" 29 | #import "NSLayoutConstraint+MASDebugAdditions.h" 30 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Masonry/Masonry/NSArray+MASShorthandAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSArray+MASShorthandAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 22/07/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "NSArray+MASAdditions.h" 10 | 11 | #ifdef MAS_SHORTHAND 12 | 13 | /** 14 | * Shorthand array additions without the 'mas_' prefixes, 15 | * only enabled if MAS_SHORTHAND is defined 16 | */ 17 | @interface NSArray (MASShorthandAdditions) 18 | 19 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block; 20 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block; 21 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block; 22 | 23 | @end 24 | 25 | @implementation NSArray (MASShorthandAdditions) 26 | 27 | - (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block { 28 | return [self mas_makeConstraints:block]; 29 | } 30 | 31 | - (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *))block { 32 | return [self mas_updateConstraints:block]; 33 | } 34 | 35 | - (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block { 36 | return [self mas_remakeConstraints:block]; 37 | } 38 | 39 | @end 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Masonry/Masonry/NSLayoutConstraint+MASDebugAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSLayoutConstraint+MASDebugAdditions.h 3 | // Masonry 4 | // 5 | // Created by Jonas Budelmann on 3/08/13. 6 | // Copyright (c) 2013 Jonas Budelmann. All rights reserved. 7 | // 8 | 9 | #import "MASUtilities.h" 10 | 11 | /** 12 | * makes debug and log output of NSLayoutConstraints more readable 13 | */ 14 | @interface NSLayoutConstraint (MASDebugAdditions) 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Masonry/Masonry/ViewController+MASAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MASAdditions.h 3 | // Masonry 4 | // 5 | // Created by Craig Siemens on 2015-06-23. 6 | // 7 | // 8 | 9 | #import "MASUtilities.h" 10 | #import "MASConstraintMaker.h" 11 | #import "MASViewAttribute.h" 12 | 13 | #ifdef MAS_VIEW_CONTROLLER 14 | 15 | @interface MAS_VIEW_CONTROLLER (MASAdditions) 16 | 17 | /** 18 | * following properties return a new MASViewAttribute with appropriate UILayoutGuide and NSLayoutAttribute 19 | */ 20 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuide; 21 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuide; 22 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideTop; 23 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideBottom; 24 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideTop; 25 | @property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideBottom; 26 | 27 | 28 | @end 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Masonry/Masonry/ViewController+MASAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+MASAdditions.m 3 | // Masonry 4 | // 5 | // Created by Craig Siemens on 2015-06-23. 6 | // 7 | // 8 | 9 | #import "ViewController+MASAdditions.h" 10 | 11 | #ifdef MAS_VIEW_CONTROLLER 12 | 13 | @implementation MAS_VIEW_CONTROLLER (MASAdditions) 14 | 15 | - (MASViewAttribute *)mas_topLayoutGuide { 16 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 17 | } 18 | - (MASViewAttribute *)mas_topLayoutGuideTop { 19 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 20 | } 21 | - (MASViewAttribute *)mas_topLayoutGuideBottom { 22 | return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 23 | } 24 | 25 | - (MASViewAttribute *)mas_bottomLayoutGuide { 26 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 27 | } 28 | - (MASViewAttribute *)mas_bottomLayoutGuideTop { 29 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop]; 30 | } 31 | - (MASViewAttribute *)mas_bottomLayoutGuideBottom { 32 | return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeBottom]; 33 | } 34 | 35 | 36 | 37 | @end 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Pods.xcodeproj/xcuserdata/wangkun.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Masonry.xcscheme 8 | 9 | isShown 10 | 11 | orderHint 12 | 0 13 | 14 | Pods-WKViewManagerDemo.xcscheme 15 | 16 | isShown 17 | 18 | orderHint 19 | 1 20 | 21 | Pods-WKViewManagerDemoTests.xcscheme 22 | 23 | isShown 24 | 25 | orderHint 26 | 2 27 | 28 | Pods-WKViewManagerDemoUITests.xcscheme 29 | 30 | isShown 31 | 32 | orderHint 33 | 3 34 | 35 | 36 | SuppressBuildableAutocreation 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Masonry/Masonry-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Masonry : NSObject 3 | @end 4 | @implementation PodsDummy_Masonry 5 | @end 6 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Masonry/Masonry-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Masonry/Masonry.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Masonry 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/Masonry" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Masonry" 4 | OTHER_LDFLAGS = -framework "Foundation" -framework "UIKit" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Masonry 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Pods-WKViewManagerDemo/Pods-WKViewManagerDemo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## Masonry 5 | 6 | Copyright (c) 2011-2012 Masonry Team - https://github.com/Masonry 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | Generated by CocoaPods - https://cocoapods.org 26 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Pods-WKViewManagerDemo/Pods-WKViewManagerDemo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_WKViewManagerDemo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_WKViewManagerDemo 5 | @end 6 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Pods-WKViewManagerDemo/Pods-WKViewManagerDemo.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Masonry" 3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" 4 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/Masonry" 5 | OTHER_LDFLAGS = $(inherited) -ObjC -l"Masonry" -framework "Foundation" -framework "UIKit" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Pods-WKViewManagerDemo/Pods-WKViewManagerDemo.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Masonry" 3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" 4 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/Masonry" 5 | OTHER_LDFLAGS = $(inherited) -ObjC -l"Masonry" -framework "Foundation" -framework "UIKit" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Pods-WKViewManagerDemoTests/Pods-WKViewManagerDemoTests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Pods-WKViewManagerDemoTests/Pods-WKViewManagerDemoTests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Pods-WKViewManagerDemoTests/Pods-WKViewManagerDemoTests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_WKViewManagerDemoTests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_WKViewManagerDemoTests 5 | @end 6 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Pods-WKViewManagerDemoTests/Pods-WKViewManagerDemoTests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Masonry" 3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" 4 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/Masonry" 5 | OTHER_LDFLAGS = $(inherited) -ObjC -framework "Foundation" -framework "UIKit" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Pods-WKViewManagerDemoTests/Pods-WKViewManagerDemoTests.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Masonry" 3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" 4 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/Masonry" 5 | OTHER_LDFLAGS = $(inherited) -ObjC -framework "Foundation" -framework "UIKit" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Pods-WKViewManagerDemoUITests/Pods-WKViewManagerDemoUITests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Pods-WKViewManagerDemoUITests/Pods-WKViewManagerDemoUITests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Pods-WKViewManagerDemoUITests/Pods-WKViewManagerDemoUITests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_WKViewManagerDemoUITests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_WKViewManagerDemoUITests 5 | @end 6 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Pods-WKViewManagerDemoUITests/Pods-WKViewManagerDemoUITests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Masonry" 3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" 4 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/Masonry" 5 | OTHER_LDFLAGS = $(inherited) -ObjC -framework "Foundation" -framework "UIKit" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | -------------------------------------------------------------------------------- /WKViewManagerDemo/Pods/Target Support Files/Pods-WKViewManagerDemoUITests/Pods-WKViewManagerDemoUITests.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/Masonry" 3 | LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Masonry" 4 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/Masonry" 5 | OTHER_LDFLAGS = $(inherited) -ObjC -framework "Foundation" -framework "UIKit" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo.xcodeproj/project.xcworkspace/xcuserdata/wangkun.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WangKunKun/WKDemo/9915691c5fc1ff44b494fb7f91002252c5b6b714/WKViewManagerDemo/WKViewManagerDemo.xcodeproj/project.xcworkspace/xcuserdata/wangkun.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo.xcodeproj/xcuserdata/wangkun.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WKViewManagerDemo.xcscheme 8 | 9 | orderHint 10 | 4 11 | 12 | WKViewManagerDemo.xcscheme_^#shared#^_ 13 | 14 | orderHint 15 | 4 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo.xcworkspace/xcuserdata/wangkun.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WangKunKun/WKDemo/9915691c5fc1ff44b494fb7f91002252c5b6b714/WKViewManagerDemo/WKViewManagerDemo.xcworkspace/xcuserdata/wangkun.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WKViewManagerDemo 4 | // 5 | // Created by wangkun on 2018/6/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // WKViewManagerDemo 4 | // 5 | // Created by wangkun on 2018/6/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/BaseView/KMDeallocBlockExecutor.h: -------------------------------------------------------------------------------- 1 | // 2 | // KMDeallocBlockExecutor.h 3 | // KanManHua 4 | // 5 | // Created by Banning on 2017/11/14. 6 | // Copyright © 2017年 KanManHua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface KMDeallocBlockExecutor : NSObject 12 | 13 | + (instancetype)executorWithDeallocBlock:(void (^)(void))deallocBlock; 14 | 15 | @property (nonatomic, copy) void (^deallocBlock)(void); 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/BaseView/KMDeallocBlockExecutor.m: -------------------------------------------------------------------------------- 1 | // 2 | // KMDeallocBlockExecutor.m 3 | // KanManHua 4 | // 5 | // Created by Banning on 2017/11/14. 6 | // Copyright © 2017年 KanManHua. All rights reserved. 7 | // 8 | 9 | #import "KMDeallocBlockExecutor.h" 10 | 11 | @implementation KMDeallocBlockExecutor 12 | 13 | + (instancetype)executorWithDeallocBlock:(void (^)(void))deallocBlock { 14 | KMDeallocBlockExecutor *o = [KMDeallocBlockExecutor new]; 15 | o.deallocBlock = deallocBlock; 16 | return o; 17 | } 18 | 19 | - (void)dealloc { 20 | if (self.deallocBlock) { 21 | self.deallocBlock(); 22 | self.deallocBlock = nil; 23 | } 24 | } 25 | @end 26 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/BaseView/NSObject+DealBlock.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+DealBlock.h 3 | // KanManHua 4 | // 5 | // Created by Banning on 2017/11/14. 6 | // Copyright © 2017年 KanManHua. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WKHeader.h" 11 | 12 | 13 | @interface NSObject (DealBlock) 14 | 15 | - (id)addDealBlock:(voidClosure)deallocBlock; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/BaseView/NSObject+DealBlock.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+DealBlock.m 3 | // KanManHua 4 | // 5 | // Created by Banning on 2017/11/14. 6 | // Copyright © 2017年 KanManHua. All rights reserved. 7 | // 8 | #import "NSObject+DealBlock.h" 9 | #import "KMDeallocBlockExecutor.h" 10 | #import 11 | 12 | static void *kNSObject_DeallocBlocks; 13 | 14 | @implementation NSObject (DealBlock) 15 | 16 | - (id)addDealBlock:(voidClosure)deallocBlock { 17 | if (deallocBlock == nil) { 18 | return nil; 19 | } 20 | 21 | NSMutableArray *deallocBlocks = objc_getAssociatedObject(self, &kNSObject_DeallocBlocks); 22 | if (deallocBlocks == nil) { 23 | deallocBlocks = [NSMutableArray array]; 24 | objc_setAssociatedObject(self, &kNSObject_DeallocBlocks, deallocBlocks, OBJC_ASSOCIATION_RETAIN); 25 | } 26 | // Check if the block is already existed 27 | for (KMDeallocBlockExecutor *executor in deallocBlocks) { 28 | if (executor.deallocBlock == deallocBlock) { 29 | return nil; 30 | } 31 | } 32 | 33 | KMDeallocBlockExecutor *executor = [KMDeallocBlockExecutor executorWithDeallocBlock:deallocBlock]; 34 | [deallocBlocks addObject:executor]; 35 | return executor; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/BaseView/UIViewController+ViewManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+ViewManager.h 3 | // MKWeekly 4 | // 5 | // Created by wangkun on 2018/5/23. 6 | // Copyright © 2018年 zymk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIViewController (ViewManager) 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/BaseView/WKPopBaseView.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKPopBaseView.h 3 | // MKWeekly 4 | // 5 | // Created by wangkun on 2017/8/2. 6 | // Copyright © 2017年 zymk. All rights reserved. 7 | // 8 | 9 | #import "WKBaseView.h" 10 | 11 | @interface WKPopBaseView : WKBaseView 12 | 13 | @property (nonatomic, strong) UIView * contentView; 14 | 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/BaseView/WKViewManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKViewManager.h 3 | // KanManHua 4 | // 5 | // Created by wangkun on 2017/11/8. 6 | // Copyright © 2017年 KanManHua. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WKBaseView.h" 11 | 12 | @interface WKViewManager : NSObject 13 | 14 | + (instancetype)sharedManager; 15 | ///存在黑白名单机制,有可能无法进入队列 16 | + (WKViewEnterQueueState)addOperationWithView:(WKBaseView *)view; 17 | //在vc willappear中调用 已写入运行时 18 | + (void)showWaitViewWithVC:(UIViewController *)vc; 19 | ///vc dealloc时 调用,已写入 运行时类目中 20 | + (void)canclAllOperationWithVC:(UIViewController *)vc; 21 | //vcWillDissAppear时调用 暂停队列 22 | + (void)suspendQueueWithObj:(NSObject *)obj; 23 | //vcWillAppear时调用 让暂停队列启动 24 | + (void)continueQueueWithObj:(NSObject *)obj; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/DetailPageVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // DetailPageVC.h 3 | // WKViewManagerDemo 4 | // 5 | // Created by wangkun on 2018/6/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DetailPageVC : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/DetailPageVC.m: -------------------------------------------------------------------------------- 1 | // 2 | // DetailPageVC.m 3 | // WKViewManagerDemo 4 | // 5 | // Created by wangkun on 2018/6/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "DetailPageVC.h" 10 | #import "WKOtherView.h" 11 | @interface DetailPageVC () 12 | 13 | @end 14 | 15 | @implementation DetailPageVC 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | } 21 | 22 | - (void)didReceiveMemoryWarning { 23 | [super didReceiveMemoryWarning]; 24 | // Dispose of any resources that can be recreated. 25 | } 26 | - (IBAction)showView:(id)sender { 27 | WKOtherView * v = [[WKOtherView alloc] init]; 28 | v.title = @"This is Other View Must Show in home page"; 29 | [v showInView:self.view isShow:YES]; 30 | } 31 | - (IBAction)dismiss:(id)sender { 32 | [self dismissViewControllerAnimated:YES completion:nil]; 33 | } 34 | 35 | /* 36 | #pragma mark - Navigation 37 | 38 | // In a storyboard-based application, you will often want to do a little preparation before navigation 39 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 40 | // Get the new view controller using [segue destinationViewController]. 41 | // Pass the selected object to the new view controller. 42 | } 43 | */ 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/HomePageVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // WKViewManagerDemo 4 | // 5 | // Created by wangkun on 2018/6/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface HomePageVC : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/HomePageVC.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // WKViewManagerDemo 4 | // 5 | // Created by wangkun on 2018/6/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "HomePageVC.h" 10 | #import "WKTestView.h" 11 | @interface HomePageVC () 12 | 13 | @end 14 | 15 | @implementation HomePageVC 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view, typically from a nib. 20 | } 21 | 22 | 23 | - (void)didReceiveMemoryWarning { 24 | [super didReceiveMemoryWarning]; 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | - (IBAction)showView:(id)sender { 29 | WKTestView * v = [[WKTestView alloc] init]; 30 | v.title = @"This is Test View can not show in HomePage"; 31 | [v showInView:self.view isShow:YES]; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/WKHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKHeader.h 3 | // Study 4 | // 5 | // Created by wangkun on 2018/6/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #ifndef WKHeader_h 10 | #define WKHeader_h 11 | 12 | typedef void(^voidClosure)(void); 13 | #define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width) 14 | #define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height) 15 | 16 | #import 17 | 18 | #endif /* WKHeader_h */ 19 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/WKOtherView.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKOtherView.h 3 | // Study 4 | // 5 | // Created by wangkun on 2018/6/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "WKTestView.h" 10 | 11 | @interface WKOtherView : WKTestView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/WKOtherView.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKOtherView.m 3 | // Study 4 | // 5 | // Created by wangkun on 2018/6/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "WKOtherView.h" 10 | 11 | @implementation WKOtherView 12 | 13 | 14 | - (void)setInterFace 15 | { 16 | [super setInterFace]; 17 | 18 | self.titleLabel.textColor = [UIColor redColor]; 19 | } 20 | 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/WKTestView.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKTestView.h 3 | // Study 4 | // 5 | // Created by wangkun on 2018/6/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "WKPopBaseView.h" 10 | 11 | @interface WKTestView : WKPopBaseView 12 | 13 | @property (nonatomic, strong) NSString * title; 14 | @property (nonatomic, strong, readonly) UILabel * titleLabel; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/WKTestView.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKTestView.m 3 | // Study 4 | // 5 | // Created by wangkun on 2018/6/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "WKTestView.h" 10 | 11 | @interface WKTestView () 12 | 13 | @property (nonatomic, strong) UILabel * titleLabel; 14 | 15 | @end 16 | 17 | @implementation WKTestView 18 | 19 | 20 | - (void)setInterFace 21 | { 22 | [super setInterFace]; 23 | 24 | [self.contentView addSubview:self.titleLabel]; 25 | [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { 26 | make.edges.equalTo(self.contentView); 27 | }]; 28 | 29 | //TODO contentview的高度必须设置 30 | [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) { 31 | make.centerX.equalTo(self); 32 | make.centerY.equalTo(self).offset(SCREEN_HEIGHT); 33 | make.width.height.equalTo(@200); 34 | }]; 35 | } 36 | 37 | - (UILabel *)titleLabel 38 | { 39 | if (!_titleLabel) { 40 | _titleLabel = [UILabel new]; 41 | _titleLabel.font = [UIFont systemFontOfSize:15]; 42 | _titleLabel.textColor = [UIColor blackColor]; 43 | _titleLabel.numberOfLines = 0; 44 | } 45 | return _titleLabel; 46 | } 47 | 48 | - (void)updateContentViewConstraint:(BOOL)isShow 49 | { 50 | [self.contentView mas_updateConstraints:^(MASConstraintMaker *make) { 51 | make.centerY.equalTo(self).offset(isShow ? 0 : SCREEN_HEIGHT); 52 | }]; 53 | } 54 | 55 | - (void)setTitle:(NSString *)title 56 | { 57 | _title = title; 58 | self.titleLabel.text = title; 59 | } 60 | /* 61 | // Only override drawRect: if you perform custom drawing. 62 | // An empty implementation adversely affects performance during animation. 63 | - (void)drawRect:(CGRect)rect { 64 | // Drawing code 65 | } 66 | */ 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/WKViewManagerHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKViewManagerHeader.h 3 | // WKViewManagerDemo 4 | // 5 | // Created by wangkun on 2018/12/21. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #ifndef WKViewManagerHeader_h 10 | #define WKViewManagerHeader_h 11 | #imprt "UIViewController+ViewManager.h" 12 | #imprt "WKPopBaseView.h" 13 | #imprt "WKViewManager.h" 14 | #endif /* WKViewManagerHeader_h */ 15 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WKViewManagerDemo 4 | // 5 | // Created by wangkun on 2018/6/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemoTests/WKViewManagerDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKViewManagerDemoTests.m 3 | // WKViewManagerDemoTests 4 | // 5 | // Created by wangkun on 2018/6/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WKViewManagerDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation WKViewManagerDemoTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemoUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /WKViewManagerDemo/WKViewManagerDemoUITests/WKViewManagerDemoUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKViewManagerDemoUITests.m 3 | // WKViewManagerDemoUITests 4 | // 5 | // Created by wangkun on 2018/6/8. 6 | // Copyright © 2018年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WKViewManagerDemoUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation WKViewManagerDemoUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter.xcodeproj/project.xcworkspace/xcuserdata/wangkun.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WangKunKun/WKDemo/9915691c5fc1ff44b494fb7f91002252c5b6b714/exchangeSetter/exchangeSetter.xcodeproj/project.xcworkspace/xcuserdata/wangkun.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter.xcodeproj/xcuserdata/wangkun.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter.xcodeproj/xcuserdata/wangkun.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | exchangeSetter.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | EA9FC0011FAD70B400454D34 16 | 17 | primary 18 | 19 | 20 | EA9FC01A1FAD70B400454D34 21 | 22 | primary 23 | 24 | 25 | EA9FC0251FAD70B400454D34 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/4. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/4. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/KMDeallocBlockExecutor.h: -------------------------------------------------------------------------------- 1 | // 2 | // KMDeallocBlockExecutor.h 3 | // KanManHua 4 | // 5 | // Created by wangkun on 2017/11/14. 6 | // Copyright © 2017年 - -. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface KMDeallocBlockExecutor : NSObject 12 | 13 | + (instancetype)executorWithDeallocBlock:(void (^)())deallocBlock; 14 | 15 | @property (nonatomic, copy) void (^deallocBlock)(); 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/KMDeallocBlockExecutor.m: -------------------------------------------------------------------------------- 1 | // 2 | // KMDeallocBlockExecutor.m 3 | // KanManHua 4 | // 5 | // Created by wangkun on 2017/11/14. 6 | // Copyright © 2017年 - -. All rights reserved. 7 | // 8 | 9 | #import "KMDeallocBlockExecutor.h" 10 | 11 | @implementation KMDeallocBlockExecutor 12 | 13 | + (instancetype)executorWithDeallocBlock:(void (^)(void))deallocBlock { 14 | KMDeallocBlockExecutor *o = [KMDeallocBlockExecutor new]; 15 | o.deallocBlock = deallocBlock; 16 | return o; 17 | } 18 | 19 | - (void)dealloc { 20 | if (self.deallocBlock) { 21 | self.deallocBlock(); 22 | self.deallocBlock = nil; 23 | } 24 | } 25 | @end 26 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/NSObject+DataBase.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+DataBase.h 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/12/18. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "NSObject+DealBlock.h" 11 | 12 | #define WKDataBaseSetter \ 13 | + (void)load \ 14 | { \ 15 | [self wk_exchangeSetter]; \ 16 | } \ 17 | 18 | 19 | @interface NSObject (DataBase) 20 | @property (nonatomic, assign) NSTimeInterval saveiIntervaltime; 21 | @property (nonatomic, strong, readonly) NSMutableDictionary * saveKeyValue; 22 | 23 | + (void)wk_exchangeSetter; 24 | //数据库主key 主键不能被忽略 25 | + (NSArray *)DBMainKey; 26 | //数据库需要忽略存储的属性(不写入表) 主键不能被忽略 27 | + (NSArray *)ignoreProperty; 28 | 29 | //主键是否可为空 特殊情形,一个模型对应多种情况,每一种情况对应主键不同,但是写表需要全部写入,因为在一个模型里,设计问题 30 | //默认NO 31 | + (BOOL)DBMainKeyCanBeEmpty; 32 | 33 | //调用FMDB 可重写 34 | - (void)saveToLocal; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/NSObject+DealBlock.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+DealBlock.h 3 | // KanManHua 4 | // 5 | // Created by Wangkun on 2017/11/14. 6 | // Copyright © 2017年 - -. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (DealBlock) 12 | 13 | - (id)addDeallocBlock:(void (^)())deallocBlock; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/NSObject+DealBlock.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+DealBlock.m 3 | // KanManHua 4 | // 5 | // Created by Wangkun on 2017/11/14. 6 | // Copyright © 2017年 - -. All rights reserved. 7 | // 8 | #import "NSObject+DealBlock.h" 9 | #import "KMDeallocBlockExecutor.h" 10 | #import 11 | 12 | static void *kNSObject_DeallocBlocks; 13 | 14 | @implementation NSObject (DealBlock) 15 | 16 | - (id)addDeallocBlock:(void (^)())deallocBlock { 17 | if (deallocBlock == nil) { 18 | return nil; 19 | } 20 | 21 | NSMutableArray *deallocBlocks = objc_getAssociatedObject(self, &kNSObject_DeallocBlocks); 22 | if (deallocBlocks == nil) { 23 | deallocBlocks = [NSMutableArray array]; 24 | objc_setAssociatedObject(self, &kNSObject_DeallocBlocks, deallocBlocks, OBJC_ASSOCIATION_RETAIN); 25 | } 26 | // Check if the block is already existed 27 | for (KMDeallocBlockExecutor *executor in deallocBlocks) { 28 | if (executor.deallocBlock == deallocBlock) { 29 | return nil; 30 | } 31 | } 32 | 33 | KMDeallocBlockExecutor *executor = [KMDeallocBlockExecutor executorWithDeallocBlock:deallocBlock]; 34 | [deallocBlocks addObject:executor]; 35 | return executor; 36 | } 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/UserModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // UserModel.h 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/4. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "NSObject+DataBase.h" 11 | 12 | 13 | @interface UserModel : NSObject 14 | 15 | @property (nonatomic, strong) NSString * userName; 16 | @property (nonatomic, assign) NSUInteger userID; 17 | @property (nonatomic, assign) BOOL isGirl; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/UserModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // UserModel.m 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/4. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "UserModel.h" 10 | 11 | 12 | @interface UserModel () 13 | 14 | @property (nonatomic, strong) NSString * userDetail; 15 | 16 | @end 17 | 18 | @implementation UserModel 19 | 20 | WKDataBaseSetter 21 | 22 | - (void)setUserID:(NSUInteger)userID 23 | { 24 | _userID = userID; 25 | NSLog(@"修改userid"); 26 | } 27 | 28 | - (void)setUserName:(NSString *)userName 29 | { 30 | _userName = userName; 31 | NSLog(@"修改username"); 32 | } 33 | 34 | + (NSArray *)DBMainKey 35 | { 36 | return @[@"userID"]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/4. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/4. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "UserModel.h" 11 | @interface ViewController () 12 | 13 | @property (nonatomic, strong) UIView * aa; 14 | 15 | @end 16 | 17 | @implementation ViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | // Do any additional setup after loading the view, typically from a nib. 22 | __block UserModel * model = [UserModel new]; 23 | model.userID = 123; 24 | model.userName = @"aaa"; 25 | model.isGirl = YES; 26 | NSLog(@"%@,%ld,%ld",model.userName,model.userID,model.isGirl); 27 | _aa = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)]; 28 | _aa.backgroundColor = [UIColor redColor]; 29 | [self.view addSubview:_aa]; 30 | 31 | 32 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 33 | model = nil; 34 | }); 35 | } 36 | 37 | - (void)didReceiveMemoryWarning { 38 | [super didReceiveMemoryWarning]; 39 | // Dispose of any resources that can be recreated. 40 | } 41 | 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/WKClassManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKClassPropertyManager.h 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/4. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WKClassPropertyModel.h" 11 | #import "WKClassMethodModel.h" 12 | @interface WKClassManager : NSObject 13 | 14 | + (NSArray *)getClassPropertysWithClass:(Class)classs; 15 | + (NSArray *)getClassMethodsWithClass:(Class)classs; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/WKClassMethodModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKClassMethodModel.h 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/9. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @interface WKClassMethodModel : NSObject 12 | 13 | @property (nonatomic, strong) NSString * name; 14 | @property (nonatomic, assign) IMP oldIMP; 15 | @property (nonatomic, assign) Method method; 16 | + (instancetype)createClassMethodModelWithMethod:(Method)property; 17 | 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/WKClassMethodModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // WKClassMethodModel.m 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/9. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "WKClassMethodModel.h" 10 | 11 | @implementation WKClassMethodModel 12 | 13 | + (instancetype)createClassMethodModelWithMethod:(Method)method 14 | { 15 | WKClassMethodModel * model = [self new]; 16 | model.name = NSStringFromSelector(method_getName(method)); 17 | model.oldIMP = method_getImplementation(method); 18 | model.method = method; 19 | return model; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/WKClassPropertyModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKClassPropertyModel.h 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/4. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | typedef enum : NSUInteger { 13 | WKPropertyType_Object, 14 | WKPropertyType_CNumber, 15 | WKPropertyType_Unknown, 16 | } WKPropertyType; 17 | 18 | @interface WKClassPropertyModel : NSObject 19 | 20 | @property (nonatomic, strong) NSString * setterName; 21 | @property (nonatomic, strong) NSString * getterName; 22 | @property (nonatomic, strong) NSString * varName; 23 | @property (nonatomic, strong) NSString * typeName; 24 | @property (nonatomic, assign) WKPropertyType type; 25 | 26 | @property (nonatomic, strong) NSString * name; 27 | @property (nonatomic, assign) IMP oldsetterIMP; 28 | 29 | + (instancetype)createClassPropertyModelWithProperty:(objc_property_t)property; 30 | 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetter/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // exchangeSetter 4 | // 5 | // Created by wangkun on 2017/11/4. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetterTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetterTests/exchangeSetterTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // exchangeSetterTests.m 3 | // exchangeSetterTests 4 | // 5 | // Created by wangkun on 2017/11/4. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface exchangeSetterTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation exchangeSetterTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetterUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /exchangeSetter/exchangeSetterUITests/exchangeSetterUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // exchangeSetterUITests.m 3 | // exchangeSetterUITests 4 | // 5 | // Created by wangkun on 2017/11/4. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface exchangeSetterUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation exchangeSetterUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /searchKeyChangeColor/README.MD: -------------------------------------------------------------------------------- 1 | #关键字变色Demo-支持中文全拼以及首字母匹配 2 | 3 | [详情介绍地址](https://www.jianshu.com/p/727b6016b33d) -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColor.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColor.xcodeproj/project.xcworkspace/xcuserdata/wangkun.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WangKunKun/WKDemo/9915691c5fc1ff44b494fb7f91002252c5b6b714/searchKeyChangeColor/searchKeyChangeColor.xcodeproj/project.xcworkspace/xcuserdata/wangkun.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColor.xcodeproj/xcuserdata/wangkun.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColor.xcodeproj/xcuserdata/wangkun.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | searchKeyChangeColor.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColor/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // searchKeyChangeColor 4 | // 5 | // Created by wangkun on 2017/12/26. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColor/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // searchKeyChangeColor 4 | // 5 | // Created by wangkun on 2017/12/26. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColor/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColor/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColor/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColor/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColor/NSString+WKExtend.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+WKExtend.h 3 | // searchKeyChangeColor 4 | // 5 | // Created by wangkun on 2017/12/26. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | typedef void(^PYDictBlock)(NSDictionary *,BOOL isJustChinese); 11 | 12 | @interface NSString (WKExtend) 13 | - (NSArray *)getAllRangeOfString:(NSString *)searchString; 14 | + (NSString *)transform:(NSString *)chinese; 15 | + (NSString *)changeChineseToPinYin:(NSString *)str block:(PYDictBlock)dictBlock; 16 | + (NSString *)changeChineseToPinYinFirstLetter:(NSString *)str; 17 | + (BOOL)IsChineseForString:(NSString *)string; 18 | @end 19 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColor/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // searchKeyChangeColor 4 | // 5 | // Created by wangkun on 2017/12/26. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColor/WKSearchStringManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // WKSearchStringManager.h 3 | // MKWeekly 4 | // 5 | // Created by wangkun on 2017/12/26. 6 | // Copyright © 2017年 zymk. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WKSearchStringManager : NSObject 12 | + (instancetype)sharedSearchStringManager; 13 | @property (nonatomic, strong) NSString * searchStr; 14 | @property (nonatomic, strong) NSString * sourceStr; 15 | - (NSMutableArray *)matching; 16 | @end 17 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColor/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // searchKeyChangeColor 4 | // 5 | // Created by wangkun on 2017/12/26. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColorTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColorTests/searchKeyChangeColorTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // searchKeyChangeColorTests.m 3 | // searchKeyChangeColorTests 4 | // 5 | // Created by wangkun on 2017/12/26. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface searchKeyChangeColorTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation searchKeyChangeColorTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColorUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /searchKeyChangeColor/searchKeyChangeColorUITests/searchKeyChangeColorUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // searchKeyChangeColorUITests.m 3 | // searchKeyChangeColorUITests 4 | // 5 | // Created by wangkun on 2017/12/26. 6 | // Copyright © 2017年 wangkun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface searchKeyChangeColorUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation searchKeyChangeColorUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | --------------------------------------------------------------------------------