├── .gitignore ├── METhemeKit.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── METhemeKit ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── Default │ │ ├── Contents.json │ │ └── avatar.imageset │ │ │ ├── 10187156,1920,1080.png │ │ │ └── Contents.json │ └── Year │ │ ├── Contents.json │ │ ├── navigationBarShadowImage339.imageset │ │ ├── Contents.json │ │ └── navigationBarShadowImage339@2x.png │ │ └── year_avatar.imageset │ │ ├── 10271405,1920,1080.png │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── BaseNavViewController.h ├── BaseNavViewController.m ├── BaseViewController.h ├── BaseViewController.m ├── FirstViewController.h ├── FirstViewController.m ├── Info.plist ├── METhemeKit │ ├── Core │ │ ├── CALayer+Theme.h │ │ ├── CALayer+Theme.m │ │ ├── METhemeManager.h │ │ ├── METhemeManager.m │ │ ├── NSObject+Theme.h │ │ ├── NSObject+Theme.m │ │ ├── ThemeProperties.h │ │ ├── UIColor+Theme.h │ │ ├── UIColor+Theme.m │ │ ├── UIImage+Theme.h │ │ └── UIImage+Theme.m │ ├── DeallocBlock │ │ ├── MEDeallocBlockExecutor.h │ │ ├── MEDeallocBlockExecutor.m │ │ ├── NSObject+DeallocBlock.h │ │ └── NSObject+DeallocBlock.m │ ├── METhemeKit.h │ ├── ThemeData │ │ ├── ThemeDefault.json │ │ └── ThemeOrange.json │ └── ThemeUIKit │ │ ├── UIButton+Theme.h │ │ ├── UIButton+Theme.m │ │ ├── UIImageView+Theme.h │ │ ├── UIImageView+Theme.m │ │ ├── UILabel+Theme.h │ │ ├── UILabel+Theme.m │ │ ├── UINavigationBar+Theme.h │ │ ├── UINavigationBar+Theme.m │ │ ├── UIView+Theme.h │ │ └── UIView+Theme.m ├── SecondViewController.h ├── SecondViewController.m └── Supporting Files │ └── main.m ├── METhemeKitTests ├── Info.plist └── METhemeKitTests.m ├── METhemeKitUITests ├── Info.plist └── METhemeKitUITests.m └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata 19 | 20 | ## Other 21 | *.xccheckout 22 | *.moved-aside 23 | *.xcuserstate 24 | *.xcscmblueprint 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | -------------------------------------------------------------------------------- /METhemeKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 849DD4D11C89889100772BE1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD4D01C89889100772BE1 /* main.m */; }; 11 | 849DD4D41C89889100772BE1 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD4D31C89889100772BE1 /* AppDelegate.m */; }; 12 | 849DD4DA1C89889100772BE1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 849DD4D81C89889100772BE1 /* Main.storyboard */; }; 13 | 849DD4DC1C89889100772BE1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 849DD4DB1C89889100772BE1 /* Assets.xcassets */; }; 14 | 849DD4DF1C89889100772BE1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 849DD4DD1C89889100772BE1 /* LaunchScreen.storyboard */; }; 15 | 849DD4EA1C89889200772BE1 /* METhemeKitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD4E91C89889200772BE1 /* METhemeKitTests.m */; }; 16 | 849DD4F51C89889200772BE1 /* METhemeKitUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD4F41C89889200772BE1 /* METhemeKitUITests.m */; }; 17 | 849DD52A1C8988D000772BE1 /* METhemeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD5071C8988D000772BE1 /* METhemeManager.m */; }; 18 | 849DD52B1C8988D000772BE1 /* NSObject+Theme.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD5091C8988D000772BE1 /* NSObject+Theme.m */; }; 19 | 849DD52C1C8988D000772BE1 /* UIColor+Theme.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD50C1C8988D000772BE1 /* UIColor+Theme.m */; }; 20 | 849DD52D1C8988D000772BE1 /* UIImage+Theme.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD50E1C8988D000772BE1 /* UIImage+Theme.m */; }; 21 | 849DD52E1C8988D000772BE1 /* ThemeDefault.json in Resources */ = {isa = PBXBuildFile; fileRef = 849DD5111C8988D000772BE1 /* ThemeDefault.json */; }; 22 | 849DD52F1C8988D000772BE1 /* ThemeOrange.json in Resources */ = {isa = PBXBuildFile; fileRef = 849DD5121C8988D000772BE1 /* ThemeOrange.json */; }; 23 | 849DD5311C8988D000772BE1 /* CALayer+Theme.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD5171C8988D000772BE1 /* CALayer+Theme.m */; }; 24 | 849DD5341C8988D000772BE1 /* UIButton+Theme.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD51D1C8988D000772BE1 /* UIButton+Theme.m */; }; 25 | 849DD5351C8988D000772BE1 /* UIImageView+Theme.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD51F1C8988D000772BE1 /* UIImageView+Theme.m */; }; 26 | 849DD5361C8988D000772BE1 /* UILabel+Theme.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD5211C8988D000772BE1 /* UILabel+Theme.m */; }; 27 | 849DD5371C8988D000772BE1 /* UINavigationBar+Theme.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD5231C8988D000772BE1 /* UINavigationBar+Theme.m */; }; 28 | 849DD5381C8988D000772BE1 /* UIView+Theme.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD5251C8988D000772BE1 /* UIView+Theme.m */; }; 29 | 849DD5431C8997DE00772BE1 /* FirstViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD5421C8997DE00772BE1 /* FirstViewController.m */; }; 30 | 849DD5461C8997ED00772BE1 /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 849DD5451C8997ED00772BE1 /* SecondViewController.m */; }; 31 | 849E44D51C8D211C00397F6F /* BaseNavViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 849E44D41C8D211C00397F6F /* BaseNavViewController.m */; }; 32 | 849E44D81C8D233E00397F6F /* BaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 849E44D71C8D233E00397F6F /* BaseViewController.m */; }; 33 | 849E44DC1C8D27C300397F6F /* NSObject+DeallocBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 849E44DB1C8D27C300397F6F /* NSObject+DeallocBlock.m */; }; 34 | 849E44DF1C8D2B5A00397F6F /* MEDeallocBlockExecutor.m in Sources */ = {isa = PBXBuildFile; fileRef = 849E44DE1C8D2B5A00397F6F /* MEDeallocBlockExecutor.m */; }; 35 | /* End PBXBuildFile section */ 36 | 37 | /* Begin PBXContainerItemProxy section */ 38 | 849DD4E61C89889200772BE1 /* PBXContainerItemProxy */ = { 39 | isa = PBXContainerItemProxy; 40 | containerPortal = 849DD4C41C89889100772BE1 /* Project object */; 41 | proxyType = 1; 42 | remoteGlobalIDString = 849DD4CB1C89889100772BE1; 43 | remoteInfo = METhemeKit; 44 | }; 45 | 849DD4F11C89889200772BE1 /* PBXContainerItemProxy */ = { 46 | isa = PBXContainerItemProxy; 47 | containerPortal = 849DD4C41C89889100772BE1 /* Project object */; 48 | proxyType = 1; 49 | remoteGlobalIDString = 849DD4CB1C89889100772BE1; 50 | remoteInfo = METhemeKit; 51 | }; 52 | /* End PBXContainerItemProxy section */ 53 | 54 | /* Begin PBXFileReference section */ 55 | 849DD4CC1C89889100772BE1 /* METhemeKit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = METhemeKit.app; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | 849DD4D01C89889100772BE1 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 57 | 849DD4D21C89889100772BE1 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 58 | 849DD4D31C89889100772BE1 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 59 | 849DD4D91C89889100772BE1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 60 | 849DD4DB1C89889100772BE1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 61 | 849DD4DE1C89889100772BE1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 62 | 849DD4E01C89889100772BE1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 63 | 849DD4E51C89889200772BE1 /* METhemeKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = METhemeKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 64 | 849DD4E91C89889200772BE1 /* METhemeKitTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = METhemeKitTests.m; sourceTree = ""; }; 65 | 849DD4EB1C89889200772BE1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 66 | 849DD4F01C89889200772BE1 /* METhemeKitUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = METhemeKitUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 67 | 849DD4F41C89889200772BE1 /* METhemeKitUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = METhemeKitUITests.m; sourceTree = ""; }; 68 | 849DD4F61C89889200772BE1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 69 | 849DD5061C8988D000772BE1 /* METhemeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = METhemeManager.h; sourceTree = ""; }; 70 | 849DD5071C8988D000772BE1 /* METhemeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = METhemeManager.m; sourceTree = ""; }; 71 | 849DD5081C8988D000772BE1 /* NSObject+Theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+Theme.h"; sourceTree = ""; }; 72 | 849DD5091C8988D000772BE1 /* NSObject+Theme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+Theme.m"; sourceTree = ""; }; 73 | 849DD50A1C8988D000772BE1 /* ThemeProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThemeProperties.h; sourceTree = ""; }; 74 | 849DD50B1C8988D000772BE1 /* UIColor+Theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+Theme.h"; sourceTree = ""; }; 75 | 849DD50C1C8988D000772BE1 /* UIColor+Theme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+Theme.m"; sourceTree = ""; }; 76 | 849DD50D1C8988D000772BE1 /* UIImage+Theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Theme.h"; sourceTree = ""; }; 77 | 849DD50E1C8988D000772BE1 /* UIImage+Theme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Theme.m"; sourceTree = ""; }; 78 | 849DD50F1C8988D000772BE1 /* METhemeKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = METhemeKit.h; sourceTree = ""; }; 79 | 849DD5111C8988D000772BE1 /* ThemeDefault.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ThemeDefault.json; sourceTree = ""; }; 80 | 849DD5121C8988D000772BE1 /* ThemeOrange.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = ThemeOrange.json; sourceTree = ""; }; 81 | 849DD5161C8988D000772BE1 /* CALayer+Theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CALayer+Theme.h"; sourceTree = ""; }; 82 | 849DD5171C8988D000772BE1 /* CALayer+Theme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CALayer+Theme.m"; sourceTree = ""; }; 83 | 849DD51C1C8988D000772BE1 /* UIButton+Theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIButton+Theme.h"; sourceTree = ""; }; 84 | 849DD51D1C8988D000772BE1 /* UIButton+Theme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIButton+Theme.m"; sourceTree = ""; }; 85 | 849DD51E1C8988D000772BE1 /* UIImageView+Theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImageView+Theme.h"; sourceTree = ""; }; 86 | 849DD51F1C8988D000772BE1 /* UIImageView+Theme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImageView+Theme.m"; sourceTree = ""; }; 87 | 849DD5201C8988D000772BE1 /* UILabel+Theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UILabel+Theme.h"; sourceTree = ""; }; 88 | 849DD5211C8988D000772BE1 /* UILabel+Theme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UILabel+Theme.m"; sourceTree = ""; }; 89 | 849DD5221C8988D000772BE1 /* UINavigationBar+Theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UINavigationBar+Theme.h"; sourceTree = ""; }; 90 | 849DD5231C8988D000772BE1 /* UINavigationBar+Theme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UINavigationBar+Theme.m"; sourceTree = ""; }; 91 | 849DD5241C8988D000772BE1 /* UIView+Theme.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Theme.h"; sourceTree = ""; }; 92 | 849DD5251C8988D000772BE1 /* UIView+Theme.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Theme.m"; sourceTree = ""; }; 93 | 849DD5411C8997DE00772BE1 /* FirstViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FirstViewController.h; sourceTree = ""; }; 94 | 849DD5421C8997DE00772BE1 /* FirstViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FirstViewController.m; sourceTree = ""; }; 95 | 849DD5441C8997ED00772BE1 /* SecondViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecondViewController.h; sourceTree = ""; }; 96 | 849DD5451C8997ED00772BE1 /* SecondViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; }; 97 | 849E44D31C8D211C00397F6F /* BaseNavViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BaseNavViewController.h; sourceTree = ""; }; 98 | 849E44D41C8D211C00397F6F /* BaseNavViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BaseNavViewController.m; sourceTree = ""; }; 99 | 849E44D61C8D233E00397F6F /* BaseViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BaseViewController.h; sourceTree = ""; }; 100 | 849E44D71C8D233E00397F6F /* BaseViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BaseViewController.m; sourceTree = ""; }; 101 | 849E44DA1C8D27C300397F6F /* NSObject+DeallocBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+DeallocBlock.h"; sourceTree = ""; }; 102 | 849E44DB1C8D27C300397F6F /* NSObject+DeallocBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+DeallocBlock.m"; sourceTree = ""; }; 103 | 849E44DD1C8D2B5A00397F6F /* MEDeallocBlockExecutor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MEDeallocBlockExecutor.h; sourceTree = ""; }; 104 | 849E44DE1C8D2B5A00397F6F /* MEDeallocBlockExecutor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MEDeallocBlockExecutor.m; sourceTree = ""; }; 105 | /* End PBXFileReference section */ 106 | 107 | /* Begin PBXFrameworksBuildPhase section */ 108 | 849DD4C91C89889100772BE1 /* Frameworks */ = { 109 | isa = PBXFrameworksBuildPhase; 110 | buildActionMask = 2147483647; 111 | files = ( 112 | ); 113 | runOnlyForDeploymentPostprocessing = 0; 114 | }; 115 | 849DD4E21C89889200772BE1 /* Frameworks */ = { 116 | isa = PBXFrameworksBuildPhase; 117 | buildActionMask = 2147483647; 118 | files = ( 119 | ); 120 | runOnlyForDeploymentPostprocessing = 0; 121 | }; 122 | 849DD4ED1C89889200772BE1 /* Frameworks */ = { 123 | isa = PBXFrameworksBuildPhase; 124 | buildActionMask = 2147483647; 125 | files = ( 126 | ); 127 | runOnlyForDeploymentPostprocessing = 0; 128 | }; 129 | /* End PBXFrameworksBuildPhase section */ 130 | 131 | /* Begin PBXGroup section */ 132 | 849DD4C31C89889100772BE1 = { 133 | isa = PBXGroup; 134 | children = ( 135 | 849DD4CE1C89889100772BE1 /* METhemeKit */, 136 | 849DD4E81C89889200772BE1 /* METhemeKitTests */, 137 | 849DD4F31C89889200772BE1 /* METhemeKitUITests */, 138 | 849DD4CD1C89889100772BE1 /* Products */, 139 | ); 140 | sourceTree = ""; 141 | }; 142 | 849DD4CD1C89889100772BE1 /* Products */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 849DD4CC1C89889100772BE1 /* METhemeKit.app */, 146 | 849DD4E51C89889200772BE1 /* METhemeKitTests.xctest */, 147 | 849DD4F01C89889200772BE1 /* METhemeKitUITests.xctest */, 148 | ); 149 | name = Products; 150 | sourceTree = ""; 151 | }; 152 | 849DD4CE1C89889100772BE1 /* METhemeKit */ = { 153 | isa = PBXGroup; 154 | children = ( 155 | 849DD5041C8988D000772BE1 /* METhemeKit */, 156 | 849DD4CF1C89889100772BE1 /* Supporting Files */, 157 | 849DD4D21C89889100772BE1 /* AppDelegate.h */, 158 | 849DD4D31C89889100772BE1 /* AppDelegate.m */, 159 | 849DD4DB1C89889100772BE1 /* Assets.xcassets */, 160 | 849E44D31C8D211C00397F6F /* BaseNavViewController.h */, 161 | 849E44D41C8D211C00397F6F /* BaseNavViewController.m */, 162 | 849E44D61C8D233E00397F6F /* BaseViewController.h */, 163 | 849E44D71C8D233E00397F6F /* BaseViewController.m */, 164 | 849DD5411C8997DE00772BE1 /* FirstViewController.h */, 165 | 849DD5421C8997DE00772BE1 /* FirstViewController.m */, 166 | 849DD4E01C89889100772BE1 /* Info.plist */, 167 | 849DD4DD1C89889100772BE1 /* LaunchScreen.storyboard */, 168 | 849DD4D81C89889100772BE1 /* Main.storyboard */, 169 | 849DD5441C8997ED00772BE1 /* SecondViewController.h */, 170 | 849DD5451C8997ED00772BE1 /* SecondViewController.m */, 171 | ); 172 | path = METhemeKit; 173 | sourceTree = ""; 174 | }; 175 | 849DD4CF1C89889100772BE1 /* Supporting Files */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | 849DD4D01C89889100772BE1 /* main.m */, 179 | ); 180 | path = "Supporting Files"; 181 | sourceTree = ""; 182 | }; 183 | 849DD4E81C89889200772BE1 /* METhemeKitTests */ = { 184 | isa = PBXGroup; 185 | children = ( 186 | 849DD4EB1C89889200772BE1 /* Info.plist */, 187 | 849DD4E91C89889200772BE1 /* METhemeKitTests.m */, 188 | ); 189 | path = METhemeKitTests; 190 | sourceTree = ""; 191 | }; 192 | 849DD4F31C89889200772BE1 /* METhemeKitUITests */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | 849DD4F61C89889200772BE1 /* Info.plist */, 196 | 849DD4F41C89889200772BE1 /* METhemeKitUITests.m */, 197 | ); 198 | path = METhemeKitUITests; 199 | sourceTree = ""; 200 | }; 201 | 849DD5041C8988D000772BE1 /* METhemeKit */ = { 202 | isa = PBXGroup; 203 | children = ( 204 | 849DD5051C8988D000772BE1 /* Core */, 205 | 849E44D91C8D276500397F6F /* DeallocBlock */, 206 | 849DD5101C8988D000772BE1 /* ThemeData */, 207 | 849DD5131C8988D000772BE1 /* ThemeUIKit */, 208 | 849DD50F1C8988D000772BE1 /* METhemeKit.h */, 209 | ); 210 | path = METhemeKit; 211 | sourceTree = ""; 212 | }; 213 | 849DD5051C8988D000772BE1 /* Core */ = { 214 | isa = PBXGroup; 215 | children = ( 216 | 849DD5161C8988D000772BE1 /* CALayer+Theme.h */, 217 | 849DD5171C8988D000772BE1 /* CALayer+Theme.m */, 218 | 849DD5061C8988D000772BE1 /* METhemeManager.h */, 219 | 849DD5071C8988D000772BE1 /* METhemeManager.m */, 220 | 849DD5081C8988D000772BE1 /* NSObject+Theme.h */, 221 | 849DD5091C8988D000772BE1 /* NSObject+Theme.m */, 222 | 849DD50A1C8988D000772BE1 /* ThemeProperties.h */, 223 | 849DD50B1C8988D000772BE1 /* UIColor+Theme.h */, 224 | 849DD50C1C8988D000772BE1 /* UIColor+Theme.m */, 225 | 849DD50D1C8988D000772BE1 /* UIImage+Theme.h */, 226 | 849DD50E1C8988D000772BE1 /* UIImage+Theme.m */, 227 | ); 228 | path = Core; 229 | sourceTree = ""; 230 | }; 231 | 849DD5101C8988D000772BE1 /* ThemeData */ = { 232 | isa = PBXGroup; 233 | children = ( 234 | 849DD5111C8988D000772BE1 /* ThemeDefault.json */, 235 | 849DD5121C8988D000772BE1 /* ThemeOrange.json */, 236 | ); 237 | path = ThemeData; 238 | sourceTree = ""; 239 | }; 240 | 849DD5131C8988D000772BE1 /* ThemeUIKit */ = { 241 | isa = PBXGroup; 242 | children = ( 243 | 849DD51C1C8988D000772BE1 /* UIButton+Theme.h */, 244 | 849DD51D1C8988D000772BE1 /* UIButton+Theme.m */, 245 | 849DD51E1C8988D000772BE1 /* UIImageView+Theme.h */, 246 | 849DD51F1C8988D000772BE1 /* UIImageView+Theme.m */, 247 | 849DD5201C8988D000772BE1 /* UILabel+Theme.h */, 248 | 849DD5211C8988D000772BE1 /* UILabel+Theme.m */, 249 | 849DD5221C8988D000772BE1 /* UINavigationBar+Theme.h */, 250 | 849DD5231C8988D000772BE1 /* UINavigationBar+Theme.m */, 251 | 849DD5241C8988D000772BE1 /* UIView+Theme.h */, 252 | 849DD5251C8988D000772BE1 /* UIView+Theme.m */, 253 | ); 254 | path = ThemeUIKit; 255 | sourceTree = ""; 256 | }; 257 | 849E44D91C8D276500397F6F /* DeallocBlock */ = { 258 | isa = PBXGroup; 259 | children = ( 260 | 849E44DD1C8D2B5A00397F6F /* MEDeallocBlockExecutor.h */, 261 | 849E44DE1C8D2B5A00397F6F /* MEDeallocBlockExecutor.m */, 262 | 849E44DA1C8D27C300397F6F /* NSObject+DeallocBlock.h */, 263 | 849E44DB1C8D27C300397F6F /* NSObject+DeallocBlock.m */, 264 | ); 265 | path = DeallocBlock; 266 | sourceTree = ""; 267 | }; 268 | /* End PBXGroup section */ 269 | 270 | /* Begin PBXNativeTarget section */ 271 | 849DD4CB1C89889100772BE1 /* METhemeKit */ = { 272 | isa = PBXNativeTarget; 273 | buildConfigurationList = 849DD4F91C89889200772BE1 /* Build configuration list for PBXNativeTarget "METhemeKit" */; 274 | buildPhases = ( 275 | 849DD4C81C89889100772BE1 /* Sources */, 276 | 849DD4C91C89889100772BE1 /* Frameworks */, 277 | 849DD4CA1C89889100772BE1 /* Resources */, 278 | ); 279 | buildRules = ( 280 | ); 281 | dependencies = ( 282 | ); 283 | name = METhemeKit; 284 | productName = METhemeKit; 285 | productReference = 849DD4CC1C89889100772BE1 /* METhemeKit.app */; 286 | productType = "com.apple.product-type.application"; 287 | }; 288 | 849DD4E41C89889200772BE1 /* METhemeKitTests */ = { 289 | isa = PBXNativeTarget; 290 | buildConfigurationList = 849DD4FC1C89889200772BE1 /* Build configuration list for PBXNativeTarget "METhemeKitTests" */; 291 | buildPhases = ( 292 | 849DD4E11C89889200772BE1 /* Sources */, 293 | 849DD4E21C89889200772BE1 /* Frameworks */, 294 | 849DD4E31C89889200772BE1 /* Resources */, 295 | ); 296 | buildRules = ( 297 | ); 298 | dependencies = ( 299 | 849DD4E71C89889200772BE1 /* PBXTargetDependency */, 300 | ); 301 | name = METhemeKitTests; 302 | productName = METhemeKitTests; 303 | productReference = 849DD4E51C89889200772BE1 /* METhemeKitTests.xctest */; 304 | productType = "com.apple.product-type.bundle.unit-test"; 305 | }; 306 | 849DD4EF1C89889200772BE1 /* METhemeKitUITests */ = { 307 | isa = PBXNativeTarget; 308 | buildConfigurationList = 849DD4FF1C89889200772BE1 /* Build configuration list for PBXNativeTarget "METhemeKitUITests" */; 309 | buildPhases = ( 310 | 849DD4EC1C89889200772BE1 /* Sources */, 311 | 849DD4ED1C89889200772BE1 /* Frameworks */, 312 | 849DD4EE1C89889200772BE1 /* Resources */, 313 | ); 314 | buildRules = ( 315 | ); 316 | dependencies = ( 317 | 849DD4F21C89889200772BE1 /* PBXTargetDependency */, 318 | ); 319 | name = METhemeKitUITests; 320 | productName = METhemeKitUITests; 321 | productReference = 849DD4F01C89889200772BE1 /* METhemeKitUITests.xctest */; 322 | productType = "com.apple.product-type.bundle.ui-testing"; 323 | }; 324 | /* End PBXNativeTarget section */ 325 | 326 | /* Begin PBXProject section */ 327 | 849DD4C41C89889100772BE1 /* Project object */ = { 328 | isa = PBXProject; 329 | attributes = { 330 | LastUpgradeCheck = 0720; 331 | ORGANIZATIONNAME = Yasin; 332 | TargetAttributes = { 333 | 849DD4CB1C89889100772BE1 = { 334 | CreatedOnToolsVersion = 7.2.1; 335 | }; 336 | 849DD4E41C89889200772BE1 = { 337 | CreatedOnToolsVersion = 7.2.1; 338 | TestTargetID = 849DD4CB1C89889100772BE1; 339 | }; 340 | 849DD4EF1C89889200772BE1 = { 341 | CreatedOnToolsVersion = 7.2.1; 342 | TestTargetID = 849DD4CB1C89889100772BE1; 343 | }; 344 | }; 345 | }; 346 | buildConfigurationList = 849DD4C71C89889100772BE1 /* Build configuration list for PBXProject "METhemeKit" */; 347 | compatibilityVersion = "Xcode 3.2"; 348 | developmentRegion = English; 349 | hasScannedForEncodings = 0; 350 | knownRegions = ( 351 | en, 352 | Base, 353 | ); 354 | mainGroup = 849DD4C31C89889100772BE1; 355 | productRefGroup = 849DD4CD1C89889100772BE1 /* Products */; 356 | projectDirPath = ""; 357 | projectRoot = ""; 358 | targets = ( 359 | 849DD4CB1C89889100772BE1 /* METhemeKit */, 360 | 849DD4E41C89889200772BE1 /* METhemeKitTests */, 361 | 849DD4EF1C89889200772BE1 /* METhemeKitUITests */, 362 | ); 363 | }; 364 | /* End PBXProject section */ 365 | 366 | /* Begin PBXResourcesBuildPhase section */ 367 | 849DD4CA1C89889100772BE1 /* Resources */ = { 368 | isa = PBXResourcesBuildPhase; 369 | buildActionMask = 2147483647; 370 | files = ( 371 | 849DD4DF1C89889100772BE1 /* LaunchScreen.storyboard in Resources */, 372 | 849DD52E1C8988D000772BE1 /* ThemeDefault.json in Resources */, 373 | 849DD52F1C8988D000772BE1 /* ThemeOrange.json in Resources */, 374 | 849DD4DC1C89889100772BE1 /* Assets.xcassets in Resources */, 375 | 849DD4DA1C89889100772BE1 /* Main.storyboard in Resources */, 376 | ); 377 | runOnlyForDeploymentPostprocessing = 0; 378 | }; 379 | 849DD4E31C89889200772BE1 /* Resources */ = { 380 | isa = PBXResourcesBuildPhase; 381 | buildActionMask = 2147483647; 382 | files = ( 383 | ); 384 | runOnlyForDeploymentPostprocessing = 0; 385 | }; 386 | 849DD4EE1C89889200772BE1 /* Resources */ = { 387 | isa = PBXResourcesBuildPhase; 388 | buildActionMask = 2147483647; 389 | files = ( 390 | ); 391 | runOnlyForDeploymentPostprocessing = 0; 392 | }; 393 | /* End PBXResourcesBuildPhase section */ 394 | 395 | /* Begin PBXSourcesBuildPhase section */ 396 | 849DD4C81C89889100772BE1 /* Sources */ = { 397 | isa = PBXSourcesBuildPhase; 398 | buildActionMask = 2147483647; 399 | files = ( 400 | 849DD5461C8997ED00772BE1 /* SecondViewController.m in Sources */, 401 | 849DD5381C8988D000772BE1 /* UIView+Theme.m in Sources */, 402 | 849E44DC1C8D27C300397F6F /* NSObject+DeallocBlock.m in Sources */, 403 | 849E44D51C8D211C00397F6F /* BaseNavViewController.m in Sources */, 404 | 849DD5371C8988D000772BE1 /* UINavigationBar+Theme.m in Sources */, 405 | 849DD5361C8988D000772BE1 /* UILabel+Theme.m in Sources */, 406 | 849DD52B1C8988D000772BE1 /* NSObject+Theme.m in Sources */, 407 | 849DD5341C8988D000772BE1 /* UIButton+Theme.m in Sources */, 408 | 849DD5311C8988D000772BE1 /* CALayer+Theme.m in Sources */, 409 | 849DD4D41C89889100772BE1 /* AppDelegate.m in Sources */, 410 | 849E44D81C8D233E00397F6F /* BaseViewController.m in Sources */, 411 | 849E44DF1C8D2B5A00397F6F /* MEDeallocBlockExecutor.m in Sources */, 412 | 849DD4D11C89889100772BE1 /* main.m in Sources */, 413 | 849DD5431C8997DE00772BE1 /* FirstViewController.m in Sources */, 414 | 849DD5351C8988D000772BE1 /* UIImageView+Theme.m in Sources */, 415 | 849DD52D1C8988D000772BE1 /* UIImage+Theme.m in Sources */, 416 | 849DD52A1C8988D000772BE1 /* METhemeManager.m in Sources */, 417 | 849DD52C1C8988D000772BE1 /* UIColor+Theme.m in Sources */, 418 | ); 419 | runOnlyForDeploymentPostprocessing = 0; 420 | }; 421 | 849DD4E11C89889200772BE1 /* Sources */ = { 422 | isa = PBXSourcesBuildPhase; 423 | buildActionMask = 2147483647; 424 | files = ( 425 | 849DD4EA1C89889200772BE1 /* METhemeKitTests.m in Sources */, 426 | ); 427 | runOnlyForDeploymentPostprocessing = 0; 428 | }; 429 | 849DD4EC1C89889200772BE1 /* Sources */ = { 430 | isa = PBXSourcesBuildPhase; 431 | buildActionMask = 2147483647; 432 | files = ( 433 | 849DD4F51C89889200772BE1 /* METhemeKitUITests.m in Sources */, 434 | ); 435 | runOnlyForDeploymentPostprocessing = 0; 436 | }; 437 | /* End PBXSourcesBuildPhase section */ 438 | 439 | /* Begin PBXTargetDependency section */ 440 | 849DD4E71C89889200772BE1 /* PBXTargetDependency */ = { 441 | isa = PBXTargetDependency; 442 | target = 849DD4CB1C89889100772BE1 /* METhemeKit */; 443 | targetProxy = 849DD4E61C89889200772BE1 /* PBXContainerItemProxy */; 444 | }; 445 | 849DD4F21C89889200772BE1 /* PBXTargetDependency */ = { 446 | isa = PBXTargetDependency; 447 | target = 849DD4CB1C89889100772BE1 /* METhemeKit */; 448 | targetProxy = 849DD4F11C89889200772BE1 /* PBXContainerItemProxy */; 449 | }; 450 | /* End PBXTargetDependency section */ 451 | 452 | /* Begin PBXVariantGroup section */ 453 | 849DD4D81C89889100772BE1 /* Main.storyboard */ = { 454 | isa = PBXVariantGroup; 455 | children = ( 456 | 849DD4D91C89889100772BE1 /* Base */, 457 | ); 458 | name = Main.storyboard; 459 | path = .; 460 | sourceTree = ""; 461 | }; 462 | 849DD4DD1C89889100772BE1 /* LaunchScreen.storyboard */ = { 463 | isa = PBXVariantGroup; 464 | children = ( 465 | 849DD4DE1C89889100772BE1 /* Base */, 466 | ); 467 | name = LaunchScreen.storyboard; 468 | path = .; 469 | sourceTree = ""; 470 | }; 471 | /* End PBXVariantGroup section */ 472 | 473 | /* Begin XCBuildConfiguration section */ 474 | 849DD4F71C89889200772BE1 /* Debug */ = { 475 | isa = XCBuildConfiguration; 476 | buildSettings = { 477 | ALWAYS_SEARCH_USER_PATHS = NO; 478 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 479 | CLANG_CXX_LIBRARY = "libc++"; 480 | CLANG_ENABLE_MODULES = YES; 481 | CLANG_ENABLE_OBJC_ARC = YES; 482 | CLANG_WARN_BOOL_CONVERSION = YES; 483 | CLANG_WARN_CONSTANT_CONVERSION = YES; 484 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 485 | CLANG_WARN_EMPTY_BODY = YES; 486 | CLANG_WARN_ENUM_CONVERSION = YES; 487 | CLANG_WARN_INT_CONVERSION = YES; 488 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 489 | CLANG_WARN_UNREACHABLE_CODE = YES; 490 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 491 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 492 | COPY_PHASE_STRIP = NO; 493 | DEBUG_INFORMATION_FORMAT = dwarf; 494 | ENABLE_STRICT_OBJC_MSGSEND = YES; 495 | ENABLE_TESTABILITY = YES; 496 | GCC_C_LANGUAGE_STANDARD = gnu99; 497 | GCC_DYNAMIC_NO_PIC = NO; 498 | GCC_NO_COMMON_BLOCKS = YES; 499 | GCC_OPTIMIZATION_LEVEL = 0; 500 | GCC_PREPROCESSOR_DEFINITIONS = ( 501 | "DEBUG=1", 502 | "$(inherited)", 503 | ); 504 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 505 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 506 | GCC_WARN_UNDECLARED_SELECTOR = YES; 507 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 508 | GCC_WARN_UNUSED_FUNCTION = YES; 509 | GCC_WARN_UNUSED_VARIABLE = YES; 510 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 511 | MTL_ENABLE_DEBUG_INFO = YES; 512 | ONLY_ACTIVE_ARCH = YES; 513 | SDKROOT = iphoneos; 514 | }; 515 | name = Debug; 516 | }; 517 | 849DD4F81C89889200772BE1 /* Release */ = { 518 | isa = XCBuildConfiguration; 519 | buildSettings = { 520 | ALWAYS_SEARCH_USER_PATHS = NO; 521 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 522 | CLANG_CXX_LIBRARY = "libc++"; 523 | CLANG_ENABLE_MODULES = YES; 524 | CLANG_ENABLE_OBJC_ARC = YES; 525 | CLANG_WARN_BOOL_CONVERSION = YES; 526 | CLANG_WARN_CONSTANT_CONVERSION = YES; 527 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 528 | CLANG_WARN_EMPTY_BODY = YES; 529 | CLANG_WARN_ENUM_CONVERSION = YES; 530 | CLANG_WARN_INT_CONVERSION = YES; 531 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 532 | CLANG_WARN_UNREACHABLE_CODE = YES; 533 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 534 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 535 | COPY_PHASE_STRIP = NO; 536 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 537 | ENABLE_NS_ASSERTIONS = NO; 538 | ENABLE_STRICT_OBJC_MSGSEND = YES; 539 | GCC_C_LANGUAGE_STANDARD = gnu99; 540 | GCC_NO_COMMON_BLOCKS = YES; 541 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 542 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 543 | GCC_WARN_UNDECLARED_SELECTOR = YES; 544 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 545 | GCC_WARN_UNUSED_FUNCTION = YES; 546 | GCC_WARN_UNUSED_VARIABLE = YES; 547 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 548 | MTL_ENABLE_DEBUG_INFO = NO; 549 | SDKROOT = iphoneos; 550 | VALIDATE_PRODUCT = YES; 551 | }; 552 | name = Release; 553 | }; 554 | 849DD4FA1C89889200772BE1 /* Debug */ = { 555 | isa = XCBuildConfiguration; 556 | buildSettings = { 557 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 558 | INFOPLIST_FILE = METhemeKit/Info.plist; 559 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 560 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 561 | PRODUCT_BUNDLE_IDENTIFIER = Yasin.METhemeKit; 562 | PRODUCT_NAME = "$(TARGET_NAME)"; 563 | }; 564 | name = Debug; 565 | }; 566 | 849DD4FB1C89889200772BE1 /* Release */ = { 567 | isa = XCBuildConfiguration; 568 | buildSettings = { 569 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 570 | INFOPLIST_FILE = METhemeKit/Info.plist; 571 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 572 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 573 | PRODUCT_BUNDLE_IDENTIFIER = Yasin.METhemeKit; 574 | PRODUCT_NAME = "$(TARGET_NAME)"; 575 | }; 576 | name = Release; 577 | }; 578 | 849DD4FD1C89889200772BE1 /* Debug */ = { 579 | isa = XCBuildConfiguration; 580 | buildSettings = { 581 | BUNDLE_LOADER = "$(TEST_HOST)"; 582 | INFOPLIST_FILE = METhemeKitTests/Info.plist; 583 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 584 | PRODUCT_BUNDLE_IDENTIFIER = Yasin.METhemeKitTests; 585 | PRODUCT_NAME = "$(TARGET_NAME)"; 586 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/METhemeKit.app/METhemeKit"; 587 | }; 588 | name = Debug; 589 | }; 590 | 849DD4FE1C89889200772BE1 /* Release */ = { 591 | isa = XCBuildConfiguration; 592 | buildSettings = { 593 | BUNDLE_LOADER = "$(TEST_HOST)"; 594 | INFOPLIST_FILE = METhemeKitTests/Info.plist; 595 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 596 | PRODUCT_BUNDLE_IDENTIFIER = Yasin.METhemeKitTests; 597 | PRODUCT_NAME = "$(TARGET_NAME)"; 598 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/METhemeKit.app/METhemeKit"; 599 | }; 600 | name = Release; 601 | }; 602 | 849DD5001C89889200772BE1 /* Debug */ = { 603 | isa = XCBuildConfiguration; 604 | buildSettings = { 605 | INFOPLIST_FILE = METhemeKitUITests/Info.plist; 606 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 607 | PRODUCT_BUNDLE_IDENTIFIER = Yasin.METhemeKitUITests; 608 | PRODUCT_NAME = "$(TARGET_NAME)"; 609 | TEST_TARGET_NAME = METhemeKit; 610 | USES_XCTRUNNER = YES; 611 | }; 612 | name = Debug; 613 | }; 614 | 849DD5011C89889200772BE1 /* Release */ = { 615 | isa = XCBuildConfiguration; 616 | buildSettings = { 617 | INFOPLIST_FILE = METhemeKitUITests/Info.plist; 618 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 619 | PRODUCT_BUNDLE_IDENTIFIER = Yasin.METhemeKitUITests; 620 | PRODUCT_NAME = "$(TARGET_NAME)"; 621 | TEST_TARGET_NAME = METhemeKit; 622 | USES_XCTRUNNER = YES; 623 | }; 624 | name = Release; 625 | }; 626 | /* End XCBuildConfiguration section */ 627 | 628 | /* Begin XCConfigurationList section */ 629 | 849DD4C71C89889100772BE1 /* Build configuration list for PBXProject "METhemeKit" */ = { 630 | isa = XCConfigurationList; 631 | buildConfigurations = ( 632 | 849DD4F71C89889200772BE1 /* Debug */, 633 | 849DD4F81C89889200772BE1 /* Release */, 634 | ); 635 | defaultConfigurationIsVisible = 0; 636 | defaultConfigurationName = Release; 637 | }; 638 | 849DD4F91C89889200772BE1 /* Build configuration list for PBXNativeTarget "METhemeKit" */ = { 639 | isa = XCConfigurationList; 640 | buildConfigurations = ( 641 | 849DD4FA1C89889200772BE1 /* Debug */, 642 | 849DD4FB1C89889200772BE1 /* Release */, 643 | ); 644 | defaultConfigurationIsVisible = 0; 645 | defaultConfigurationName = Release; 646 | }; 647 | 849DD4FC1C89889200772BE1 /* Build configuration list for PBXNativeTarget "METhemeKitTests" */ = { 648 | isa = XCConfigurationList; 649 | buildConfigurations = ( 650 | 849DD4FD1C89889200772BE1 /* Debug */, 651 | 849DD4FE1C89889200772BE1 /* Release */, 652 | ); 653 | defaultConfigurationIsVisible = 0; 654 | defaultConfigurationName = Release; 655 | }; 656 | 849DD4FF1C89889200772BE1 /* Build configuration list for PBXNativeTarget "METhemeKitUITests" */ = { 657 | isa = XCConfigurationList; 658 | buildConfigurations = ( 659 | 849DD5001C89889200772BE1 /* Debug */, 660 | 849DD5011C89889200772BE1 /* Release */, 661 | ); 662 | defaultConfigurationIsVisible = 0; 663 | defaultConfigurationName = Release; 664 | }; 665 | /* End XCConfigurationList section */ 666 | }; 667 | rootObject = 849DD4C41C89889100772BE1 /* Project object */; 668 | } 669 | -------------------------------------------------------------------------------- /METhemeKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /METhemeKit/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/4. 6 | // Copyright © 2016年 Yasin. 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 | -------------------------------------------------------------------------------- /METhemeKit/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/4. 6 | // Copyright © 2016年 Yasin. 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 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // 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. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /METhemeKit/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 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /METhemeKit/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /METhemeKit/Assets.xcassets/Default/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /METhemeKit/Assets.xcassets/Default/avatar.imageset/10187156,1920,1080.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YasinZhou/METhemeKit/4e53a259553f32992afcd53b4caf58d311d99f7e/METhemeKit/Assets.xcassets/Default/avatar.imageset/10187156,1920,1080.png -------------------------------------------------------------------------------- /METhemeKit/Assets.xcassets/Default/avatar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "10187156,1920,1080.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /METhemeKit/Assets.xcassets/Year/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /METhemeKit/Assets.xcassets/Year/navigationBarShadowImage339.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "navigationBarShadowImage339@2x.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /METhemeKit/Assets.xcassets/Year/navigationBarShadowImage339.imageset/navigationBarShadowImage339@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YasinZhou/METhemeKit/4e53a259553f32992afcd53b4caf58d311d99f7e/METhemeKit/Assets.xcassets/Year/navigationBarShadowImage339.imageset/navigationBarShadowImage339@2x.png -------------------------------------------------------------------------------- /METhemeKit/Assets.xcassets/Year/year_avatar.imageset/10271405,1920,1080.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YasinZhou/METhemeKit/4e53a259553f32992afcd53b4caf58d311d99f7e/METhemeKit/Assets.xcassets/Year/year_avatar.imageset/10271405,1920,1080.png -------------------------------------------------------------------------------- /METhemeKit/Assets.xcassets/Year/year_avatar.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "10271405,1920,1080.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /METhemeKit/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 | -------------------------------------------------------------------------------- /METhemeKit/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 | 28 | 39 | 46 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /METhemeKit/BaseNavViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseNavViewController.h 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/7. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "METhemeKit.h" 11 | @interface BaseNavViewController : UINavigationController 12 | -(void)changeNavBarType:(NavBarType)navBarType; 13 | @end 14 | -------------------------------------------------------------------------------- /METhemeKit/BaseNavViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseNavViewController.m 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/7. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "BaseNavViewController.h" 10 | #import "FirstViewController.h" 11 | 12 | @interface BaseNavViewController () 13 | 14 | @end 15 | 16 | @implementation BaseNavViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | // Do any additional setup after loading the view. 21 | __weak typeof(self) weakSelf = self; 22 | 23 | self.delegate = weakSelf; 24 | } 25 | -(void)changeNavBarType:(NavBarType)navBarType{ 26 | [self.navigationBar me_setBackgroundImageForBarMetrics:UIBarMetricsDefault WithType:navBarType]; 27 | if (navBarType == NavBarLevel1) { 28 | self.navigationBar.shadowImage = [UIImage imageNamed:@"navigationBarShadowImage"]; 29 | } else { 30 | self.navigationBar.shadowImage = [UIImage new]; 31 | } 32 | } 33 | - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { 34 | 35 | // NSLog(@" willShowViewController %@ ; viewControlers %@",viewController,navigationController.viewControllers); 36 | 37 | if ([viewController isKindOfClass:[FirstViewController class]]) { 38 | [self changeNavBarType:NavBarDefault]; // 修改导航栏 背景颜色 39 | 40 | } else { 41 | [self changeNavBarType:NavBarLevel1]; // 修改导航栏 背景颜色 42 | } 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /METhemeKit/BaseViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewController.h 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/7. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BaseViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /METhemeKit/BaseViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewController.m 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/7. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "BaseViewController.h" 10 | #import "BaseNavViewController.h" 11 | @interface BaseViewController () 12 | 13 | @end 14 | 15 | @implementation BaseViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | } 21 | - (void)viewWillAppear:(BOOL)animated{ 22 | [super viewWillAppear:animated]; 23 | // 修改导航栏背景图片 24 | [self changeNavBarBackgroundWithType]; 25 | } 26 | 27 | -(void)changeNavBarBackgroundWithType{ 28 | /** 29 | * 手势返回的时候滑动一半不返回,这里做导航条的背景颜色更改,主要针对导航条背景颜色不一致的页面 30 | */ 31 | if (self.navigationController.viewControllers.lastObject == self) { 32 | if ([self.navigationController isKindOfClass:[BaseNavViewController class]]) { 33 | BaseNavViewController *baseNav = (BaseNavViewController *)self.navigationController; 34 | [baseNav changeNavBarType:NavBarLevel1]; 35 | } 36 | } 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /METhemeKit/FirstViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.h 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/4. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "BaseViewController.h" 10 | 11 | @interface FirstViewController : BaseViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /METhemeKit/FirstViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.m 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/4. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "FirstViewController.h" 10 | #import "SecondViewController.h" 11 | #import "METhemeKit.h" 12 | @interface FirstViewController () 13 | @property (weak, nonatomic) IBOutlet UILabel *themeLabel; 14 | @property (weak, nonatomic) IBOutlet UIImageView *themeImageView; 15 | @property (weak, nonatomic) IBOutlet UIButton *themeSureButton; 16 | 17 | @end 18 | 19 | @implementation FirstViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | self.title = @"首页"; 24 | // Do any additional setup after loading the view. 25 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 26 | button.frame = CGRectMake(0, 70, 90, 30); 27 | [button me_setTitleColor:[UIColor me_colorPickerForMode:ThemeColorMode_Default] forState:UIControlStateNormal]; 28 | [button setBackgroundColor:[UIColor colorWithRed:0.5397 green:0.9142 blue:0.5158 alpha:1.0]]; 29 | [button addTarget:self action:@selector(changeTheme) forControlEvents:UIControlEventTouchUpInside]; 30 | [button setTitle:@"切换主题" forState:UIControlStateNormal]; 31 | UIWindow *window = [[UIApplication sharedApplication] keyWindow]; 32 | [window addSubview:button]; 33 | 34 | 35 | self.themeLabel.me_textColor = [UIColor me_colorPickerForMode:ThemeColorMode_Default]; 36 | 37 | self.themeImageView.me_image = [UIImage me_imageNamed:@"avatar"]; 38 | 39 | self.themeSureButton.me_configKey = ThemeMode_Button_NoBackgroundImage_SureButton; 40 | 41 | } 42 | - (void)changeTheme{ 43 | ThemeType type = [METhemeManager sharedThemeManager].themeType; 44 | if (type == ThemeDefault) { 45 | [METhemeManager sharedThemeManager].themeType = ThemeYear; 46 | } else { 47 | [METhemeManager sharedThemeManager].themeType = ThemeDefault; 48 | } 49 | } 50 | - (IBAction)next:(id)sender { 51 | SecondViewController *view = [[SecondViewController alloc]init]; 52 | [self.navigationController pushViewController:view animated:YES]; 53 | } 54 | - (IBAction)changeTemeNotification:(id)sender { 55 | [[NSNotificationCenter defaultCenter] postNotificationName:@"kThemeChangeNotification" object:nil]; 56 | } 57 | - (IBAction)removeImageTheme:(id)sender { 58 | [self.themeImageView removePickerForSEL:@selector(setImage:)]; 59 | } 60 | 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /METhemeKit/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/Core/CALayer+Theme.h: -------------------------------------------------------------------------------- 1 | // 2 | // CALayer+Theme.h 3 | // neighborhood 4 | // 5 | // Created by 杨世昌 on 16/1/18. 6 | // Copyright © 2016年 iYaYa. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIColor+Theme.h" 11 | @interface CALayer (Theme) 12 | 13 | @property (nonatomic, copy) MECGColorPicker me_borderColor; 14 | @property (nonatomic, copy) MECGColorPicker me_backgroundColor; 15 | @end 16 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/Core/CALayer+Theme.m: -------------------------------------------------------------------------------- 1 | // 2 | // CALayer+Theme.m 3 | // neighborhood 4 | // 5 | // Created by 杨世昌 on 16/1/18. 6 | // Copyright © 2016年 iYaYa. All rights reserved. 7 | // 8 | 9 | #import "CALayer+Theme.h" 10 | #import "NSObject+Theme.h" 11 | #import 12 | @implementation CALayer (Theme) 13 | 14 | -(MECGColorPicker)me_borderColor{ 15 | return objc_getAssociatedObject(self, @selector(me_borderColor)); 16 | } 17 | -(void)setMe_borderColor:(MECGColorPicker)me_borderColor { 18 | objc_setAssociatedObject(self, @selector(me_borderColor), me_borderColor, OBJC_ASSOCIATION_COPY_NONATOMIC); 19 | self.borderColor = me_borderColor(); 20 | 21 | [self.pickers setValue:[me_borderColor copy] forKey:@"setBorderColor:"]; 22 | } 23 | 24 | - (MECGColorPicker)me_backgroundColor{ 25 | return objc_getAssociatedObject(self, @selector(me_backgroundColor)); 26 | } 27 | - (void)setMe_backgroundColor:(MECGColorPicker)me_backgroundColor{ 28 | objc_setAssociatedObject(self, @selector(me_backgroundColor), me_backgroundColor, OBJC_ASSOCIATION_COPY_NONATOMIC); 29 | self.backgroundColor = me_backgroundColor(); 30 | [self.pickers setValue:[me_backgroundColor copy] forKey:@"setBackgroundColor:"]; 31 | } 32 | @end 33 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/Core/METhemeManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // METhemeManager.h 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | typedef NS_ENUM(NSUInteger,ThemeType) { 13 | ThemeDefault = 0, 14 | ThemeYear = 1, 15 | }; 16 | 17 | 18 | @interface METhemeManager : NSObject 19 | ///当前主题,以及主题的修改,重写了set方法,set方法里面发送通知 20 | @property (nonatomic,assign) ThemeType themeType; 21 | ///当前主题的配置参数 22 | @property (nonatomic, strong, readonly) NSDictionary *currentThemeConfig; 23 | ///图片名字前缀 24 | @property (nonatomic, strong, readonly) NSString *imageNamePrefix; 25 | 26 | ///`METhemeManager`应该作为单例出现在工程中 27 | + (METhemeManager *)sharedThemeManager; 28 | 29 | ///当前主题图片名字前缀 30 | + (NSString *)getImageNamePrefix; 31 | 32 | 33 | 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/Core/METhemeManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // METhemeManager.m 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "METhemeManager.h" 10 | #import 11 | #import "ThemeProperties.h" 12 | #define BlackColorHex @"000000" 13 | 14 | static METhemeManager *instance = nil; 15 | 16 | @interface METhemeManager () 17 | 18 | @end 19 | 20 | @implementation METhemeManager 21 | + (void)load{ 22 | [super load]; 23 | [METhemeManager sharedThemeManager]; 24 | } 25 | + (METhemeManager *)sharedThemeManager { 26 | @synchronized(self){//为了确保多线程情况下,仍然确保实体的唯一性 27 | if (!instance) { 28 | instance = [[self alloc] init]; //确保使用同一块内存地址 29 | } 30 | } 31 | return instance; 32 | } 33 | +(id)allocWithZone:(NSZone *)zone{ 34 | @synchronized(self){// //为了确保多线程情况下,仍然确保实体的唯一性 35 | if (!instance) { 36 | instance = [super allocWithZone:zone]; //确保使用同一块内存地址 37 | return instance; 38 | } 39 | } 40 | return nil; 41 | } 42 | - (instancetype)init 43 | { 44 | self = [super init]; 45 | if (self) { 46 | self.themeType = [self getTypeFromLocal]; 47 | } 48 | return self; 49 | } 50 | - (id)copyWithZone:(NSZone *)zone;{ 51 | return self; //确保copy对象也是唯一 52 | } 53 | 54 | - (void)setThemeType:(ThemeType)themeType { 55 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 56 | _themeType = themeType; 57 | NSString *path; 58 | switch (themeType) { 59 | case ThemeDefault:{ 60 | _imageNamePrefix = @""; 61 | path = [[NSBundle mainBundle]pathForResource:@"ThemeDefault" ofType:@"json"]; 62 | } 63 | break; 64 | case ThemeYear:{ 65 | _imageNamePrefix = @"year_"; 66 | path = [[NSBundle mainBundle]pathForResource:@"ThemeOrange" ofType:@"json"]; 67 | } 68 | break; 69 | default: 70 | break; 71 | } 72 | NSData *jsonData = [NSData dataWithContentsOfFile:path]; 73 | _currentThemeConfig = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:nil]; 74 | if (_currentThemeConfig == nil) { 75 | NSAssert(false, @"ThemeConfig配置有误", self); 76 | abort(); 77 | } 78 | //保存当前配置到本地 79 | [self saveTypeLocal:themeType]; 80 | 81 | /** 82 | * 发送通知 83 | */ 84 | dispatch_async(dispatch_get_main_queue(), ^{ 85 | [[NSNotificationCenter defaultCenter] postNotificationName:kMEThemeChangeNotification object:nil]; 86 | }); 87 | }); 88 | } 89 | #pragma mark - 获取配置 90 | #pragma mark - 获取图片名字前缀 91 | + (NSString *)getImageNamePrefix{ 92 | return [METhemeManager sharedThemeManager].imageNamePrefix; 93 | } 94 | 95 | - (void)saveTypeLocal:(ThemeType)themeType{ 96 | [[NSUserDefaults standardUserDefaults]setInteger:themeType forKey:ThemeTypeKey]; 97 | [[NSUserDefaults standardUserDefaults] synchronize]; 98 | } 99 | - (ThemeType)getTypeFromLocal{ 100 | ThemeType type = [[NSUserDefaults standardUserDefaults]integerForKey:ThemeTypeKey]; 101 | return type; 102 | } 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | @end 111 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/Core/NSObject+Theme.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Theme.h 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef id _Nullable (^MEPicker)(void); 12 | 13 | @interface NSObject (Theme) 14 | @property (nonatomic, strong, nonnull,readonly) NSMutableDictionary *pickers; 15 | 16 | - (void)removePickerForSEL:(nullable SEL)selector; 17 | @end 18 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/Core/NSObject+Theme.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Theme.m 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "NSObject+Theme.h" 10 | #import "ThemeProperties.h" 11 | #import "NSObject+DeallocBlock.h" 12 | #import 13 | #import 14 | 15 | @implementation NSObject (Theme) 16 | - (void)removePickerForSEL:(SEL)selector{ 17 | NSString *key = NSStringFromSelector(selector); 18 | [self.pickers removeObjectForKey:key]; 19 | } 20 | 21 | -(NSMutableDictionary *)pickers{ 22 | NSMutableDictionary *pickers = objc_getAssociatedObject(self, @selector(pickers)); 23 | if (!pickers) { 24 | //获取数组的时候进行初始化操作,同时进行通知的注册 25 | 26 | pickers = [[NSMutableDictionary alloc] init]; 27 | objc_setAssociatedObject(self, @selector(pickers), pickers, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 28 | 29 | //初始化的时候添加通知 30 | __weak typeof(self) weakSelf = self; 31 | __weak id notificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMEThemeChangeNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) { 32 | [weakSelf changeTheme]; 33 | }]; 34 | if (self.deallocHelperExecutor == nil) { 35 | //这里添加一个属性,监听控件的dealloc事件,进行通知的移除 36 | MEDeallocBlockExecutor *deallocHelper = [[MEDeallocBlockExecutor alloc]initWith:^{ 37 | [[NSNotificationCenter defaultCenter] removeObserver:notificationObserver]; 38 | }]; 39 | self.deallocHelperExecutor = deallocHelper; 40 | } 41 | } 42 | return pickers; 43 | } 44 | - (void)changeTheme { 45 | [self.pickers enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, MEPicker _Nonnull obj, BOOL * _Nonnull stop) { 46 | SEL sel = NSSelectorFromString(key); 47 | id result = obj(); 48 | [UIView animateWithDuration:METhemeAnimationDuration animations:^{ 49 | #pragma clang diagnostic push 50 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 51 | if ([self respondsToSelector:sel]) { 52 | [self performSelector:sel withObject:result]; 53 | } 54 | #pragma clang diagnostic pop 55 | }]; 56 | 57 | }]; 58 | } 59 | @end 60 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/Core/ThemeProperties.h: -------------------------------------------------------------------------------- 1 | // 2 | // ThemeProperties.h 3 | // neighborhood 4 | // 5 | // Created by Yasin on 16/1/17. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #ifndef ThemeProperties_h 10 | #define ThemeProperties_h 11 | 12 | #define kMEThemeChangeNotification @"kMEThemeChangeNotificationName" 13 | #define METhemeAnimationDuration 0.3 14 | 15 | static NSString * ThemeTypeKey = @"ThemeType"; 16 | 17 | 18 | static NSString * ThemeColorMode_Default = @"ThemeColorMode_Default"; 19 | static NSString * ThemeColorMode_Default_Highlight = @"ThemeColorMode_Default_Highlight"; 20 | 21 | 22 | 23 | // Config button 24 | static NSString * ThemeMode_Button_Sure = @"ThemeMode_Button_SureButton"; // 25 | static NSString * ThemeMode_Button_NoBackgroundImage_SureButton = @"ThemeMode_Button_NoBackgroundImage_SureButton"; 26 | #define ThemeMode_Button_Sure_CapInsets UIEdgeInsetsMake(5, 5, 5, 5) 27 | static NSString * ThemeMode_Button_NavBarRight = @"ThemeMode_Button_NavBarRight"; // 28 | //快递,地址选择器,上部地址选择指示 29 | static NSString * ThemeMode_Button_ExpressAddressSele = @"ThemeMode_Button_ExpressAddressSele"; 30 | //时间选择器的取消确定按钮 31 | static NSString * ThemeModel_Button_PickerView = @"ThemeModel_Button_PickerView"; 32 | 33 | 34 | // color 35 | 36 | // 工具租借, 我的工具租借 取消按钮 37 | static NSString * ThemeMode_Color_ToolRental_MyToolRental_CancelButton = @"ThemeMode_Color_ToolRental_MyToolRental_CancelButton"; 38 | static NSString * ThemeMode_Color_LifeNumber_Label_CategoryItemHot = @"ThemeMode_Color_LifeNumber_Label_CategoryItemHot"; 39 | 40 | // page control 41 | static NSString * ThemeMode_Color_UserGuide_PageControl_PageIndicatorColor = @"ThemeMode_Color_UserGuide_PageControl_PageIndicatorColor"; 42 | static NSString * ThemeMode_Color_UserGuide_PageControl_CurrentPageIndicatorColor = @"ThemeMode_Color_UserGuide_PageControl_CurrentPageIndicatorColor"; 43 | 44 | // chat 45 | static NSString * ThemeMode_Color_Chat_MyMessage_ContentTextColor = @"ThemeMode_Color_Chat_MyMessage_ContentTextColor"; 46 | 47 | static NSString * ThemeMode_Color_BBS_Reply_Vest_Select_BackgroundColor = @"ThemeMode_Color_BBS_Reply_Vest_Select_BackgroundColor"; 48 | 49 | // StatusBarStyle 50 | static NSString * ThemeMode_StatusBarStyle = @"StatusBarStyle"; 51 | static NSString * ThemeMode_StatusBarStyle_DefaultStyle = @"Default"; 52 | static NSString * ThemeMode_StatusBarStyleDefault = @"UIStatusBarStyleDefault"; 53 | static NSString * ThemeMode_StatusBarStyleLightContent = @"UIStatusBarStyleLightContent"; 54 | 55 | #endif /* ThemeProperties_h */ 56 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/Core/UIColor+Theme.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+Theme.h 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | typedef UIColor *(^MEColorPicker)(void); 13 | typedef CGColorRef (^MECGColorPicker)(void); 14 | 15 | @interface UIColor (Theme) 16 | + (UIColor *)me_colorWithHexString:(NSString *) hexString; 17 | #pragma mark - binding property 18 | + (MEColorPicker)me_colorPickerForMode:(NSString *)mode; 19 | 20 | #pragma mark - CGColor 21 | + (MECGColorPicker)me_cgcolorPickerWithMode:(NSString *)mode; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/Core/UIColor+Theme.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+Theme.m 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "UIColor+Theme.h" 10 | #import "METhemeManager.h" 11 | #import "NSObject+Theme.h" 12 | @implementation UIColor (Theme) 13 | + (UIColor *)me_colorWithHexString:(NSString *) hexString 14 | { 15 | if (!hexString) { 16 | return nil; 17 | } 18 | NSString *colorString = [[hexString stringByReplacingOccurrencesOfString: @"#" withString: @""] uppercaseString]; 19 | CGFloat alpha, red, blue, green; 20 | switch ([colorString length]) { 21 | case 0: 22 | return nil; 23 | case 3: // #RGB 24 | alpha = 1.0f; 25 | red = [self colorComponentFrom: colorString start: 0 length: 1]; 26 | green = [self colorComponentFrom: colorString start: 1 length: 1]; 27 | blue = [self colorComponentFrom: colorString start: 2 length: 1]; 28 | break; 29 | case 4: // #ARGB 30 | alpha = [self colorComponentFrom: colorString start: 0 length: 1]; 31 | red = [self colorComponentFrom: colorString start: 1 length: 1]; 32 | green = [self colorComponentFrom: colorString start: 2 length: 1]; 33 | blue = [self colorComponentFrom: colorString start: 3 length: 1]; 34 | break; 35 | case 6: // #RRGGBB 36 | alpha = 1.0f; 37 | red = [self colorComponentFrom: colorString start: 0 length: 2]; 38 | green = [self colorComponentFrom: colorString start: 2 length: 2]; 39 | blue = [self colorComponentFrom: colorString start: 4 length: 2]; 40 | break; 41 | case 8: // #AARRGGBB 42 | alpha = [self colorComponentFrom: colorString start: 0 length: 2]; 43 | red = [self colorComponentFrom: colorString start: 2 length: 2]; 44 | green = [self colorComponentFrom: colorString start: 4 length: 2]; 45 | blue = [self colorComponentFrom: colorString start: 6 length: 2]; 46 | break; 47 | default: 48 | alpha = 0, red = 0, blue = 0, green = 0; 49 | break; 50 | } 51 | return [UIColor colorWithRed: red green: green blue: blue alpha: alpha]; 52 | } 53 | + (CGFloat) colorComponentFrom: (NSString *) string start:(NSUInteger) start length:(NSUInteger) length 54 | { 55 | NSString *substring = [string substringWithRange: NSMakeRange(start, length)]; 56 | NSString *fullHex = length == 2 ? substring : [NSString stringWithFormat: @"%@%@", substring, substring]; 57 | unsigned hexComponent; 58 | [[NSScanner scannerWithString: fullHex] scanHexInt: &hexComponent]; 59 | return hexComponent / 255.0; 60 | } 61 | 62 | 63 | 64 | 65 | #pragma mark - binding property 66 | #pragma mark - binding 67 | + (NSString *)getColorForMode:(NSString *)mode { 68 | //这里通过管理类拿到当前主题的配置文件(是一个字典),然后根据key值来获取对应的颜色 69 | NSString *colorStr = [METhemeManager sharedThemeManager].currentThemeConfig[@"Color"][mode]; 70 | return colorStr; 71 | } 72 | + (MEColorPicker)me_colorPickerForMode:(NSString *)mode { 73 | return ^() { 74 | NSString *colorHexStr = [self getColorForMode:mode]; 75 | return [self me_colorWithHexString:colorHexStr]; 76 | }; 77 | } 78 | 79 | 80 | 81 | #pragma mark - CGColor 82 | + (MECGColorPicker)me_cgcolorPickerWithMode:(NSString *)mode { 83 | return ^() { 84 | NSString *colorHexStr = [self getColorForMode:mode]; 85 | UIColor *color = [self me_colorWithHexString:colorHexStr]; 86 | return [color CGColor]; 87 | }; 88 | } 89 | 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/Core/UIImage+Theme.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Theme.h 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIColor+Theme.h" 11 | typedef UIImage *(^MEImagePicker)(void); 12 | typedef NSString *(^MEImageNamePicker)(void); 13 | typedef NSArray *(^MEArrayPicker)(void); 14 | 15 | @interface UIImage (Theme) 16 | + (MEImagePicker)me_imageNamed:(NSString *)name; 17 | 18 | 19 | + (MEImagePicker)me_imageNamed:(NSString *)name 20 | resizableImageWithCapInsets:(UIEdgeInsets)capInsets; 21 | 22 | + (MEImagePicker)me_imageNamed:(NSString *)name 23 | resizableImageWithCapInsets:(UIEdgeInsets)capInsets 24 | resizingMode:(UIImageResizingMode)resizingMode; 25 | 26 | + (UIImage *)me_createImageFromColor:(MEColorPicker)colorPicker; 27 | @end 28 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/Core/UIImage+Theme.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Theme.m 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "UIImage+Theme.h" 10 | #import "METhemeManager.h" 11 | @implementation UIImage (Theme) 12 | +(MEImagePicker)me_imageNamed:(NSString *)name { 13 | return ^() { 14 | //获得主题前缀 15 | NSString *pre = [METhemeManager getImageNamePrefix]; 16 | UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%@%@",pre,name]]; 17 | if (image) { 18 | return image; 19 | }else { 20 | //如果根据前缀没有读取到图片,则读取原始图片 21 | return [UIImage imageNamed:name]; 22 | } 23 | }; 24 | } 25 | +(MEImagePicker)me_imageNamed:(NSString *)name 26 | resizableImageWithCapInsets:(UIEdgeInsets)capInsets{ 27 | return ^() { 28 | NSString *pre = [METhemeManager getImageNamePrefix]; 29 | UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%@%@",pre,name]]; 30 | 31 | if (image) { 32 | UIImage *resiableImage = [image resizableImageWithCapInsets:capInsets]; 33 | return resiableImage; 34 | }else { 35 | UIImage *defaultImage = [UIImage imageNamed:name]; 36 | UIImage *resiableImage = [defaultImage resizableImageWithCapInsets:capInsets]; 37 | return resiableImage; 38 | } 39 | }; 40 | } 41 | 42 | +(MEImagePicker)me_imageNamed:(NSString *)name 43 | resizableImageWithCapInsets:(UIEdgeInsets)capInsets 44 | resizingMode:(UIImageResizingMode)resizingMode { 45 | return ^() { 46 | NSString *pre = [METhemeManager getImageNamePrefix]; 47 | UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%@%@",pre,name]]; 48 | 49 | if (image) { 50 | UIImage *resiableImage = [image resizableImageWithCapInsets:capInsets resizingMode:resizingMode]; 51 | return resiableImage; 52 | }else { 53 | UIImage *defaultImage = [UIImage imageNamed:name]; 54 | UIImage *resiableImage = [defaultImage resizableImageWithCapInsets:capInsets resizingMode:resizingMode]; 55 | return resiableImage; 56 | } 57 | }; 58 | } 59 | 60 | + (UIImage *)me_createImageFromColor:(MEColorPicker)colorPicker { 61 | UIColor *color = colorPicker(); 62 | if (!color) { 63 | return nil; 64 | } 65 | CGRect rect = CGRectMake(0, 0, 1, 1); 66 | UIGraphicsBeginImageContext(rect.size); 67 | CGContextRef context = UIGraphicsGetCurrentContext(); 68 | CGContextSetFillColorWithColor(context, color.CGColor); 69 | CGContextFillRect(context, rect); 70 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 71 | UIGraphicsEndImageContext(); 72 | return image; 73 | } 74 | @end 75 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/DeallocBlock/MEDeallocBlockExecutor.h: -------------------------------------------------------------------------------- 1 | // 2 | // MEDeallocBlockExecutor.h 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/7. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | /** 9 | * MEDeallocBlockExecutor初始化一个回调,在MEDeallocBlockExecutor释放的时候会进行回调 10 | 用于NSObject注销通知 11 | * 12 | */ 13 | 14 | #import 15 | typedef void(^DeallocBlock)(void); 16 | @interface MEDeallocBlockExecutor : NSObject 17 | 18 | - (instancetype)initWith:(DeallocBlock)deallocBlock; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/DeallocBlock/MEDeallocBlockExecutor.m: -------------------------------------------------------------------------------- 1 | // 2 | // MEDeallocBlockExecutor.m 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/7. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "MEDeallocBlockExecutor.h" 10 | @interface MEDeallocBlockExecutor() 11 | @property (nonatomic, copy) DeallocBlock deallocBlock; 12 | @end 13 | @implementation MEDeallocBlockExecutor 14 | - (instancetype)initWith:(DeallocBlock)deallocBlock{ 15 | self = [super init]; 16 | if (self) { 17 | self.deallocBlock = deallocBlock; 18 | } 19 | return self; 20 | } 21 | -(void)dealloc{ 22 | if (self.deallocBlock) { 23 | self.deallocBlock(); 24 | self.deallocBlock = nil; 25 | } 26 | } 27 | @end 28 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/DeallocBlock/NSObject+DeallocBlock.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+DeallocBlock.h 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/7. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | /** 10 | * 给主题NSObject扩展添加一个MEDeallocBlockExecutor成员变量,在NSObject释放内存的时候, 11 | deallocHelperExecutor也会释放,deallocHelperExecutor释放的时候会调用回调注销通知 12 | * 13 | */ 14 | #import 15 | #import "MEDeallocBlockExecutor.h" 16 | @interface NSObject (DeallocBlock) 17 | /** 18 | * deallocHelperExecutor是一个继承于NSObject的类,主要作用就是使用它的dealloc事件移除通知 19 | */ 20 | @property (nonatomic, strong)MEDeallocBlockExecutor *deallocHelperExecutor; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/DeallocBlock/NSObject+DeallocBlock.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+DeallocBlock.m 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/7. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "NSObject+DeallocBlock.h" 10 | #import 11 | @implementation NSObject (DeallocBlock) 12 | - (MEDeallocBlockExecutor *)deallocHelperExecutor{ 13 | return objc_getAssociatedObject(self, @selector(deallocHelperExecutor)); 14 | } 15 | - (void)setDeallocHelperExecutor:(MEDeallocBlockExecutor *)deallocHelperExecutor{ 16 | objc_setAssociatedObject(self, @selector(deallocHelperExecutor), deallocHelperExecutor, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/METhemeKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // METhemeKit.h 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #ifndef METhemeKit_h 10 | #define METhemeKit_h 11 | #import "METhemeManager.h" 12 | #import "ThemeProperties.h" 13 | 14 | #import "NSObject+Theme.h" 15 | #import "UIView+Theme.h" 16 | #import "UILabel+Theme.h" 17 | #import "UIButton+Theme.h" 18 | #import "UIImageView+Theme.h" 19 | #import "UINavigationBar+Theme.h" 20 | #import "CALayer+Theme.h" 21 | #endif 22 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/ThemeData/ThemeDefault.json: -------------------------------------------------------------------------------- 1 | { 2 | "Color":{ 3 | "ThemeColorMode_Default":"03A9F4", 4 | "ThemeColorMode_Default_Highlight":"13689C" 5 | }, 6 | "UINavigationBar": { 7 | "NavBarDefault":{ 8 | "tintColor":"03A9F4", 9 | "backgroundImageColor":"03A9F4", 10 | "shadowImageColor":"", 11 | "titleLabelColor":"FFFFFF" 12 | }, 13 | "NavBarLevel1":{ 14 | "tintColor":"03A9F4", 15 | "backgroundImageColor":"03A9F4", 16 | "shadowImageColor":"", 17 | "titleLabelColor":"FFFFFF" 18 | } 19 | }, 20 | 21 | "Button":{ 22 | "ThemeMode_Button_SureButton": { 23 | "titleColor": { 24 | "UIControlStateNormal":"FFFFFF", 25 | "UIControlStateHighlight":"FFFFFF", 26 | "UIControlStateDisabled":"FFFFFF", 27 | "UIControlStateSelected":"FFFFFF" 28 | } 29 | }, 30 | "ThemeMode_Button_NoBackgroundImage_SureButton": { 31 | "titleColor": { 32 | "UIControlStateNormal":"03A9F4", 33 | "UIControlStateHighlight":"03A9F4", 34 | "UIControlStateDisabled":"666666", 35 | "UIControlStateSelected":"03A9F4" 36 | } 37 | }, 38 | "ThemeMode_Button_NavBarRight":{ 39 | "titleColor": { 40 | "UIControlStateNormal":"FFFFFF", 41 | "UIControlStateHighlight":"4DFFFFFF", 42 | "UIControlStateDisabled":"7FFFFFFF" 43 | } 44 | }, 45 | "ThemeMode_Button_ExpressAddressSele":{ 46 | "titleColor": { 47 | "UIControlStateNormal":"888888", 48 | "UIControlStateSelected":"7aa0b2" 49 | } 50 | }, 51 | "ThemeModel_Button_PickerView":{ 52 | "titleColor": { 53 | "UIControlStateNormal":"03A9F4", 54 | "UIControlStateHighlight":"4D03A9F4" 55 | } 56 | } 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/ThemeData/ThemeOrange.json: -------------------------------------------------------------------------------- 1 | { 2 | "Color":{ 3 | "ThemeColorMode_Default":"F85825", 4 | "ThemeColorMode_Default_Highlight":"D34D21" 5 | }, 6 | "UINavigationBar": { 7 | "NavBarDefault":{ 8 | "tintColor":"FF6E40", 9 | "backgroundImageColor":"FF6E40", 10 | "shadowImageColor":"00", 11 | "titleLabelColor":"FFFFFF" 12 | }, 13 | "NavBarLevel1":{ 14 | "tintColor":"F8F8F8", 15 | "backgroundImageColor":"F8F8F8", 16 | "shadowImageColor":"4DB2B2B2", 17 | "titleLabelColor":"333333" 18 | } 19 | }, 20 | 21 | "Button":{ 22 | "ThemeMode_Button_SureButton": { 23 | "titleColor": { 24 | "UIControlStateNormal":"FFFFFF", 25 | "UIControlStateHighlight":"FFFFFF", 26 | "UIControlStateDisabled":"FFFFFF", 27 | "UIControlStateSelected":"FFFFFF" 28 | } 29 | }, 30 | "ThemeMode_Button_NoBackgroundImage_SureButton": { 31 | "titleColor": { 32 | "UIControlStateNormal":"F85825", 33 | "UIControlStateHighlight":"F85825", 34 | "UIControlStateDisabled":"666666", 35 | "UIControlStateSelected":"F85825" 36 | } 37 | }, 38 | "ThemeMode_Button_NavBarRight":{ 39 | "titleColor": { 40 | "UIControlStateNormal":"F85825", 41 | "UIControlStateHighlight":"4DF85825", 42 | "UIControlStateDisabled":"7FF85825" 43 | }, 44 | "backgroundColor":"" 45 | }, 46 | "ThemeMode_Button_ExpressAddressSele":{ 47 | "titleColor": { 48 | "UIControlStateNormal":"888888", 49 | "UIControlStateSelected":"D98D2B" 50 | } 51 | }, 52 | "ThemeModel_Button_PickerView":{ 53 | "titleColor": { 54 | "UIControlStateNormal":"03A9F4", 55 | "UIControlStateHighlight":"4D03A9F4" 56 | } 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/ThemeUIKit/UIButton+Theme.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIButton+Theme.h 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIColor+Theme.h" 11 | #import "UIImage+Theme.h" 12 | @interface UIButton (Theme) 13 | 14 | - (void)me_setImage:(_Nullable MEImagePicker)picker forState:(UIControlState)state; 15 | - (void)me_setBackgroundImage:(_Nullable MEImagePicker)picker forState:(UIControlState)state; 16 | - (void)me_setTitleColor:(_Nullable MEColorPicker)picker forState:(UIControlState)state; 17 | 18 | @property (nonatomic, strong,nullable) NSString * me_configKey; 19 | 20 | // 确定按钮要用这个方法 21 | - (void)me_setConfigModeSureButton; 22 | @end 23 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/ThemeUIKit/UIButton+Theme.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIButton+Theme.m 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "UIButton+Theme.h" 10 | #import "ThemeProperties.h" 11 | #import "NSObject+Theme.h" 12 | #import "METhemeManager.h" 13 | #import 14 | @interface UIButton () 15 | 16 | @property (nonatomic, strong) NSMutableDictionary *pickers; 17 | 18 | @end 19 | @implementation UIButton (Theme) 20 | 21 | - (void)me_setImage:(_Nullable MEImagePicker)picker forState:(UIControlState)state { 22 | NSString *key = NSStringFromSelector(@selector(setImage:forState:)); 23 | id dictionary = [self.pickers valueForKey:key]; 24 | if (!dictionary || ![dictionary isKindOfClass:[NSMutableDictionary class]]) { 25 | dictionary = [[NSMutableDictionary alloc] init]; 26 | } 27 | [dictionary setValue:[picker copy] forKey:[NSString stringWithFormat:@"%@", @(state)]]; 28 | if (!picker) { 29 | [self setImage:nil forState:state]; 30 | [self.pickers removeObjectForKey:key]; 31 | } else { 32 | [self setImage:picker() forState:state]; 33 | [self.pickers setValue:dictionary forKey:key]; 34 | } 35 | } 36 | - (void)me_setBackgroundImage:(_Nullable MEImagePicker)picker forState:(UIControlState)state{ 37 | [self setBackgroundImage:picker() forState:state]; 38 | NSString *key = NSStringFromSelector(@selector(setBackgroundImage:forState:)); 39 | id dictionary = [self.pickers valueForKey:key]; 40 | if (!dictionary || ![dictionary isKindOfClass:[NSMutableDictionary class]]) { 41 | dictionary = [[NSMutableDictionary alloc] init]; 42 | } 43 | [dictionary setValue:[picker copy] forKey:[NSString stringWithFormat:@"%@", @(state)]]; 44 | [self.pickers setValue:dictionary forKey:key]; 45 | } 46 | - (void)me_setTitleColor:(_Nullable MEColorPicker)picker forState:(UIControlState)state{ 47 | [self setTitleColor:picker() forState:state]; 48 | NSString *key = NSStringFromSelector(@selector(setTitleColor:forState:)); 49 | id dictionary = [self.pickers valueForKey:key]; 50 | if (!dictionary || ![dictionary isKindOfClass:[NSMutableDictionary class]]) { 51 | dictionary = [[NSMutableDictionary alloc] init]; 52 | } 53 | [dictionary setValue:[picker copy] forKey:[NSString stringWithFormat:@"%@", @(state)]]; 54 | [self.pickers setValue:dictionary forKey:key]; 55 | } 56 | 57 | - (void)changeTheme{ 58 | [self.pickers enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull selector, id _Nonnull obj, BOOL * _Nonnull stop) { 59 | if ([obj isKindOfClass:[NSDictionary class]]) { 60 | NSDictionary *dictionary = (NSDictionary *)obj; 61 | [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, MEPicker _Nonnull picker, BOOL * _Nonnull stop) { 62 | UIControlState state = [key integerValue]; 63 | [UIView animateWithDuration:METhemeAnimationDuration 64 | animations:^{ 65 | if ([selector isEqualToString:NSStringFromSelector(@selector(setTitleColor:forState:))]) { 66 | UIColor *resultColor = picker(); 67 | [self setTitleColor:resultColor forState:state]; 68 | } else if ([selector isEqualToString:NSStringFromSelector(@selector(setBackgroundImage:forState:))]) { 69 | UIImage *resultImage = ((MEImagePicker)picker)(); 70 | [self setBackgroundImage:resultImage forState:state]; 71 | } else if ([selector isEqualToString:NSStringFromSelector(@selector(setImage:forState:))]) { 72 | UIImage *resultImage = ((MEImagePicker)picker)(); 73 | [self setImage:resultImage forState:state]; 74 | } 75 | }]; 76 | }]; 77 | } else { 78 | SEL sel = NSSelectorFromString(selector); 79 | id result = ((MEPicker)obj)(); 80 | [UIView animateWithDuration:METhemeAnimationDuration 81 | animations:^{ 82 | #pragma clang diagnostic push 83 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 84 | [self performSelector:sel withObject:result]; 85 | #pragma clang diagnostic pop 86 | }]; 87 | 88 | } 89 | }]; 90 | } 91 | 92 | - (void)me_setConfigModeSureButton { 93 | self.me_configKey = ThemeMode_Button_Sure; 94 | 95 | 96 | UIImageResizingMode resizingMode = UIImageResizingModeStretch; 97 | 98 | MEImagePicker imagePickerNormal = [UIImage me_imageNamed:@"button_sure_normal" resizableImageWithCapInsets:ThemeMode_Button_Sure_CapInsets resizingMode:resizingMode]; 99 | [self me_setBackgroundImage:imagePickerNormal forState:UIControlStateNormal]; 100 | 101 | MEImagePicker imagePickerHighlighted = [UIImage me_imageNamed:@"button_sure_highlight" resizableImageWithCapInsets:ThemeMode_Button_Sure_CapInsets resizingMode:resizingMode]; 102 | [self me_setBackgroundImage:imagePickerHighlighted forState:UIControlStateHighlighted]; 103 | 104 | UIImage *imagePickerDisabled = [[UIImage imageNamed:@"button_sure_disabled"] resizableImageWithCapInsets:ThemeMode_Button_Sure_CapInsets resizingMode:resizingMode]; 105 | [self setBackgroundImage:imagePickerDisabled forState:UIControlStateDisabled]; 106 | } 107 | 108 | 109 | - (NSString *)me_configKey { 110 | return objc_getAssociatedObject(self, @selector(me_configKey)); 111 | } 112 | 113 | -(void)setMe_configKey:(NSString *)me_configKey { 114 | objc_setAssociatedObject(self, @selector(me_configKey), me_configKey, OBJC_ASSOCIATION_COPY_NONATOMIC); 115 | [self me_setButtonConfigWithMode:me_configKey]; 116 | 117 | } 118 | - (void)me_setButtonConfigWithMode:( NSString * _Nullable )mode { 119 | if ([mode isEqualToString:ThemeMode_Button_NavBarRight]) { 120 | [self.titleLabel setFont:[UIFont systemFontOfSize:16]]; 121 | } 122 | [self me_ButtonTitleColorForMode:mode withState:UIControlStateNormal]; 123 | [self me_ButtonTitleColorForMode:mode withState:UIControlStateHighlighted]; 124 | [self me_ButtonTitleColorForMode:mode withState:UIControlStateDisabled]; 125 | [self me_ButtonTitleColorForMode:mode withState:UIControlStateSelected]; 126 | } 127 | 128 | #pragma mark - GET Color 129 | - (MEColorPicker)getButtonTitleColorForMode:(NSString *)mode withState:(UIControlState)state{ 130 | return ^() { 131 | NSString *colorHexStr = [METhemeManager sharedThemeManager].currentThemeConfig[@"Button"][mode][@"titleColor"][[self buttonControlStateToStr:state]]; 132 | UIColor *color = [UIColor me_colorWithHexString:colorHexStr]; 133 | if (color == nil) { 134 | color = [self titleColorForState:state]; 135 | } 136 | return color; 137 | }; 138 | } 139 | - (void)me_ButtonTitleColorForMode:(NSString *)mode withState:(UIControlState)state{ 140 | MEColorPicker colorPicker = [self getButtonTitleColorForMode:mode withState:state]; 141 | [self me_setTitleColor:colorPicker forState:state]; 142 | } 143 | - (NSString *)buttonControlStateToStr:(UIControlState)state{ 144 | NSString *str = @"UIControlStateNormal"; 145 | switch (state) { 146 | case UIControlStateHighlighted: 147 | str = @"UIControlStateHighlight"; 148 | break; 149 | case UIControlStateDisabled: 150 | str = @"UIControlStateDisabled"; 151 | break; 152 | case UIControlStateSelected: 153 | str = @"UIControlStateSelected"; 154 | break; 155 | default: 156 | break; 157 | } 158 | return str; 159 | } 160 | @end 161 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/ThemeUIKit/UIImageView+Theme.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+Theme.h 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIImage+Theme.h" 11 | @interface UIImageView (Theme) 12 | @property (nonatomic,copy)MEImagePicker me_image; 13 | - (instancetype)me_initWithImage:(MEImagePicker)imagePicker; 14 | @end 15 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/ThemeUIKit/UIImageView+Theme.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImageView+Theme.m 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "UIImageView+Theme.h" 10 | #import "NSObject+Theme.h" 11 | #import 12 | 13 | @implementation UIImageView (Theme) 14 | - (instancetype)me_initWithImage:(MEImagePicker)imagePicker{ 15 | if ([self initWithImage:imagePicker()]) { 16 | [self.pickers setObject:[imagePicker copy] forKey:@"setImage:"]; 17 | return self; 18 | } 19 | return nil; 20 | } 21 | -(MEImagePicker)me_image{ 22 | return objc_getAssociatedObject(self, @selector(me_image)); 23 | } 24 | 25 | -(void)setMe_image:(MEImagePicker)me_image{ 26 | objc_setAssociatedObject(self, @selector(me_image), me_image, OBJC_ASSOCIATION_COPY_NONATOMIC); 27 | self.image = me_image(); 28 | [self.pickers setObject:[me_image copy] forKey:@"setImage:"]; 29 | } 30 | 31 | @end 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/ThemeUIKit/UILabel+Theme.h: -------------------------------------------------------------------------------- 1 | // 2 | // UILabel+Theme.h 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIColor+Theme.h" 11 | 12 | @interface UILabel (Theme) 13 | @property (nonatomic,copy)MEColorPicker me_textColor; 14 | @end 15 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/ThemeUIKit/UILabel+Theme.m: -------------------------------------------------------------------------------- 1 | // 2 | // UILabel+Theme.m 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/12. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "UILabel+Theme.h" 10 | #import "NSObject+Theme.h" 11 | #import 12 | 13 | @implementation UILabel (Theme) 14 | -(MEColorPicker)me_textColor{ 15 | return objc_getAssociatedObject(self, @selector(me_textColor)); 16 | } 17 | -(void)setMe_textColor:(MEColorPicker)me_textColor{ 18 | //注册新属性的set方法 19 | objc_setAssociatedObject(self, @selector(me_textColor), me_textColor, OBJC_ASSOCIATION_COPY_NONATOMIC); 20 | //调用原始的方法 21 | self.textColor = me_textColor(); 22 | //保存主题填充的操作,将(MEColorPicker)me_textColor参数和"setTextColor:"方法绑定保存 23 | [self.pickers setValue:[me_textColor copy] forKey:@"setTextColor:"]; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/ThemeUIKit/UINavigationBar+Theme.h: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBar+Theme.h 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/13. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIColor+Theme.h" 11 | typedef NS_ENUM(NSUInteger,NavBarType) { 12 | NavBarDefault = 0, 13 | NavBarLevel1 14 | }; 15 | @interface UINavigationBar (Theme) 16 | - (void)me_setBackgroundImageForBarMetrics:(UIBarMetrics)barMetrics WithType:(NavBarType)navType; 17 | - (void)me_setShadowImageForType:(NavBarType)navType; 18 | #pragma mark TitleColor 19 | - (MEColorPicker)me_navBarTitleColorWithType:(NavBarType)navBarType; 20 | @end 21 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/ThemeUIKit/UINavigationBar+Theme.m: -------------------------------------------------------------------------------- 1 | // 2 | // UINavigationBar+Theme.m 3 | // ThemeDemo 4 | // 5 | // Created by ss on 16/1/13. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "UINavigationBar+Theme.h" 10 | #import "ThemeProperties.h" 11 | #import "METhemeManager.h" 12 | #import "NSObject+Theme.h" 13 | #import "UIImage+Theme.h" 14 | #import 15 | @interface UINavigationBar () 16 | 17 | @property (nonatomic, strong) NSMutableDictionary *pickers; 18 | 19 | @end 20 | @implementation UINavigationBar (Theme) 21 | - (void)me_setShadowImageForType:(NavBarType)navType{ 22 | MEColorPicker picker = [self me_navBarShadowImageColorWithType:navType]; 23 | self.shadowImage = [UIImage me_createImageFromColor:picker]; 24 | [self.pickers setValue:[picker copy] forKey:@"setShadowImage:"]; 25 | } 26 | - (void)me_setBackgroundImageForBarMetrics:(UIBarMetrics)barMetrics WithType:(NavBarType)navType{ 27 | NSString *key = [NSString stringWithFormat:@"%@", @(barMetrics)]; 28 | MEColorPicker colorPicker = [self me_NavBarBackgroundColor:navType]; 29 | [self setBackgroundImage:[UIImage me_createImageFromColor:colorPicker] forBarMetrics:barMetrics]; 30 | id dictionary = [self.pickers valueForKey:key]; 31 | if (!dictionary || ![dictionary isKindOfClass:[NSMutableDictionary class]]) { 32 | dictionary = [[NSMutableDictionary alloc] init]; 33 | } 34 | [dictionary setValue:[colorPicker copy] forKey:NSStringFromSelector(@selector(setBackgroundImage:forBarMetrics:))]; 35 | [self.pickers setValue:dictionary forKey:key]; 36 | } 37 | - (void)changeTheme{ 38 | [self.pickers enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { 39 | if ([obj isKindOfClass:[NSDictionary class]]) { 40 | NSDictionary *dictionary = (NSDictionary *)obj; 41 | [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull selector, MEPicker _Nonnull picker, BOOL * _Nonnull stop) { 42 | UIBarMetrics state = [key integerValue]; 43 | [UIView animateWithDuration:METhemeAnimationDuration 44 | animations:^{ 45 | if ([selector isEqualToString:NSStringFromSelector(@selector(setBackgroundImage:forBarMetrics:))]) { 46 | UIImage *resultImage = ([UIImage me_createImageFromColor:(MEColorPicker)picker]); 47 | [self setBackgroundImage:resultImage forBarMetrics:state]; 48 | } 49 | }]; 50 | }]; 51 | } else { 52 | if ([key isEqualToString:NSStringFromSelector(@selector(setShadowImage:))]) { 53 | MEColorPicker picker = obj; 54 | self.shadowImage = [UIImage me_createImageFromColor:picker]; 55 | } else{ 56 | SEL sel = NSSelectorFromString(key); 57 | MEPicker picker = (MEPicker)obj; 58 | id result = picker(); 59 | [UIView animateWithDuration:METhemeAnimationDuration 60 | animations:^{ 61 | #pragma clang diagnostic push 62 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks" 63 | [self performSelector:sel withObject:result]; 64 | #pragma clang diagnostic pop 65 | }]; 66 | } 67 | 68 | 69 | } 70 | }]; 71 | } 72 | #pragma mark - GET Color 73 | #warning 如果NavBarType更新这里也要更改 74 | - (NSString *)navBarTypeToStr:(NavBarType)navBarType{ 75 | NSString *str = @"NavBarDefault"; 76 | switch (navBarType) { 77 | case NavBarLevel1: 78 | str = @"NavBarLevel1"; 79 | break; 80 | default: 81 | break; 82 | } 83 | return str; 84 | } 85 | 86 | #pragma mark BackgroundImageColor 87 | - (MEColorPicker)me_NavBarBackgroundColor:(NavBarType)navBarType{ 88 | return ^() { 89 | NSString *colorHexStr = [METhemeManager sharedThemeManager].currentThemeConfig[@"UINavigationBar"][[self navBarTypeToStr:navBarType]][@"backgroundImageColor"]; 90 | return [UIColor me_colorWithHexString:colorHexStr]; 91 | }; 92 | } 93 | #pragma mark BarShadowImageColor 94 | - (MEColorPicker)me_navBarShadowImageColorWithType:(NavBarType)navBarType{ 95 | return ^() { 96 | NSString *colorHexStr = [METhemeManager sharedThemeManager].currentThemeConfig[@"UINavigationBar"][[self navBarTypeToStr:navBarType]][@"shadowImageColor"]; 97 | return [UIColor me_colorWithHexString:colorHexStr]; 98 | }; 99 | } 100 | 101 | #pragma mark TitleColor 102 | - (MEColorPicker)me_navBarTitleColorWithType:(NavBarType)navBarType{ 103 | return ^() { 104 | NSString *colorHexStr = [METhemeManager sharedThemeManager].currentThemeConfig[@"UINavigationBar"][[self navBarTypeToStr:navBarType]][@"titleLabelColor"]; 105 | return [UIColor me_colorWithHexString:colorHexStr]; 106 | }; 107 | } 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/ThemeUIKit/UIView+Theme.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Theme.h 3 | // neighborhood 4 | // 5 | // Created by ss on 16/1/18. 6 | // Copyright © 2016年 iYaYa. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIColor+Theme.h" 11 | @interface UIView (Theme) 12 | @property (nonatomic, copy) MEColorPicker me_backgroundColor; 13 | @end 14 | -------------------------------------------------------------------------------- /METhemeKit/METhemeKit/ThemeUIKit/UIView+Theme.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Theme.m 3 | // neighborhood 4 | // 5 | // Created by ss on 16/1/18. 6 | // Copyright © 2016年 iYaYa. All rights reserved. 7 | // 8 | 9 | #import "UIView+Theme.h" 10 | #import "NSObject+Theme.h" 11 | #import 12 | @implementation UIView (Theme) 13 | - (MEColorPicker)me_backgroundColor{ 14 | return objc_getAssociatedObject(self, @selector(me_backgroundColor)); 15 | } 16 | - (void)setMe_backgroundColor:(MEColorPicker)me_backgroundColor{ 17 | objc_setAssociatedObject(self, @selector(me_backgroundColor), me_backgroundColor, OBJC_ASSOCIATION_COPY_NONATOMIC); 18 | self.backgroundColor = me_backgroundColor(); 19 | [self.pickers setValue:[me_backgroundColor copy] forKey:@"setBackgroundColor:"]; 20 | } 21 | @end 22 | -------------------------------------------------------------------------------- /METhemeKit/SecondViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.h 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/4. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "BaseViewController.h" 10 | 11 | @interface SecondViewController : BaseViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /METhemeKit/SecondViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.m 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/4. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import "SecondViewController.h" 10 | #import "METhemeKit.h" 11 | @interface SecondViewController () 12 | 13 | @end 14 | 15 | @implementation SecondViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | // Do any additional setup after loading the view. 20 | self.view.backgroundColor = [UIColor whiteColor]; 21 | 22 | UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(20, 80, 120, 30)]; 23 | label.text = @"测试通知释放"; 24 | label.me_textColor = [UIColor me_colorPickerForMode:ThemeColorMode_Default]; 25 | [self.view addSubview:label]; 26 | } 27 | 28 | - (void)didReceiveMemoryWarning { 29 | [super didReceiveMemoryWarning]; 30 | // Dispose of any resources that can be recreated. 31 | } 32 | 33 | /* 34 | #pragma mark - Navigation 35 | 36 | // In a storyboard-based application, you will often want to do a little preparation before navigation 37 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 38 | // Get the new view controller using [segue destinationViewController]. 39 | // Pass the selected object to the new view controller. 40 | } 41 | */ 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /METhemeKit/Supporting Files/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // METhemeKit 4 | // 5 | // Created by Yasin on 16/3/4. 6 | // Copyright © 2016年 Yasin. 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 | -------------------------------------------------------------------------------- /METhemeKitTests/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /METhemeKitTests/METhemeKitTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // METhemeKitTests.m 3 | // METhemeKitTests 4 | // 5 | // Created by Yasin on 16/3/4. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface METhemeKitTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation METhemeKitTests 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 | -------------------------------------------------------------------------------- /METhemeKitUITests/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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /METhemeKitUITests/METhemeKitUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // METhemeKitUITests.m 3 | // METhemeKitUITests 4 | // 5 | // Created by Yasin on 16/3/4. 6 | // Copyright © 2016年 Yasin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface METhemeKitUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation METhemeKitUITests 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # METhemeKit 2 | iOS多主题切换框架,基于DKNightVersion白天黑夜主题切换,更改为支持更多主题 3 | [iOS主题切换框架设计demo教程](http://www.jianshu.com/p/440eece9ac16) 4 | 5 | [DKNightVersion连接](https://github.com/Draveness/DKNightVersion) --------------------------------------------------------------------------------