├── WHC_ModelApp └── WHC_DataModelFactory.app │ └── Contents │ ├── PkgInfo │ ├── Resources │ ├── oc.png │ ├── dict.png │ ├── swift.png │ ├── AppIcon.icns │ └── Base.lproj │ │ └── Main.storyboardc │ │ ├── Info.plist │ │ ├── MainMenu.nib │ │ ├── XfG-lQ-9wD-view-m2S-Jp-Qdl.nib │ │ └── NSWindowController-B8D-0N-5wS.nib │ ├── MacOS │ └── WHC_DataModelFactory │ ├── Info.plist │ └── _CodeSignature │ └── CodeResources ├── WHC_DataModelFactory ├── xx.png ├── images │ ├── oc.png │ ├── dict.png │ └── swift.png ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── icon_16x16.png │ │ ├── icon_32x32.png │ │ ├── icon_128x128.png │ │ ├── icon_16x16@2x.png │ │ ├── icon_256x256.png │ │ ├── icon_32x32@2x.png │ │ ├── icon_512x512.png │ │ ├── icon_128x128@2x.png │ │ ├── icon_256x256@2x.png │ │ ├── icon_512x512@2x.png │ │ └── Contents.json ├── main.m ├── WHC_AutoLayoutKit │ ├── WHC_AutoLayoutUtilities.h │ ├── WHC_AutoLayout.h │ ├── UIView+WHC_Frame.h │ ├── UITableViewCell+WHC_AutoHeightForCell.h │ ├── WHC_StackView.h │ ├── UIView+WHC_Frame.m │ ├── UITableViewCell+WHC_AutoHeightForCell.m │ ├── UIView+WHC_AutoLayout.h │ └── WHC_StackView.m ├── Info.plist ├── ViewController.h ├── AppDelegate.h ├── WHCLib │ ├── WHC_XMLParser.h │ └── WHC_XMLParser.m ├── AppDelegate.m └── ViewController.m ├── WHC_DataModelFactory.xcodeproj ├── xcuserdata │ ├── WHC.xcuserdatad │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ │ ├── xcschememanagement.plist │ │ │ └── WHC_DataModelFactory.xcscheme │ └── wuhaichao.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── WHC_DataModelFactory.xcscheme ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ ├── WHC.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ │ └── wuhaichao.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcshareddata │ │ └── WHC_DataModelFactory.xccheckout └── project.pbxproj ├── WHC_DataModelFactoryTests ├── Info.plist └── WHC_DataModelFactoryTests.m ├── LICENSE └── README.md /WHC_ModelApp/WHC_DataModelFactory.app/Contents/PkgInfo: -------------------------------------------------------------------------------- 1 | APPL???? -------------------------------------------------------------------------------- /WHC_DataModelFactory/xx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory/xx.png -------------------------------------------------------------------------------- /WHC_DataModelFactory/images/oc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory/images/oc.png -------------------------------------------------------------------------------- /WHC_DataModelFactory/images/dict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory/images/dict.png -------------------------------------------------------------------------------- /WHC_DataModelFactory/images/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory/images/swift.png -------------------------------------------------------------------------------- /WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/oc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/oc.png -------------------------------------------------------------------------------- /WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/dict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/dict.png -------------------------------------------------------------------------------- /WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/swift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/swift.png -------------------------------------------------------------------------------- /WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/AppIcon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/AppIcon.icns -------------------------------------------------------------------------------- /WHC_DataModelFactory.xcodeproj/xcuserdata/WHC.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_16x16.png -------------------------------------------------------------------------------- /WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_32x32.png -------------------------------------------------------------------------------- /WHC_DataModelFactory.xcodeproj/xcuserdata/wuhaichao.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_128x128.png -------------------------------------------------------------------------------- /WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_16x16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_16x16@2x.png -------------------------------------------------------------------------------- /WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_256x256.png -------------------------------------------------------------------------------- /WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_32x32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_32x32@2x.png -------------------------------------------------------------------------------- /WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_512x512.png -------------------------------------------------------------------------------- /WHC_ModelApp/WHC_DataModelFactory.app/Contents/MacOS/WHC_DataModelFactory: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_ModelApp/WHC_DataModelFactory.app/Contents/MacOS/WHC_DataModelFactory -------------------------------------------------------------------------------- /WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_128x128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_128x128@2x.png -------------------------------------------------------------------------------- /WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_256x256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_256x256@2x.png -------------------------------------------------------------------------------- /WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_512x512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/icon_512x512@2x.png -------------------------------------------------------------------------------- /WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/Base.lproj/Main.storyboardc/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/Base.lproj/Main.storyboardc/Info.plist -------------------------------------------------------------------------------- /WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/Base.lproj/Main.storyboardc/MainMenu.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/Base.lproj/Main.storyboardc/MainMenu.nib -------------------------------------------------------------------------------- /WHC_DataModelFactory.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WHC_DataModelFactory.xcodeproj/project.xcworkspace/xcuserdata/WHC.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory.xcodeproj/project.xcworkspace/xcuserdata/WHC.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WHC_DataModelFactory.xcodeproj/project.xcworkspace/xcuserdata/wuhaichao.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_DataModelFactory.xcodeproj/project.xcworkspace/xcuserdata/wuhaichao.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/Base.lproj/Main.storyboardc/XfG-lQ-9wD-view-m2S-Jp-Qdl.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/Base.lproj/Main.storyboardc/XfG-lQ-9wD-view-m2S-Jp-Qdl.nib -------------------------------------------------------------------------------- /WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/Base.lproj/Main.storyboardc/NSWindowController-B8D-0N-5wS.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netyouli/WHC_DataModelFactory/HEAD/WHC_ModelApp/WHC_DataModelFactory.app/Contents/Resources/Base.lproj/Main.storyboardc/NSWindowController-B8D-0N-5wS.nib -------------------------------------------------------------------------------- /WHC_DataModelFactory/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WHC_DataModelFactory 4 | // 5 | // Created by 吴海超 on 15/4/30. 6 | // Copyright (c) 2015年 吴海超. All rights reserved. 7 | // 8 | /* 9 | * qq:712641411 10 | * iOS大神qq群:460122071 11 | * gitHub:https://github.com/netyouli 12 | * csdn:http://blog.csdn.net/windwhc/article/category/3117381 13 | */ 14 | #import 15 | 16 | int main(int argc, const char * argv[]) { 17 | return NSApplicationMain(argc, argv); 18 | } 19 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/WHC_AutoLayoutKit/WHC_AutoLayoutUtilities.h: -------------------------------------------------------------------------------- 1 | // 2 | // WHC_AutoLayoutUtilities.h 3 | // WHC_AutoLayoutKit 4 | // 5 | // Created by WHC on 17/4/12. 6 | // Copyright © 2017年 WHC. All rights reserved. 7 | // 8 | 9 | #import 10 | #if TARGET_OS_IPHONE || TARGET_OS_TV 11 | 12 | #define WHC_VIEW UIView 13 | #define WHC_LayoutPriority UILayoutPriority 14 | #define WHC_COLOR UIColor 15 | #import 16 | 17 | #elif TARGET_OS_MAC 18 | 19 | #define WHC_VIEW NSView 20 | #define WHC_LayoutPriority NSLayoutPriority 21 | #define WHC_COLOR NSColor 22 | #import 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /WHC_DataModelFactory.xcodeproj/xcuserdata/WHC.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WHC_DataModelFactory.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | C3D4D7FB1AF1D769004DE109 16 | 17 | primary 18 | 19 | 20 | C3D4D8111AF1D769004DE109 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /WHC_DataModelFactory.xcodeproj/xcuserdata/wuhaichao.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WHC_DataModelFactory.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | C3D4D7FB1AF1D769004DE109 16 | 17 | primary 18 | 19 | 20 | C3D4D8111AF1D769004DE109 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /WHC_DataModelFactoryTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | WHC.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.8.8 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.8.8 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 吴海超 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | WHC.$(PRODUCT_NAME:rfc1034identifier) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | WHC_ModelFactory 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2015年 吴海超. All rights reserved. 29 | NSMainStoryboardFile 30 | Main 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WHC_ModelFactory iOS开发高效辅助工具!(Version:1.9.0) 2 | 3 | 简介 4 | ============== 5 | - **高效**: 自动把json或者xml字符串自动生成模型类文件内容 6 | - **准确**: 避免手工创建模型类的麻烦和高错误率(提高开发效率) 7 | - **处理**: 自动生成类名称首字符大写属性名首字母小写 8 | - **兼容**: 支持xml/json字符串和dictionary字符串 9 | 10 | [JavaScript 版本](https://github.com/netyouli/jsonToClass) 11 | 12 | 更新:**生成[SexyJson](https://github.com/netyouli/SexyJson)模型类支持<<<格式对齐** 13 | 14 | 效果 15 | ============== 16 | * Swift 17 | 18 | 19 | * Objective-C 20 | 21 | 22 | 推荐 23 | ============== 24 | * iOS平台Sqlite ORM库: [ModelSqliteKit](https://github.com/netyouli/WHC_ModelSqliteKit) 25 | 26 | 使用 27 | ============== 28 | * 打开WHC_ModelApp目录app双击或者复制到应用程序文件夹 29 | * 运行该工程生成WHC_DataModelFactory.App 复制到应用程序文件夹 30 | 31 | 要求 32 | ============== 33 | * mac os x 10.7 or later 34 | * Xcode 8.0 or later 35 | 36 | ## 期待 37 | 38 | - 如果您在使用过程中有任何问题,欢迎issue me! 很乐意为您解答任何相关问题! 39 | - 与其给我点star,不如向我狠狠地抛来一个BUG! 40 | - 如果您想要更多的接口来自定义或者建议/意见,欢迎issue me!我会根据大家的需求提供更多的功能! 41 | 42 | ## Licenses 43 | All source code is licensed under the MIT License. 44 | -------------------------------------------------------------------------------- /WHC_DataModelFactoryTests/WHC_DataModelFactoryTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // WHC_DataModelFactoryTests.m 3 | // WHC_DataModelFactoryTests 4 | // 5 | // Created by 吴海超 on 15/4/30. 6 | // Copyright (c) 2015年 吴海超. All rights reserved. 7 | // 8 | /* 9 | * qq:712641411 10 | * iOS大神qq群:460122071 11 | * gitHub:https://github.com/netyouli 12 | * csdn:http://blog.csdn.net/windwhc/article/category/3117381 13 | */ 14 | #import 15 | #import 16 | 17 | @interface WHC_DataModelFactoryTests : XCTestCase 18 | 19 | @end 20 | 21 | @implementation WHC_DataModelFactoryTests 22 | 23 | - (void)setUp { 24 | [super setUp]; 25 | // Put setup code here. This method is called before the invocation of each test method in the class. 26 | } 27 | 28 | - (void)tearDown { 29 | // Put teardown code here. This method is called after the invocation of each test method in the class. 30 | [super tearDown]; 31 | } 32 | 33 | - (void)testExample { 34 | // This is an example of a functional test case. 35 | XCTAssert(YES, @"Pass"); 36 | } 37 | 38 | - (void)testPerformanceExample { 39 | // This is an example of a performance test case. 40 | [self measureBlock:^{ 41 | // Put the code you want to measure the time of here. 42 | }]; 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // WHC_DataModelFactory 4 | // 5 | // Created by 吴海超 on 15/4/30. 6 | // Copyright (c) 2015年 吴海超. All rights reserved. 7 | // 8 | 9 | // Github 10 | 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in 20 | // all copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | // THE SOFTWARE. 29 | 30 | 31 | #import 32 | 33 | @interface ViewController : NSViewController 34 | 35 | 36 | @end 37 | 38 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WHC_DataModelFactory 4 | // 5 | // Created by 吴海超 on 15/4/30. 6 | // Copyright (c) 2015年 吴海超. All rights reserved. 7 | // 8 | 9 | 10 | // Github 11 | 12 | // 13 | // Permission is hereby granted, free of charge, to any person obtaining a copy 14 | // of this software and associated documentation files (the "Software"), to deal 15 | // in the Software without restriction, including without limitation the rights 16 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | // copies of the Software, and to permit persons to whom the Software is 18 | // furnished to do so, subject to the following conditions: 19 | // 20 | // The above copyright notice and this permission notice shall be included in 21 | // all copies or substantial portions of the Software. 22 | // 23 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | // THE SOFTWARE. 30 | 31 | #import 32 | 33 | @interface AppDelegate : NSObject 34 | 35 | 36 | @end 37 | 38 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon_16x16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon_16x16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon_32x32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon_32x32@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon_128x128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon_128x128@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon_256x256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon_256x256@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon_512x512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "icon_512x512@2x.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /WHC_DataModelFactory.xcodeproj/project.xcworkspace/xcshareddata/WHC_DataModelFactory.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 74AACD06-0BB9-4054-85FB-FBB94E879263 9 | IDESourceControlProjectName 10 | project 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 088AC0207E7A2F2A264A276A84BCA7AFBE855AFA 14 | https://github.com/netyouli/WHC_DataModelFactory.git 15 | 16 | IDESourceControlProjectPath 17 | WHC_DataModelFactory.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 088AC0207E7A2F2A264A276A84BCA7AFBE855AFA 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/netyouli/WHC_DataModelFactory.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 088AC0207E7A2F2A264A276A84BCA7AFBE855AFA 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 088AC0207E7A2F2A264A276A84BCA7AFBE855AFA 36 | IDESourceControlWCCName 37 | WHC_DataModelFactory 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /WHC_ModelApp/WHC_DataModelFactory.app/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 16G1036 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | WHC_DataModelFactory 11 | CFBundleIconFile 12 | AppIcon 13 | CFBundleIdentifier 14 | WHC.WHC-DataModelFactory 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | WHC_ModelFactory 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleSupportedPlatforms 26 | 27 | MacOSX 28 | 29 | CFBundleVersion 30 | 1 31 | DTCompiler 32 | com.apple.compilers.llvm.clang.1_0 33 | DTPlatformBuild 34 | 9B55 35 | DTPlatformVersion 36 | GM 37 | DTSDKBuild 38 | 17B41 39 | DTSDKName 40 | macosx10.13 41 | DTXcode 42 | 0910 43 | DTXcodeBuild 44 | 9B55 45 | LSMinimumSystemVersion 46 | 10.10 47 | NSHumanReadableCopyright 48 | Copyright © 2015年 吴海超. All rights reserved. 49 | NSMainStoryboardFile 50 | Main 51 | NSPrincipalClass 52 | NSApplication 53 | 54 | 55 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/WHC_AutoLayoutKit/WHC_AutoLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // WHC_AutoLayout.h 3 | // WHC_AutoLayoutKit 4 | // 5 | // Github 6 | // 7 | // Created by WHC on 17/4/8. 8 | // Copyright © 2017年 吴海超. All rights reserved. 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | #import 29 | 30 | //! Project version number for WHC_AutoLayout. 31 | FOUNDATION_EXPORT double WHC_AutoLayoutVersionNumber; 32 | 33 | //! Project version string for WHC_AutoLayout. 34 | FOUNDATION_EXPORT const unsigned char WHC_AutoLayoutVersionString[]; 35 | 36 | #import "WHC_StackView.h" 37 | #import "UITableViewCell+WHC_AutoHeightForCell.h" 38 | #import "UIView+WHC_AutoLayout.h" 39 | #import "UIView+WHC_Frame.h" 40 | 41 | 42 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/WHCLib/WHC_XMLParser.h: -------------------------------------------------------------------------------- 1 | // 2 | // WHC_XMLParse.h 3 | // WHC_XMLParse 4 | // 5 | // Created by 吴海超 on 15/4/28. 6 | // Copyright (c) 2015年 吴海超. All rights reserved. 7 | // 8 | 9 | // Github 10 | 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in 20 | // all copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | // THE SOFTWARE. 29 | 30 | 31 | #import 32 | 33 | typedef enum:NSInteger { 34 | WHC_XMLParserOptionsProcessNamespaces = 1 << 0, 35 | WHC_XMLParserOptionsReportNamespacePrefixes = 1 << 1, 36 | WHC_XMLParserOptionsResolveExternalEntities = 1 << 2, 37 | }WHC_XMLParserOptions; 38 | 39 | @interface WHC_XMLParser : NSObject 40 | + (NSDictionary *)dictionaryForXMLData:(NSData *)data; 41 | + (NSDictionary *)dictionaryForXMLString:(NSString *)string; 42 | + (NSDictionary *)dictionaryForXMLData:(NSData *)data options:(WHC_XMLParserOptions)options; 43 | + (NSDictionary *)dictionaryForXMLString:(NSString *)string options:(WHC_XMLParserOptions)options; 44 | @end 45 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // WHC_DataModelFactory 4 | // 5 | // Created by 吴海超 on 15/4/30. 6 | // Copyright (c) 2015年 吴海超. All rights reserved. 7 | // 8 | 9 | 10 | // Github 11 | 12 | // 13 | // Permission is hereby granted, free of charge, to any person obtaining a copy 14 | // of this software and associated documentation files (the "Software"), to deal 15 | // in the Software without restriction, including without limitation the rights 16 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | // copies of the Software, and to permit persons to whom the Software is 18 | // furnished to do so, subject to the following conditions: 19 | // 20 | // The above copyright notice and this permission notice shall be included in 21 | // all copies or substantial portions of the Software. 22 | // 23 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | // THE SOFTWARE. 30 | 31 | #import "AppDelegate.h" 32 | 33 | @interface AppDelegate () 34 | 35 | @end 36 | 37 | @implementation AppDelegate 38 | 39 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 40 | // Insert code here to initialize your application 41 | } 42 | 43 | - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag 44 | { 45 | if (!flag){ 46 | for (NSWindow * window in sender.windows) { 47 | [window makeKeyAndOrderFront:self]; 48 | } 49 | } 50 | return YES; 51 | } 52 | 53 | - (void)applicationWillTerminate:(NSNotification *)aNotification { 54 | // Insert code here to tear down your application 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/WHC_AutoLayoutKit/UIView+WHC_Frame.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+WHC_Frame.h 3 | // Github 4 | // 5 | // Created by 吴海超 on 16/2/17. 6 | // Copyright © 2016年 吴海超. All rights reserved. 7 | // 8 | 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | #import "WHC_AutoLayoutUtilities.h" 28 | 29 | @interface WHC_VIEW (WHC_Frame) 30 | /// 获取屏幕宽度 31 | @property (nonatomic, assign, readonly)CGFloat whc_sw; 32 | /// 获取屏幕高度 33 | @property (nonatomic, assign, readonly)CGFloat whc_sh; 34 | /// 获取视图宽度 35 | @property (nonatomic, assign)CGFloat whc_w; 36 | /// 获取视图高度 37 | @property (nonatomic, assign)CGFloat whc_h; 38 | /// 获取视图x 39 | @property (nonatomic, assign)CGFloat whc_x; 40 | /// 获取视图y 41 | @property (nonatomic, assign)CGFloat whc_y; 42 | /// 获取视图最大x 43 | @property (nonatomic, assign)CGFloat whc_maxX; 44 | /// 获取视图最大y 45 | @property (nonatomic, assign)CGFloat whc_maxY; 46 | /// 获取视图中间x 47 | @property (nonatomic, assign)CGFloat whc_midX; 48 | /// 获取视图中间y 49 | @property (nonatomic, assign)CGFloat whc_midY; 50 | #if TARGET_OS_IPHONE || TARGET_OS_TV 51 | /// 获取视图中心x 52 | @property (nonatomic, assign)CGFloat whc_cx; 53 | /// 获取视图中心y 54 | @property (nonatomic, assign)CGFloat whc_cy; 55 | #endif 56 | /// 获取视图xy 57 | @property (nonatomic, assign)CGPoint whc_xy; 58 | /// 获取视图size 59 | @property (nonatomic, assign)CGSize whc_s; 60 | @end 61 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/WHC_AutoLayoutKit/UITableViewCell+WHC_AutoHeightForCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // UITableViewCell+WHC_AutoHeightForCell.h 3 | // Github 4 | // 5 | // Created by 吴海超 on 16/2/17. 6 | // Copyright © 2016年 吴海超. All rights reserved. 7 | // 8 | 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | #import "WHC_AutoLayoutUtilities.h" 29 | ////////////////////////////列表视图////////////////////////////// 30 | #if TARGET_OS_IPHONE || TARGET_OS_TV 31 | @interface UITableViewCell (WHC_AutoHeightForCell) 32 | /// cell最底部视图 33 | @property (nonatomic , strong) UIView * whc_CellBottomView; 34 | /// cell最底部视图集合 35 | @property (nonatomic , strong) NSArray * whc_CellBottomViews; 36 | /// cell最底部视图与cell底部的间隙 37 | @property (nonatomic , assign) CGFloat whc_CellBottomOffset; 38 | /// cell中包含的UITableView 39 | @property (nonatomic , strong) UITableView * whc_CellTableView; 40 | /// 指定tableview宽度(有助于提高自动计算效率) 41 | @property (nonatomic , assign) CGFloat whc_TableViewWidth; 42 | 43 | /// 自动计算cell高度 44 | + (CGFloat)whc_CellHeightForIndexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableView; 45 | 46 | 47 | /** 48 | 自动计算cell高度: 重用cell api 49 | 50 | @param indexPath cell index 51 | @param tableView 列表 52 | @param identifier 重用标示 53 | @param block cell 布局回调 54 | @return cell高度 55 | 56 | @note 改api定要实现block回调才能正确计算cell高度 57 | */ 58 | + (CGFloat)whc_CellHeightForIndexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableView identifier:(NSString *)identifier layoutBlock:(void (^)(UITableViewCell * cell))block; 59 | @end 60 | #endif 61 | 62 | -------------------------------------------------------------------------------- /WHC_DataModelFactory.xcodeproj/xcuserdata/WHC.xcuserdatad/xcschemes/WHC_DataModelFactory.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 66 | 68 | 74 | 75 | 76 | 77 | 78 | 79 | 85 | 87 | 93 | 94 | 95 | 96 | 98 | 99 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/WHC_AutoLayoutKit/WHC_StackView.h: -------------------------------------------------------------------------------- 1 | // 2 | // WHC_StackView.h 3 | // Github 4 | // 5 | // Created by 吴海超 on 16/2/17. 6 | // Copyright © 2016年 吴海超. All rights reserved. 7 | // 8 | 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | #import "UIView+WHC_AutoLayout.h" 28 | 29 | #if TARGET_OS_IPHONE || TARGET_OS_TV 30 | 31 | typedef NS_OPTIONS(NSUInteger, WHC_UILabelVerticalAlignment) { 32 | Top = 1 << 0, /// 顶部对齐 33 | Middle = 1 << 1, /// 居中对齐 34 | Bottom = 1 << 2, /// 底部对齐 35 | }; 36 | 37 | @interface UIButton (WHC_StackView) 38 | 39 | @end 40 | 41 | @interface UILabel (WHC_StackView) 42 | /************重载父类属性**************/ 43 | /// 自动高度 44 | @property (nonatomic ,copy , readonly)HeightAuto whc_HeightAuto; 45 | 46 | /// 自动宽度 47 | @property (nonatomic ,copy , readonly)WidthAuto whc_WidthAuto; 48 | @property (nonatomic, assign)CGFloat whc_LeftPadding; 49 | @property (nonatomic, assign)CGFloat whc_TopPadding; 50 | @property (nonatomic, assign)CGFloat whc_RightPadding; 51 | @property (nonatomic, assign)CGFloat whc_BottomPadding; 52 | 53 | /// 设置标签垂直方向对齐方式 54 | @property (nonatomic, assign)WHC_UILabelVerticalAlignment whc_VerticalAlignment; 55 | @end 56 | 57 | #endif 58 | 59 | #pragma mark - UI自动布局StackView容器 - 60 | 61 | @interface WHC_VIEW (WHC_StackViewCategory) 62 | /** 63 | 控件横向和垂直布局宽度或者高度权重比例 64 | */ 65 | @property (nonatomic , assign)CGFloat whc_WidthWeight; 66 | 67 | @property (nonatomic , assign)CGFloat whc_HeightWeight; 68 | @end 69 | 70 | @interface WHC_StackView : WHC_VIEW 71 | 72 | 73 | 74 | /// 混合布局(同时垂直和横向)每行多少列 75 | @property (nonatomic , assign) NSInteger whc_Column; 76 | /// 容器内边距 77 | #if TARGET_OS_IPHONE || TARGET_OS_TV 78 | @property (nonatomic , assign) UIEdgeInsets whc_Edge; 79 | #elif TARGET_OS_MAC 80 | @property (nonatomic , assign) NSEdgeInsets whc_Edge; 81 | #endif 82 | /// 容器内子控件横向间隙 83 | @property (nonatomic , assign) CGFloat whc_HSpace; 84 | /// 容器内子控件垂直间隙 85 | @property (nonatomic , assign) CGFloat whc_VSpace; 86 | 87 | /// 子元素高宽比 88 | @property (nonatomic , assign) CGFloat whc_ElementHeightWidthRatio; 89 | 90 | /// 子元素宽高比 91 | @property (nonatomic , assign) CGFloat whc_ElementWidthHeightRatio; 92 | 93 | /// 容器里子元素实际数量 94 | @property (nonatomic , assign , readonly) NSInteger whc_SubViewCount; 95 | 96 | /// 容器自动布局方向 97 | @property (nonatomic , assign) WHC_LayoutOrientationOptions whc_Orientation; 98 | 99 | /// 子视图固定宽度 100 | @property (nonatomic , assign) CGFloat whc_SubViewWidth; 101 | 102 | /// 子视图固定高度 103 | @property (nonatomic , assign) CGFloat whc_SubViewHeight; 104 | 105 | /// 设置分割线尺寸 106 | @property (nonatomic , assign) CGFloat whc_SegmentLineSize; 107 | /// 设置分割线内边距 108 | @property (nonatomic , assign) CGFloat whc_SegmentLinePadding; 109 | /// 设置分割线的颜色 110 | @property (nonatomic , strong) WHC_COLOR * whc_SegmentLineColor; 111 | /************重载父类属性**************/ 112 | /// 自动高度 113 | @property (nonatomic ,copy , readonly)HeightAuto whc_HeightAuto; 114 | 115 | /// 自动宽度 116 | @property (nonatomic ,copy , readonly)WidthAuto whc_WidthAuto; 117 | 118 | /************重载父类方法**************/ 119 | /** 120 | 自动宽度 121 | */ 122 | 123 | - (void)whc_AutoWidth; 124 | 125 | /** 126 | 自动高度 127 | */ 128 | 129 | - (void)whc_AutoHeight; 130 | 131 | /** 132 | 开始进行自动布局 133 | */ 134 | - (void)whc_StartLayout; 135 | 136 | /** 137 | 清除所有子视图 138 | */ 139 | - (void)whc_RemoveAllSubviews; 140 | 141 | /** 142 | 移除所有空白站位视图(仅仅横向垂直混合布局有效) 143 | */ 144 | - (void)whc_RemoveAllVacntView; 145 | @end 146 | 147 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/WHC_AutoLayoutKit/UIView+WHC_Frame.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+WHC_Frame.m 3 | // Github 4 | // 5 | // Created by 吴海超 on 16/2/17. 6 | // Copyright © 2016年 吴海超. All rights reserved. 7 | // 8 | 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | #import "UIView+WHC_Frame.h" 29 | 30 | @implementation WHC_VIEW (WHC_Frame) 31 | 32 | #if TARGET_OS_IPHONE || TARGET_OS_TV 33 | - (CGFloat)whc_sw { 34 | return CGRectGetWidth([UIScreen mainScreen].bounds); 35 | } 36 | 37 | - (CGFloat)whc_sh { 38 | return CGRectGetHeight([UIScreen mainScreen].bounds); 39 | } 40 | 41 | #elif TARGET_OS_MAC 42 | - (CGFloat)whc_sw { 43 | return CGRectGetWidth([NSScreen mainScreen].frame); 44 | } 45 | 46 | - (CGFloat)whc_sh { 47 | return CGRectGetHeight([NSScreen mainScreen].frame); 48 | } 49 | #endif 50 | - (void)setWhc_w:(CGFloat)whc_w { 51 | CGRect rect = self.frame; 52 | rect.size.width = whc_w; 53 | self.frame = rect; 54 | } 55 | 56 | - (CGFloat)whc_w { 57 | return CGRectGetWidth(self.frame); 58 | } 59 | 60 | - (void)setWhc_h:(CGFloat)whc_h { 61 | CGRect rect = self.frame; 62 | rect.size.height = whc_h; 63 | self.frame = rect; 64 | } 65 | 66 | - (CGFloat)whc_h { 67 | return CGRectGetHeight(self.frame); 68 | } 69 | 70 | - (void)setWhc_x:(CGFloat)whc_x { 71 | CGRect rect = self.frame; 72 | rect.origin.x = whc_x; 73 | self.frame = rect; 74 | } 75 | 76 | - (CGFloat)whc_x { 77 | return CGRectGetMinX(self.frame); 78 | } 79 | 80 | - (void)setWhc_y:(CGFloat)whc_y { 81 | CGRect rect = self.frame; 82 | rect.origin.y = whc_y; 83 | self.frame = rect; 84 | } 85 | 86 | - (CGFloat)whc_y { 87 | return CGRectGetMinY(self.frame); 88 | } 89 | 90 | - (void)setWhc_maxX:(CGFloat)whc_maxX { 91 | self.whc_w = whc_maxX - self.whc_x; 92 | } 93 | 94 | - (CGFloat)whc_maxX { 95 | return CGRectGetMaxX(self.frame); 96 | } 97 | 98 | - (void)setWhc_maxY:(CGFloat)whc_maxY { 99 | self.whc_h = whc_maxY - self.whc_y; 100 | } 101 | 102 | - (CGFloat)whc_maxY { 103 | return CGRectGetMaxY(self.frame); 104 | } 105 | 106 | - (void)setWhc_midX:(CGFloat)whc_midX { 107 | self.whc_w = whc_midX * 2; 108 | } 109 | 110 | - (CGFloat)whc_midX { 111 | return CGRectGetMinX(self.frame) + CGRectGetWidth(self.frame) / 2; 112 | } 113 | 114 | - (void)setWhc_midY:(CGFloat)whc_midY { 115 | self.whc_h = whc_midY * 2; 116 | } 117 | 118 | - (CGFloat)whc_midY { 119 | return CGRectGetMinY(self.frame) + CGRectGetHeight(self.frame) / 2; 120 | } 121 | 122 | #if TARGET_OS_IPHONE || TARGET_OS_TV 123 | 124 | - (void)setWhc_cx:(CGFloat)whc_cx { 125 | CGPoint center = self.center; 126 | center.x = whc_cx; 127 | self.center = center; 128 | } 129 | 130 | - (CGFloat)whc_cx { 131 | return self.center.x; 132 | } 133 | 134 | - (void)setWhc_cy:(CGFloat)whc_cy { 135 | CGPoint center = self.center; 136 | center.y = whc_cy; 137 | self.center = center; 138 | } 139 | 140 | - (CGFloat)whc_cy { 141 | return self.center.y; 142 | } 143 | 144 | #endif 145 | - (void)setWhc_xy:(CGPoint)whc_xy { 146 | CGRect rect = self.frame; 147 | rect.origin = whc_xy; 148 | self.frame = rect; 149 | } 150 | 151 | 152 | - (CGPoint)whc_xy { 153 | return self.frame.origin; 154 | } 155 | 156 | - (void)setWhc_s:(CGSize)whc_s { 157 | CGRect rect = self.frame; 158 | rect.size = whc_s; 159 | self.frame = rect; 160 | } 161 | 162 | - (CGSize)whc_s { 163 | return self.frame.size; 164 | } 165 | 166 | @end 167 | -------------------------------------------------------------------------------- /WHC_DataModelFactory.xcodeproj/xcuserdata/wuhaichao.xcuserdatad/xcschemes/WHC_DataModelFactory.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /WHC_ModelApp/WHC_DataModelFactory.app/Contents/_CodeSignature/CodeResources: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | Resources/AppIcon.icns 8 | 9 | TGXgV3ENOjAwwjSWRHURZyyLH5k= 10 | 11 | Resources/Base.lproj/Main.storyboardc/Info.plist 12 | 13 | L3U50+Np0vmBr5fLpp4vEApuvPI= 14 | 15 | Resources/Base.lproj/Main.storyboardc/MainMenu.nib 16 | 17 | 0Qc3SDU+E8xsXeECHjPgcqXgKkA= 18 | 19 | Resources/Base.lproj/Main.storyboardc/NSWindowController-B8D-0N-5wS.nib 20 | 21 | pSftd7Z0cNAZSMiceWP89qIPcP4= 22 | 23 | Resources/Base.lproj/Main.storyboardc/XfG-lQ-9wD-view-m2S-Jp-Qdl.nib 24 | 25 | EZ5+5PjhAdLlSixpruzsI2gJi60= 26 | 27 | Resources/dict.png 28 | 29 | k0zhf3eGYsePItcDyprskcwpkbE= 30 | 31 | Resources/oc.png 32 | 33 | N2biv98GCTlaO3hTmG6k+sr8D94= 34 | 35 | Resources/swift.png 36 | 37 | sV3FHV9xS7z5TOnlY3jxk5cVkIs= 38 | 39 | 40 | files2 41 | 42 | Resources/AppIcon.icns 43 | 44 | hash 45 | 46 | TGXgV3ENOjAwwjSWRHURZyyLH5k= 47 | 48 | hash2 49 | 50 | XnLJNic7fiWpby6/bv22Wymw7l4g5/MOLweqfSVJJMI= 51 | 52 | 53 | Resources/Base.lproj/Main.storyboardc/Info.plist 54 | 55 | hash 56 | 57 | L3U50+Np0vmBr5fLpp4vEApuvPI= 58 | 59 | hash2 60 | 61 | 3R+lIDUP1iB6neB5k7mm13c0N9Fj+6a/Lo5cP3vPu/s= 62 | 63 | 64 | Resources/Base.lproj/Main.storyboardc/MainMenu.nib 65 | 66 | hash 67 | 68 | 0Qc3SDU+E8xsXeECHjPgcqXgKkA= 69 | 70 | hash2 71 | 72 | /oYtnPpCFS/xZm0AqT4DSxcmLxXxrzZspKE05/bUWpE= 73 | 74 | 75 | Resources/Base.lproj/Main.storyboardc/NSWindowController-B8D-0N-5wS.nib 76 | 77 | hash 78 | 79 | pSftd7Z0cNAZSMiceWP89qIPcP4= 80 | 81 | hash2 82 | 83 | JJiHPW4IiIKZutFE6+9fvB6cHVZQ6N2wtyQfDaHlkRE= 84 | 85 | 86 | Resources/Base.lproj/Main.storyboardc/XfG-lQ-9wD-view-m2S-Jp-Qdl.nib 87 | 88 | hash 89 | 90 | EZ5+5PjhAdLlSixpruzsI2gJi60= 91 | 92 | hash2 93 | 94 | YwWJCXZy5jPNNh6thdp6hFCkmhgtGynm3RQHi3zE/Ek= 95 | 96 | 97 | Resources/dict.png 98 | 99 | hash 100 | 101 | k0zhf3eGYsePItcDyprskcwpkbE= 102 | 103 | hash2 104 | 105 | iOUnMqARCvemqdurVNX80y+Gbu+98y33Efu2u4t9O/E= 106 | 107 | 108 | Resources/oc.png 109 | 110 | hash 111 | 112 | N2biv98GCTlaO3hTmG6k+sr8D94= 113 | 114 | hash2 115 | 116 | ltpvuUbvox+6fuVfNxVSVI8MvIb3vOBE2fM7BUFvFpY= 117 | 118 | 119 | Resources/swift.png 120 | 121 | hash 122 | 123 | sV3FHV9xS7z5TOnlY3jxk5cVkIs= 124 | 125 | hash2 126 | 127 | wY1hOW+q0mSdSfTIS3yBiBgZU9IYYWExzoBH3lpb/XU= 128 | 129 | 130 | 131 | rules 132 | 133 | ^Resources/ 134 | 135 | ^Resources/.*\.lproj/ 136 | 137 | optional 138 | 139 | weight 140 | 1000 141 | 142 | ^Resources/.*\.lproj/locversion.plist$ 143 | 144 | omit 145 | 146 | weight 147 | 1100 148 | 149 | ^Resources/Base\.lproj/ 150 | 151 | weight 152 | 1010 153 | 154 | ^version.plist$ 155 | 156 | 157 | rules2 158 | 159 | .*\.dSYM($|/) 160 | 161 | weight 162 | 11 163 | 164 | ^(.*/)?\.DS_Store$ 165 | 166 | omit 167 | 168 | weight 169 | 2000 170 | 171 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ 172 | 173 | nested 174 | 175 | weight 176 | 10 177 | 178 | ^.* 179 | 180 | ^Info\.plist$ 181 | 182 | omit 183 | 184 | weight 185 | 20 186 | 187 | ^PkgInfo$ 188 | 189 | omit 190 | 191 | weight 192 | 20 193 | 194 | ^Resources/ 195 | 196 | weight 197 | 20 198 | 199 | ^Resources/.*\.lproj/ 200 | 201 | optional 202 | 203 | weight 204 | 1000 205 | 206 | ^Resources/.*\.lproj/locversion.plist$ 207 | 208 | omit 209 | 210 | weight 211 | 1100 212 | 213 | ^Resources/Base\.lproj/ 214 | 215 | weight 216 | 1010 217 | 218 | ^[^/]+$ 219 | 220 | nested 221 | 222 | weight 223 | 10 224 | 225 | ^embedded\.provisionprofile$ 226 | 227 | weight 228 | 20 229 | 230 | ^version\.plist$ 231 | 232 | weight 233 | 20 234 | 235 | 236 | 237 | 238 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/WHCLib/WHC_XMLParser.m: -------------------------------------------------------------------------------- 1 | // 2 | // WHC_XMLParse.m 3 | // WHC_XMLParse 4 | // 5 | // Created by 吴海超 on 15/4/28. 6 | // Copyright (c) 2015年 吴海超. All rights reserved. 7 | // 8 | 9 | // Github 10 | 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the "Software"), to deal 14 | // in the Software without restriction, including without limitation the rights 15 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | // copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in 20 | // all copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | // THE SOFTWARE. 29 | 30 | #import "WHC_XMLParser.h" 31 | 32 | #define kWHCXMLParserTextNodeKey (@"WHC_TXT") 33 | @interface WHC_XMLParser (){ 34 | NSMutableArray * _dictArr; //存放字典数组 35 | NSMutableString * _contentTxt; //存放当前解析内容文字 36 | NSError * _error; //存放错误信息 37 | } 38 | 39 | @end 40 | 41 | @implementation WHC_XMLParser 42 | 43 | - (instancetype)init{ 44 | self = [super init]; 45 | if(self){ 46 | _error = [NSError new]; 47 | _dictArr = [NSMutableArray new]; 48 | _contentTxt = [NSMutableString new]; 49 | } 50 | return self; 51 | } 52 | 53 | + (NSDictionary *)dictionaryForXMLData:(NSData *)data{ 54 | return [WHC_XMLParser dictionaryForXMLData:data options:0]; 55 | } 56 | 57 | + (NSDictionary *)dictionaryForXMLString:(NSString *)string{ 58 | return [WHC_XMLParser dictionaryForXMLData:[string dataUsingEncoding:NSUTF8StringEncoding]]; 59 | } 60 | 61 | + (NSDictionary *)dictionaryForXMLData:(NSData *)data options:(WHC_XMLParserOptions)options{ 62 | WHC_XMLParser * whc_xmlParser = [WHC_XMLParser new]; 63 | return [whc_xmlParser startParserXML:data options:options]; 64 | } 65 | 66 | + (NSDictionary *)dictionaryForXMLString:(NSString *)string options:(WHC_XMLParserOptions)options{ 67 | return [WHC_XMLParser dictionaryForXMLData:[string dataUsingEncoding:NSUTF8StringEncoding] options:options]; 68 | } 69 | 70 | - (NSDictionary*)startParserXML:(NSData*)data options:(WHC_XMLParserOptions)options{ 71 | [_dictArr addObject:[NSMutableDictionary new]]; 72 | NSXMLParser * xmlParser = [[NSXMLParser alloc]initWithData:data]; 73 | xmlParser.delegate = self; 74 | xmlParser.shouldProcessNamespaces = (options & WHC_XMLParserOptionsProcessNamespaces); 75 | xmlParser.shouldReportNamespacePrefixes = (options & WHC_XMLParserOptionsReportNamespacePrefixes); 76 | xmlParser.shouldResolveExternalEntities = (options & WHC_XMLParserOptionsResolveExternalEntities); 77 | if([xmlParser parse]){ 78 | [self XMLDataHandleEngine:_dictArr[0]]; 79 | return _dictArr[0]; 80 | } 81 | return nil; 82 | } 83 | 84 | - (void)XMLDataHandleEngine:(id)object{ 85 | if([object isKindOfClass:[NSDictionary class]]){ 86 | NSMutableDictionary * dict = object; 87 | NSInteger count = dict.count; 88 | NSArray * keyArr = [dict allKeys]; 89 | for (NSInteger i = 0; i < count; i++) { 90 | NSString * key = keyArr[i]; 91 | id subObject = dict[key]; 92 | if([subObject isKindOfClass:[NSDictionary class]]){ 93 | [self handleTopData:dict subDict:subObject index:i]; 94 | [self XMLDataHandleEngine:subObject]; 95 | }else if([subObject isKindOfClass:[NSArray class]]){ 96 | [self XMLDataHandleEngine:subObject]; 97 | } 98 | } 99 | }else if ([object isKindOfClass:[NSArray class]]){ 100 | NSMutableArray * arrs = object; 101 | for (NSInteger i = 0; i < arrs.count; i++) { 102 | id subObject = arrs[i]; 103 | [self XMLDataHandleEngine:subObject]; 104 | } 105 | } 106 | } 107 | 108 | - (void)handleTopData:(NSMutableDictionary *)dict subDict:(NSDictionary*)subDict index:(NSInteger)index{ 109 | NSArray * subKeyArr = [subDict allKeys]; 110 | NSArray * keyArr = [dict allKeys]; 111 | if(subKeyArr.count == 1 && [subKeyArr[0] isEqualToString:kWHCXMLParserTextNodeKey]){ 112 | [dict setObject:subDict[kWHCXMLParserTextNodeKey] forKey:keyArr[index]]; 113 | }else if(subKeyArr.count == 0){ 114 | [dict setObject:@"" forKey:keyArr[index]]; 115 | } 116 | 117 | } 118 | #pragma mark - NSXMLParserDelegate 119 | - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{ 120 | NSMutableDictionary * parentDict = [_dictArr lastObject]; 121 | NSMutableDictionary * childDict = [NSMutableDictionary new]; 122 | [childDict addEntriesFromDictionary:attributeDict]; 123 | id existingValue = [parentDict objectForKey:elementName]; 124 | if (existingValue){ 125 | NSMutableArray *array = nil; 126 | if ([existingValue isKindOfClass:[NSMutableArray class]]){ 127 | //使用存在的数组 128 | array = (NSMutableArray *) existingValue; 129 | }else{ 130 | //不存在创建数组 131 | array = [NSMutableArray new]; 132 | [array addObject:existingValue]; 133 | // 替换子字典用数组 134 | [parentDict setObject:array forKey:elementName]; 135 | } 136 | // 添加一个新的子字典 137 | [array addObject:childDict]; 138 | }else{ 139 | // 不存在插入新元素 140 | [parentDict setObject:childDict forKey:elementName]; 141 | } 142 | 143 | // 跟新数组 144 | [_dictArr addObject:childDict]; 145 | } 146 | 147 | - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{ 148 | NSMutableDictionary *dictInProgress = [_dictArr lastObject]; 149 | if (_contentTxt.length > 0){ 150 | // 存储值 151 | NSString *valueTxt = [_contentTxt stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 152 | if(valueTxt.length){ 153 | [dictInProgress setObject:[valueTxt mutableCopy] forKey:kWHCXMLParserTextNodeKey]; 154 | _contentTxt = [[NSMutableString alloc] init]; 155 | } 156 | } 157 | // 移除当前 158 | [_dictArr removeLastObject]; 159 | } 160 | 161 | - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ 162 | [_contentTxt appendString:string]; 163 | 164 | } 165 | - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{ 166 | if(parseError){ 167 | NSLog(@"WHC_XMLParserError :%@",parseError); 168 | } 169 | } 170 | @end 171 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/WHC_AutoLayoutKit/UITableViewCell+WHC_AutoHeightForCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // UITableViewCell+WHC_AutoHeightForCell.m 3 | // Github 4 | // 5 | // Created by 吴海超 on 16/2/17. 6 | // Copyright © 2016年 吴海超. All rights reserved. 7 | // 8 | 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | #import "UITableViewCell+WHC_AutoHeightForCell.h" 29 | 30 | #if TARGET_OS_IPHONE || TARGET_OS_TV 31 | #import 32 | #import "UIView+WHC_AutoLayout.h" 33 | 34 | @interface UITableView (WHC_CacheCellHeight) 35 | @end 36 | 37 | @implementation UITableView (WHC_CacheCellHeight) 38 | 39 | + (void)load { 40 | static dispatch_once_t onceToken; 41 | dispatch_once(&onceToken, ^{ 42 | Method reloadData = class_getInstanceMethod(self, @selector(reloadData)); 43 | Method whc_ReloadData = class_getInstanceMethod(self, @selector(whc_ReloadData)); 44 | Method reloadDataRow = class_getInstanceMethod(self, @selector(reloadRowsAtIndexPaths:withRowAnimation:)); 45 | Method whc_ReloadDataRow = class_getInstanceMethod(self, @selector(whc_reloadRowsAtIndexPaths:withRowAnimation:)); 46 | Method sectionReloadData = class_getInstanceMethod(self, @selector(reloadSections:withRowAnimation:)); 47 | Method whc_SectionReloadData = class_getInstanceMethod(self, @selector(whc_ReloadSetion:withRowAnimation:)); 48 | Method deleteCell = class_getInstanceMethod(self, @selector(deleteItemsAtIndexPaths:)); 49 | Method whc_deleteCell = class_getInstanceMethod(self, @selector(whc_deleteItemsAtIndexPaths:)); 50 | Method deleteSection = class_getInstanceMethod(self, @selector(deleteSections:)); 51 | Method whc_deleteSection = class_getInstanceMethod(self, @selector(whc_deleteSections:)); 52 | Method moveSection = class_getInstanceMethod(self, @selector(moveSection:toSection:)); 53 | Method whc_moveSection = class_getInstanceMethod(self, @selector(whc_MoveSection:toSection:)); 54 | Method moveRowAtIndexPath = class_getInstanceMethod(self, @selector(moveRowAtIndexPath:toIndexPath:)); 55 | Method whc_moveRowAtIndexPath = class_getInstanceMethod(self, @selector(whc_MoveRowAtIndexPath:toIndexPath:)); 56 | Method insertSections = class_getInstanceMethod(self, @selector(insertSections:withRowAnimation:)); 57 | Method whc_insertSections = class_getInstanceMethod(self, @selector(whc_InsertSections:withRowAnimation:)); 58 | Method insertRowsAtIndexPaths = class_getInstanceMethod(self, @selector(insertRowsAtIndexPaths:withRowAnimation:)); 59 | Method whc_insertRowsAtIndexPaths = class_getInstanceMethod(self, @selector(whc_InsertRowsAtIndexPaths:withRowAnimation:)); 60 | 61 | method_exchangeImplementations(sectionReloadData, whc_SectionReloadData); 62 | method_exchangeImplementations(reloadDataRow, whc_ReloadDataRow); 63 | method_exchangeImplementations(reloadData, whc_ReloadData); 64 | method_exchangeImplementations(deleteCell, whc_deleteCell); 65 | method_exchangeImplementations(deleteSection, whc_deleteSection); 66 | method_exchangeImplementations(moveSection, whc_moveSection); 67 | method_exchangeImplementations(moveRowAtIndexPath, whc_moveRowAtIndexPath); 68 | method_exchangeImplementations(insertSections, whc_insertSections); 69 | method_exchangeImplementations(insertRowsAtIndexPaths, whc_insertRowsAtIndexPaths); 70 | }); 71 | } 72 | 73 | - (void)setWhc_CacheHeightDictionary:(NSMutableDictionary *)whc_CacheHeightDictionary { 74 | objc_setAssociatedObject(self, 75 | @selector(whc_CacheHeightDictionary), 76 | whc_CacheHeightDictionary, 77 | OBJC_ASSOCIATION_RETAIN_NONATOMIC); 78 | } 79 | 80 | - (NSMutableDictionary *)whc_CacheHeightDictionary { 81 | return objc_getAssociatedObject(self, _cmd); 82 | } 83 | 84 | - (void)handleCacheHeightDictionary { 85 | if (self.whc_CacheHeightDictionary) { 86 | NSArray * allKey = [self.whc_CacheHeightDictionary.allKeys sortedArrayUsingComparator:^NSComparisonResult(NSString * obj1, NSString * obj2) { 87 | return obj1.floatValue < obj2.floatValue; 88 | }]; 89 | __block NSString * frontKey = nil; 90 | __block NSInteger index = 0; 91 | [allKey enumerateObjectsUsingBlock:^(NSString * _Nonnull key, NSUInteger idx, BOOL * _Nonnull stop) { 92 | if (frontKey == nil) { 93 | frontKey = key; 94 | }else { 95 | if (key.integerValue - frontKey.integerValue > 1) { 96 | if (index == 0) { 97 | index = frontKey.integerValue; 98 | } 99 | [self.whc_CacheHeightDictionary setObject:self.whc_CacheHeightDictionary[key] forKey:@(allKey[index].integerValue + 1).stringValue]; 100 | [self.whc_CacheHeightDictionary removeObjectForKey:key]; 101 | index = idx; 102 | } 103 | frontKey = key; 104 | } 105 | }]; 106 | } 107 | } 108 | 109 | - (void)whc_deleteSections:(NSIndexSet *)sections { 110 | if (sections && self.whc_CacheHeightDictionary) { 111 | [sections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { 112 | [self.whc_CacheHeightDictionary removeObjectForKey:@(idx).stringValue]; 113 | }]; 114 | [self handleCacheHeightDictionary]; 115 | } 116 | [self whc_deleteSections:sections]; 117 | } 118 | 119 | - (void)whc_deleteItemsAtIndexPaths:(NSArray *)indexPaths { 120 | if (indexPaths && self.whc_CacheHeightDictionary) { 121 | [indexPaths enumerateObjectsUsingBlock:^(NSIndexPath * _Nonnull indexPath, NSUInteger idx, BOOL * _Nonnull stop) { 122 | NSString * cacheHeightKey = @(indexPath.section).stringValue; 123 | NSMutableDictionary * sectionCacheHeightDictionary = self.whc_CacheHeightDictionary[cacheHeightKey]; 124 | if (sectionCacheHeightDictionary != nil) { 125 | [sectionCacheHeightDictionary removeObjectForKey:@(indexPath.row).stringValue]; 126 | } 127 | }]; 128 | } 129 | [self whc_deleteItemsAtIndexPaths:indexPaths]; 130 | } 131 | 132 | - (void)whc_ReloadSetion:(NSIndexSet *)sections 133 | withRowAnimation:(UITableViewRowAnimation)animation { 134 | if (sections && self.whc_CacheHeightDictionary) { 135 | [sections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { 136 | [self.whc_CacheHeightDictionary removeObjectForKey:@(idx).stringValue]; 137 | }]; 138 | [self handleCacheHeightDictionary]; 139 | } 140 | [self whc_ReloadSetion:sections withRowAnimation:animation]; 141 | } 142 | 143 | - (void)whc_reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation { 144 | if (indexPaths && self.whc_CacheHeightDictionary) { 145 | [indexPaths enumerateObjectsUsingBlock:^(NSIndexPath * _Nonnull indexPath, NSUInteger idx, BOOL * _Nonnull stop) { 146 | NSString * cacheHeightKey = @(indexPath.section).stringValue; 147 | NSMutableDictionary * sectionCacheHeightDictionary = self.whc_CacheHeightDictionary[cacheHeightKey]; 148 | if (sectionCacheHeightDictionary != nil) { 149 | [sectionCacheHeightDictionary removeObjectForKey:@(indexPath.row).stringValue]; 150 | } 151 | }]; 152 | } 153 | [self whc_reloadRowsAtIndexPaths:indexPaths withRowAnimation:animation]; 154 | } 155 | 156 | - (void)whc_ReloadData { 157 | if (self.whc_CacheHeightDictionary != nil) { 158 | [self.whc_CacheHeightDictionary removeAllObjects]; 159 | } 160 | [self whc_ReloadData]; 161 | } 162 | 163 | - (void)whc_MoveSection:(NSInteger)section toSection:(NSInteger)newSection { 164 | if (self.whc_CacheHeightDictionary) { 165 | NSMutableDictionary * sectionMap = [NSMutableDictionary dictionaryWithDictionary:self.whc_CacheHeightDictionary[@(section).stringValue]]; 166 | self.whc_CacheHeightDictionary[@(section).stringValue] = self.whc_CacheHeightDictionary[@(newSection).stringValue]; 167 | self.whc_CacheHeightDictionary[@(newSection).stringValue] = sectionMap; 168 | } 169 | [self whc_MoveSection:section toSection:newSection]; 170 | } 171 | 172 | - (void)whc_MoveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath { 173 | if (indexPath && newIndexPath && self.whc_CacheHeightDictionary) { 174 | NSMutableDictionary * indexPathMap = self.whc_CacheHeightDictionary[@(indexPath.section).stringValue]; 175 | CGFloat indexPathHeight = [indexPathMap[@(indexPath.row).stringValue] floatValue]; 176 | 177 | NSMutableDictionary * newIndexPathMap = self.whc_CacheHeightDictionary[@(newIndexPath.section).stringValue]; 178 | CGFloat newIndexPathHeight = [newIndexPathMap[@(newIndexPath.row).stringValue] floatValue]; 179 | 180 | indexPathMap[@(indexPath.row).stringValue] = @(newIndexPathHeight); 181 | newIndexPathMap[@(newIndexPath.row).stringValue] = @(indexPathHeight); 182 | } 183 | [self whc_MoveRowAtIndexPath:indexPath toIndexPath:newIndexPath]; 184 | } 185 | 186 | - (void)whc_InsertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation { 187 | if (sections && self.whc_CacheHeightDictionary) { 188 | NSUInteger firstSection = sections.firstIndex; 189 | NSUInteger moveSection = self.whc_CacheHeightDictionary.count; 190 | if (moveSection > firstSection) { 191 | for (NSInteger section = firstSection; section < moveSection; section++) { 192 | NSMutableDictionary * sectionMap = self.whc_CacheHeightDictionary[@(section).stringValue]; 193 | if (sectionMap != nil) { 194 | self.whc_CacheHeightDictionary[@(section + sections.count).stringValue] = sectionMap; 195 | [self.whc_CacheHeightDictionary removeObjectForKey:@(section)]; 196 | } 197 | } 198 | } 199 | } 200 | [self whc_InsertSections:sections withRowAnimation:animation]; 201 | } 202 | 203 | - (void)whc_InsertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation { 204 | if (self.whc_CacheHeightDictionary && indexPaths) { 205 | [indexPaths enumerateObjectsUsingBlock:^(NSIndexPath * _Nonnull indexPath, NSUInteger idx, BOOL * _Nonnull stop) { 206 | NSMutableDictionary * sectionMap = self.whc_CacheHeightDictionary[@(indexPath.section).stringValue]; 207 | if (sectionMap != nil) { 208 | NSInteger moveRow = sectionMap.count; 209 | if (moveRow > indexPath.row) { 210 | for (NSInteger index = indexPath.row; index < moveRow; index++) { 211 | id heightObject = sectionMap[@(index).stringValue]; 212 | if (heightObject) { 213 | sectionMap[@(index + 1).stringValue] = @([heightObject floatValue]); 214 | [sectionMap removeObjectForKey:@(index).stringValue]; 215 | } 216 | } 217 | } 218 | } 219 | }]; 220 | } 221 | [self whc_InsertRowsAtIndexPaths:indexPaths withRowAnimation:animation]; 222 | } 223 | 224 | @end 225 | 226 | 227 | 228 | @implementation UITableViewCell (WHC_AutoHeightForCell) 229 | 230 | - (void)setWhc_CellBottomOffset:(CGFloat)whc_CellBottomOffset { 231 | objc_setAssociatedObject(self, 232 | @selector(whc_CellBottomOffset), 233 | @(whc_CellBottomOffset), 234 | OBJC_ASSOCIATION_RETAIN_NONATOMIC); 235 | } 236 | 237 | - (CGFloat)whc_CellBottomOffset { 238 | id bottomOffset = objc_getAssociatedObject(self, _cmd); 239 | return bottomOffset != nil ? [bottomOffset floatValue] : 0; 240 | } 241 | 242 | - (void)setWhc_CellBottomViews:(NSArray *)whc_CellBottomViews { 243 | objc_setAssociatedObject(self, 244 | @selector(whc_CellBottomViews), 245 | whc_CellBottomViews, 246 | OBJC_ASSOCIATION_COPY); 247 | } 248 | 249 | - (NSArray *)whc_CellBottomViews { 250 | return objc_getAssociatedObject(self, _cmd); 251 | } 252 | 253 | - (void)setWhc_CellBottomView:(UIView *)whc_CellBottomView { 254 | objc_setAssociatedObject(self, 255 | @selector(whc_CellBottomView), 256 | whc_CellBottomView, 257 | OBJC_ASSOCIATION_RETAIN_NONATOMIC); 258 | } 259 | 260 | - (UIView *)whc_CellBottomView { 261 | return objc_getAssociatedObject(self, _cmd); 262 | } 263 | 264 | - (UITableView *)whc_CellTableView { 265 | return objc_getAssociatedObject(self, _cmd); 266 | } 267 | 268 | - (void)setWhc_CellTableView:(UITableView *)whc_CellTableView { 269 | objc_setAssociatedObject(self, 270 | @selector(whc_CellTableView), 271 | whc_CellTableView, 272 | OBJC_ASSOCIATION_RETAIN_NONATOMIC); 273 | } 274 | 275 | - (CGFloat)whc_TableViewWidth { 276 | id value = objc_getAssociatedObject(self, _cmd); 277 | return value != nil ? [value floatValue] : 0; 278 | } 279 | 280 | - (void)setWhc_TableViewWidth:(CGFloat)whc_TableViewWidth { 281 | objc_setAssociatedObject(self, @selector(whc_TableViewWidth), @(whc_TableViewWidth), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 282 | } 283 | 284 | + (CGFloat)whc_CellHeightForIndexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableView identifier:(NSString *)identifier layoutBlock:(void (^)(UITableViewCell * cell))block { 285 | if (tableView.whc_CacheHeightDictionary == nil) { 286 | tableView.whc_CacheHeightDictionary = [NSMutableDictionary dictionary]; 287 | } 288 | NSString * cacheHeightKey = @(indexPath.section).stringValue; 289 | NSMutableDictionary * sectionCacheHeightDictionary = tableView.whc_CacheHeightDictionary[cacheHeightKey]; 290 | if (sectionCacheHeightDictionary != nil) { 291 | NSNumber * cellHeight = sectionCacheHeightDictionary[@(indexPath.row).stringValue]; 292 | if (cellHeight) { 293 | return cellHeight.floatValue; 294 | } 295 | }else { 296 | sectionCacheHeightDictionary = [NSMutableDictionary dictionary]; 297 | [tableView.whc_CacheHeightDictionary setObject:sectionCacheHeightDictionary forKey:cacheHeightKey]; 298 | } 299 | UITableViewCell * cell = nil; 300 | if (identifier && identifier.length > 0) { 301 | cell = [tableView dequeueReusableCellWithIdentifier:identifier]; 302 | if (block) { 303 | block(cell); 304 | } 305 | if (!cell) { 306 | cell = [tableView dequeueReusableCellWithIdentifier:identifier]; 307 | } 308 | }else { 309 | cell = [tableView.dataSource tableView:tableView cellForRowAtIndexPath:indexPath]; 310 | } 311 | if (cell.whc_CellTableView) { 312 | [cell.whc_CellTableView whc_Height:cell.whc_CellTableView.contentSize.height]; 313 | } 314 | CGFloat tableViewWidth = cell.whc_TableViewWidth; 315 | if (tableViewWidth == 0) { 316 | [tableView layoutIfNeeded]; 317 | tableViewWidth = CGRectGetWidth(tableView.frame); 318 | } 319 | if (tableViewWidth == 0) return 0; 320 | CGRect cellFrame = cell.frame; 321 | cellFrame.size.width = tableViewWidth; 322 | cell.frame = cellFrame; 323 | CGRect contentFrame = cell.contentView.frame; 324 | contentFrame.size.width = tableViewWidth; 325 | cell.contentView.frame = contentFrame; 326 | [cell layoutIfNeeded]; 327 | UIView * bottomView = nil; 328 | if (cell.whc_CellBottomView != nil) { 329 | bottomView = cell.whc_CellBottomView; 330 | }else if(cell.whc_CellBottomViews != nil && cell.whc_CellBottomViews.count > 0) { 331 | bottomView = cell.whc_CellBottomViews[0]; 332 | for (int i = 1; i < cell.whc_CellBottomViews.count; i++) { 333 | UIView * view = cell.whc_CellBottomViews[i]; 334 | if (CGRectGetMaxY(bottomView.frame) < CGRectGetMaxY(view.frame)) { 335 | bottomView = view; 336 | } 337 | } 338 | }else { 339 | NSArray * cellSubViews = cell.contentView.subviews; 340 | if (cellSubViews.count > 0) { 341 | bottomView = cellSubViews[0]; 342 | for (int i = 1; i < cellSubViews.count; i++) { 343 | UIView * view = cellSubViews[i]; 344 | if (CGRectGetMaxY(bottomView.frame) < CGRectGetMaxY(view.frame)) { 345 | bottomView = view; 346 | } 347 | } 348 | }else { 349 | bottomView = cell.contentView; 350 | } 351 | } 352 | 353 | CGFloat cacheHeight = CGRectGetMaxY(bottomView.frame) + cell.whc_CellBottomOffset; 354 | [sectionCacheHeightDictionary setValue:@(cacheHeight) forKey:@(indexPath.row).stringValue]; 355 | return cacheHeight; 356 | } 357 | 358 | + (CGFloat)whc_CellHeightForIndexPath:(NSIndexPath *)indexPath tableView:(UITableView *)tableView { 359 | if (tableView.whc_CacheHeightDictionary == nil) { 360 | tableView.whc_CacheHeightDictionary = [NSMutableDictionary dictionary]; 361 | } 362 | NSString * cacheHeightKey = @(indexPath.section).stringValue; 363 | NSMutableDictionary * sectionCacheHeightDictionary = tableView.whc_CacheHeightDictionary[cacheHeightKey]; 364 | if (sectionCacheHeightDictionary != nil) { 365 | NSNumber * cellHeight = sectionCacheHeightDictionary[@(indexPath.row).stringValue]; 366 | if (cellHeight) { 367 | return cellHeight.floatValue; 368 | } 369 | }else { 370 | sectionCacheHeightDictionary = [NSMutableDictionary dictionary]; 371 | [tableView.whc_CacheHeightDictionary setObject:sectionCacheHeightDictionary forKey:cacheHeightKey]; 372 | } 373 | UITableViewCell * cell = [tableView.dataSource tableView:tableView cellForRowAtIndexPath:indexPath]; 374 | if (cell.whc_CellTableView) { 375 | [cell.whc_CellTableView whc_Height:cell.whc_CellTableView.contentSize.height]; 376 | } 377 | CGFloat tableViewWidth = cell.whc_TableViewWidth; 378 | if (tableViewWidth == 0) { 379 | [tableView layoutIfNeeded]; 380 | tableViewWidth = CGRectGetWidth(tableView.frame); 381 | } 382 | if (tableViewWidth == 0) return 0; 383 | CGRect cellFrame = cell.frame; 384 | cellFrame.size.width = tableViewWidth; 385 | cell.frame = cellFrame; 386 | CGRect contentFrame = cell.contentView.frame; 387 | contentFrame.size.width = tableViewWidth; 388 | cell.contentView.frame = contentFrame; 389 | [cell layoutIfNeeded]; 390 | UIView * bottomView = nil; 391 | if (cell.whc_CellBottomView != nil) { 392 | bottomView = cell.whc_CellBottomView; 393 | }else if(cell.whc_CellBottomViews != nil && cell.whc_CellBottomViews.count > 0) { 394 | bottomView = cell.whc_CellBottomViews[0]; 395 | for (int i = 1; i < cell.whc_CellBottomViews.count; i++) { 396 | UIView * view = cell.whc_CellBottomViews[i]; 397 | if (CGRectGetMaxY(bottomView.frame) < CGRectGetMaxY(view.frame)) { 398 | bottomView = view; 399 | } 400 | } 401 | }else { 402 | NSArray * cellSubViews = cell.contentView.subviews; 403 | if (cellSubViews.count > 0) { 404 | bottomView = cellSubViews[0]; 405 | for (int i = 1; i < cellSubViews.count; i++) { 406 | UIView * view = cellSubViews[i]; 407 | if (CGRectGetMaxY(bottomView.frame) < CGRectGetMaxY(view.frame)) { 408 | bottomView = view; 409 | } 410 | } 411 | }else { 412 | bottomView = cell.contentView; 413 | } 414 | } 415 | 416 | CGFloat cacheHeight = CGRectGetMaxY(bottomView.frame) + cell.whc_CellBottomOffset; 417 | [sectionCacheHeightDictionary setValue:@(cacheHeight) forKey:@(indexPath.row).stringValue]; 418 | return cacheHeight; 419 | } 420 | 421 | @end 422 | #endif 423 | -------------------------------------------------------------------------------- /WHC_DataModelFactory.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C3D4D8031AF1D769004DE109 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C3D4D8021AF1D769004DE109 /* AppDelegate.m */; }; 11 | C3D4D8051AF1D769004DE109 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C3D4D8041AF1D769004DE109 /* main.m */; }; 12 | C3D4D8081AF1D769004DE109 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = C3D4D8071AF1D769004DE109 /* ViewController.m */; }; 13 | C3D4D80A1AF1D769004DE109 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C3D4D8091AF1D769004DE109 /* Images.xcassets */; }; 14 | C3D4D80D1AF1D769004DE109 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C3D4D80B1AF1D769004DE109 /* Main.storyboard */; }; 15 | C3D4D8191AF1D769004DE109 /* WHC_DataModelFactoryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C3D4D8181AF1D769004DE109 /* WHC_DataModelFactoryTests.m */; }; 16 | C3D4D82C1AF1D9DB004DE109 /* WHC_XMLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = C3D4D8291AF1D9DB004DE109 /* WHC_XMLParser.m */; }; 17 | FE1031311DD2BE0100A9F284 /* dict.png in Resources */ = {isa = PBXBuildFile; fileRef = FE1031301DD2BE0100A9F284 /* dict.png */; }; 18 | FE1BA7101ED02DE6009E8935 /* UITableViewCell+WHC_AutoHeightForCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1BA7071ED02DE6009E8935 /* UITableViewCell+WHC_AutoHeightForCell.m */; }; 19 | FE1BA7111ED02DE6009E8935 /* UIView+WHC_AutoLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1BA7091ED02DE6009E8935 /* UIView+WHC_AutoLayout.m */; }; 20 | FE1BA7121ED02DE6009E8935 /* UIView+WHC_Frame.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1BA70B1ED02DE6009E8935 /* UIView+WHC_Frame.m */; }; 21 | FE1BA7131ED02DE6009E8935 /* WHC_StackView.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1BA70F1ED02DE6009E8935 /* WHC_StackView.m */; }; 22 | FED9B1941DD1BFB0004D7873 /* oc.png in Resources */ = {isa = PBXBuildFile; fileRef = FED9B1921DD1BFB0004D7873 /* oc.png */; }; 23 | FED9B1951DD1BFB0004D7873 /* swift.png in Resources */ = {isa = PBXBuildFile; fileRef = FED9B1931DD1BFB0004D7873 /* swift.png */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXContainerItemProxy section */ 27 | C3D4D8131AF1D769004DE109 /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = C3D4D7F41AF1D769004DE109 /* Project object */; 30 | proxyType = 1; 31 | remoteGlobalIDString = C3D4D7FB1AF1D769004DE109; 32 | remoteInfo = WHC_DataModelFactory; 33 | }; 34 | /* End PBXContainerItemProxy section */ 35 | 36 | /* Begin PBXFileReference section */ 37 | C3D4D7FC1AF1D769004DE109 /* WHC_DataModelFactory.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WHC_DataModelFactory.app; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | C3D4D8001AF1D769004DE109 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 39 | C3D4D8011AF1D769004DE109 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 40 | C3D4D8021AF1D769004DE109 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 41 | C3D4D8041AF1D769004DE109 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 42 | C3D4D8061AF1D769004DE109 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 43 | C3D4D8071AF1D769004DE109 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 44 | C3D4D8091AF1D769004DE109 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 45 | C3D4D80C1AF1D769004DE109 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 46 | C3D4D8121AF1D769004DE109 /* WHC_DataModelFactoryTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WHC_DataModelFactoryTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | C3D4D8171AF1D769004DE109 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | C3D4D8181AF1D769004DE109 /* WHC_DataModelFactoryTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WHC_DataModelFactoryTests.m; sourceTree = ""; }; 49 | C3D4D8281AF1D9DB004DE109 /* WHC_XMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_XMLParser.h; sourceTree = ""; }; 50 | C3D4D8291AF1D9DB004DE109 /* WHC_XMLParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_XMLParser.m; sourceTree = ""; }; 51 | FE1031301DD2BE0100A9F284 /* dict.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = dict.png; sourceTree = ""; }; 52 | FE1BA7061ED02DE6009E8935 /* UITableViewCell+WHC_AutoHeightForCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITableViewCell+WHC_AutoHeightForCell.h"; sourceTree = ""; }; 53 | FE1BA7071ED02DE6009E8935 /* UITableViewCell+WHC_AutoHeightForCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITableViewCell+WHC_AutoHeightForCell.m"; sourceTree = ""; }; 54 | FE1BA7081ED02DE6009E8935 /* UIView+WHC_AutoLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+WHC_AutoLayout.h"; sourceTree = ""; }; 55 | FE1BA7091ED02DE6009E8935 /* UIView+WHC_AutoLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+WHC_AutoLayout.m"; sourceTree = ""; }; 56 | FE1BA70A1ED02DE6009E8935 /* UIView+WHC_Frame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+WHC_Frame.h"; sourceTree = ""; }; 57 | FE1BA70B1ED02DE6009E8935 /* UIView+WHC_Frame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+WHC_Frame.m"; sourceTree = ""; }; 58 | FE1BA70C1ED02DE6009E8935 /* WHC_AutoLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_AutoLayout.h; sourceTree = ""; }; 59 | FE1BA70D1ED02DE6009E8935 /* WHC_AutoLayoutUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_AutoLayoutUtilities.h; sourceTree = ""; }; 60 | FE1BA70E1ED02DE6009E8935 /* WHC_StackView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WHC_StackView.h; sourceTree = ""; }; 61 | FE1BA70F1ED02DE6009E8935 /* WHC_StackView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WHC_StackView.m; sourceTree = ""; }; 62 | FED9B1921DD1BFB0004D7873 /* oc.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = oc.png; sourceTree = ""; }; 63 | FED9B1931DD1BFB0004D7873 /* swift.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = swift.png; sourceTree = ""; }; 64 | /* End PBXFileReference section */ 65 | 66 | /* Begin PBXFrameworksBuildPhase section */ 67 | C3D4D7F91AF1D769004DE109 /* Frameworks */ = { 68 | isa = PBXFrameworksBuildPhase; 69 | buildActionMask = 2147483647; 70 | files = ( 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | C3D4D80F1AF1D769004DE109 /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | ); 79 | runOnlyForDeploymentPostprocessing = 0; 80 | }; 81 | /* End PBXFrameworksBuildPhase section */ 82 | 83 | /* Begin PBXGroup section */ 84 | C3D4D7F31AF1D769004DE109 = { 85 | isa = PBXGroup; 86 | children = ( 87 | C3D4D7FE1AF1D769004DE109 /* WHC_DataModelFactory */, 88 | C3D4D8151AF1D769004DE109 /* WHC_DataModelFactoryTests */, 89 | C3D4D7FD1AF1D769004DE109 /* Products */, 90 | ); 91 | sourceTree = ""; 92 | }; 93 | C3D4D7FD1AF1D769004DE109 /* Products */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | C3D4D7FC1AF1D769004DE109 /* WHC_DataModelFactory.app */, 97 | C3D4D8121AF1D769004DE109 /* WHC_DataModelFactoryTests.xctest */, 98 | ); 99 | name = Products; 100 | sourceTree = ""; 101 | }; 102 | C3D4D7FE1AF1D769004DE109 /* WHC_DataModelFactory */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | FE1BA7051ED02DE6009E8935 /* WHC_AutoLayoutKit */, 106 | FED9B1911DD1BFB0004D7873 /* images */, 107 | C3D4D8231AF1D9DB004DE109 /* WHCLib */, 108 | C3D4D8011AF1D769004DE109 /* AppDelegate.h */, 109 | C3D4D8021AF1D769004DE109 /* AppDelegate.m */, 110 | C3D4D8061AF1D769004DE109 /* ViewController.h */, 111 | C3D4D8071AF1D769004DE109 /* ViewController.m */, 112 | C3D4D8091AF1D769004DE109 /* Images.xcassets */, 113 | C3D4D80B1AF1D769004DE109 /* Main.storyboard */, 114 | C3D4D7FF1AF1D769004DE109 /* Supporting Files */, 115 | ); 116 | path = WHC_DataModelFactory; 117 | sourceTree = ""; 118 | }; 119 | C3D4D7FF1AF1D769004DE109 /* Supporting Files */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | C3D4D8001AF1D769004DE109 /* Info.plist */, 123 | C3D4D8041AF1D769004DE109 /* main.m */, 124 | ); 125 | name = "Supporting Files"; 126 | sourceTree = ""; 127 | }; 128 | C3D4D8151AF1D769004DE109 /* WHC_DataModelFactoryTests */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | C3D4D8181AF1D769004DE109 /* WHC_DataModelFactoryTests.m */, 132 | C3D4D8161AF1D769004DE109 /* Supporting Files */, 133 | ); 134 | path = WHC_DataModelFactoryTests; 135 | sourceTree = ""; 136 | }; 137 | C3D4D8161AF1D769004DE109 /* Supporting Files */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | C3D4D8171AF1D769004DE109 /* Info.plist */, 141 | ); 142 | name = "Supporting Files"; 143 | sourceTree = ""; 144 | }; 145 | C3D4D8231AF1D9DB004DE109 /* WHCLib */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | C3D4D8281AF1D9DB004DE109 /* WHC_XMLParser.h */, 149 | C3D4D8291AF1D9DB004DE109 /* WHC_XMLParser.m */, 150 | ); 151 | path = WHCLib; 152 | sourceTree = ""; 153 | }; 154 | FE1BA7051ED02DE6009E8935 /* WHC_AutoLayoutKit */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | FE1BA7061ED02DE6009E8935 /* UITableViewCell+WHC_AutoHeightForCell.h */, 158 | FE1BA7071ED02DE6009E8935 /* UITableViewCell+WHC_AutoHeightForCell.m */, 159 | FE1BA7081ED02DE6009E8935 /* UIView+WHC_AutoLayout.h */, 160 | FE1BA7091ED02DE6009E8935 /* UIView+WHC_AutoLayout.m */, 161 | FE1BA70A1ED02DE6009E8935 /* UIView+WHC_Frame.h */, 162 | FE1BA70B1ED02DE6009E8935 /* UIView+WHC_Frame.m */, 163 | FE1BA70C1ED02DE6009E8935 /* WHC_AutoLayout.h */, 164 | FE1BA70D1ED02DE6009E8935 /* WHC_AutoLayoutUtilities.h */, 165 | FE1BA70E1ED02DE6009E8935 /* WHC_StackView.h */, 166 | FE1BA70F1ED02DE6009E8935 /* WHC_StackView.m */, 167 | ); 168 | path = WHC_AutoLayoutKit; 169 | sourceTree = ""; 170 | }; 171 | FED9B1911DD1BFB0004D7873 /* images */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | FE1031301DD2BE0100A9F284 /* dict.png */, 175 | FED9B1921DD1BFB0004D7873 /* oc.png */, 176 | FED9B1931DD1BFB0004D7873 /* swift.png */, 177 | ); 178 | path = images; 179 | sourceTree = ""; 180 | }; 181 | /* End PBXGroup section */ 182 | 183 | /* Begin PBXNativeTarget section */ 184 | C3D4D7FB1AF1D769004DE109 /* WHC_DataModelFactory */ = { 185 | isa = PBXNativeTarget; 186 | buildConfigurationList = C3D4D81C1AF1D769004DE109 /* Build configuration list for PBXNativeTarget "WHC_DataModelFactory" */; 187 | buildPhases = ( 188 | C3D4D7F81AF1D769004DE109 /* Sources */, 189 | C3D4D7F91AF1D769004DE109 /* Frameworks */, 190 | C3D4D7FA1AF1D769004DE109 /* Resources */, 191 | ); 192 | buildRules = ( 193 | ); 194 | dependencies = ( 195 | ); 196 | name = WHC_DataModelFactory; 197 | productName = WHC_DataModelFactory; 198 | productReference = C3D4D7FC1AF1D769004DE109 /* WHC_DataModelFactory.app */; 199 | productType = "com.apple.product-type.application"; 200 | }; 201 | C3D4D8111AF1D769004DE109 /* WHC_DataModelFactoryTests */ = { 202 | isa = PBXNativeTarget; 203 | buildConfigurationList = C3D4D81F1AF1D769004DE109 /* Build configuration list for PBXNativeTarget "WHC_DataModelFactoryTests" */; 204 | buildPhases = ( 205 | C3D4D80E1AF1D769004DE109 /* Sources */, 206 | C3D4D80F1AF1D769004DE109 /* Frameworks */, 207 | C3D4D8101AF1D769004DE109 /* Resources */, 208 | ); 209 | buildRules = ( 210 | ); 211 | dependencies = ( 212 | C3D4D8141AF1D769004DE109 /* PBXTargetDependency */, 213 | ); 214 | name = WHC_DataModelFactoryTests; 215 | productName = WHC_DataModelFactoryTests; 216 | productReference = C3D4D8121AF1D769004DE109 /* WHC_DataModelFactoryTests.xctest */; 217 | productType = "com.apple.product-type.bundle.unit-test"; 218 | }; 219 | /* End PBXNativeTarget section */ 220 | 221 | /* Begin PBXProject section */ 222 | C3D4D7F41AF1D769004DE109 /* Project object */ = { 223 | isa = PBXProject; 224 | attributes = { 225 | LastUpgradeCheck = 0610; 226 | ORGANIZATIONNAME = "吴海超"; 227 | TargetAttributes = { 228 | C3D4D7FB1AF1D769004DE109 = { 229 | CreatedOnToolsVersion = 6.1.1; 230 | }; 231 | C3D4D8111AF1D769004DE109 = { 232 | CreatedOnToolsVersion = 6.1.1; 233 | TestTargetID = C3D4D7FB1AF1D769004DE109; 234 | }; 235 | }; 236 | }; 237 | buildConfigurationList = C3D4D7F71AF1D769004DE109 /* Build configuration list for PBXProject "WHC_DataModelFactory" */; 238 | compatibilityVersion = "Xcode 3.2"; 239 | developmentRegion = English; 240 | hasScannedForEncodings = 0; 241 | knownRegions = ( 242 | en, 243 | Base, 244 | ); 245 | mainGroup = C3D4D7F31AF1D769004DE109; 246 | productRefGroup = C3D4D7FD1AF1D769004DE109 /* Products */; 247 | projectDirPath = ""; 248 | projectRoot = ""; 249 | targets = ( 250 | C3D4D7FB1AF1D769004DE109 /* WHC_DataModelFactory */, 251 | C3D4D8111AF1D769004DE109 /* WHC_DataModelFactoryTests */, 252 | ); 253 | }; 254 | /* End PBXProject section */ 255 | 256 | /* Begin PBXResourcesBuildPhase section */ 257 | C3D4D7FA1AF1D769004DE109 /* Resources */ = { 258 | isa = PBXResourcesBuildPhase; 259 | buildActionMask = 2147483647; 260 | files = ( 261 | C3D4D80A1AF1D769004DE109 /* Images.xcassets in Resources */, 262 | FE1031311DD2BE0100A9F284 /* dict.png in Resources */, 263 | FED9B1951DD1BFB0004D7873 /* swift.png in Resources */, 264 | FED9B1941DD1BFB0004D7873 /* oc.png in Resources */, 265 | C3D4D80D1AF1D769004DE109 /* Main.storyboard in Resources */, 266 | ); 267 | runOnlyForDeploymentPostprocessing = 0; 268 | }; 269 | C3D4D8101AF1D769004DE109 /* Resources */ = { 270 | isa = PBXResourcesBuildPhase; 271 | buildActionMask = 2147483647; 272 | files = ( 273 | ); 274 | runOnlyForDeploymentPostprocessing = 0; 275 | }; 276 | /* End PBXResourcesBuildPhase section */ 277 | 278 | /* Begin PBXSourcesBuildPhase section */ 279 | C3D4D7F81AF1D769004DE109 /* Sources */ = { 280 | isa = PBXSourcesBuildPhase; 281 | buildActionMask = 2147483647; 282 | files = ( 283 | FE1BA7111ED02DE6009E8935 /* UIView+WHC_AutoLayout.m in Sources */, 284 | C3D4D82C1AF1D9DB004DE109 /* WHC_XMLParser.m in Sources */, 285 | C3D4D8081AF1D769004DE109 /* ViewController.m in Sources */, 286 | FE1BA7121ED02DE6009E8935 /* UIView+WHC_Frame.m in Sources */, 287 | FE1BA7131ED02DE6009E8935 /* WHC_StackView.m in Sources */, 288 | C3D4D8051AF1D769004DE109 /* main.m in Sources */, 289 | FE1BA7101ED02DE6009E8935 /* UITableViewCell+WHC_AutoHeightForCell.m in Sources */, 290 | C3D4D8031AF1D769004DE109 /* AppDelegate.m in Sources */, 291 | ); 292 | runOnlyForDeploymentPostprocessing = 0; 293 | }; 294 | C3D4D80E1AF1D769004DE109 /* Sources */ = { 295 | isa = PBXSourcesBuildPhase; 296 | buildActionMask = 2147483647; 297 | files = ( 298 | C3D4D8191AF1D769004DE109 /* WHC_DataModelFactoryTests.m in Sources */, 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | }; 302 | /* End PBXSourcesBuildPhase section */ 303 | 304 | /* Begin PBXTargetDependency section */ 305 | C3D4D8141AF1D769004DE109 /* PBXTargetDependency */ = { 306 | isa = PBXTargetDependency; 307 | target = C3D4D7FB1AF1D769004DE109 /* WHC_DataModelFactory */; 308 | targetProxy = C3D4D8131AF1D769004DE109 /* PBXContainerItemProxy */; 309 | }; 310 | /* End PBXTargetDependency section */ 311 | 312 | /* Begin PBXVariantGroup section */ 313 | C3D4D80B1AF1D769004DE109 /* Main.storyboard */ = { 314 | isa = PBXVariantGroup; 315 | children = ( 316 | C3D4D80C1AF1D769004DE109 /* Base */, 317 | ); 318 | name = Main.storyboard; 319 | sourceTree = ""; 320 | }; 321 | /* End PBXVariantGroup section */ 322 | 323 | /* Begin XCBuildConfiguration section */ 324 | C3D4D81A1AF1D769004DE109 /* Debug */ = { 325 | isa = XCBuildConfiguration; 326 | buildSettings = { 327 | ALWAYS_SEARCH_USER_PATHS = NO; 328 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 329 | CLANG_CXX_LIBRARY = "libc++"; 330 | CLANG_ENABLE_MODULES = YES; 331 | CLANG_ENABLE_OBJC_ARC = YES; 332 | CLANG_WARN_BOOL_CONVERSION = YES; 333 | CLANG_WARN_CONSTANT_CONVERSION = YES; 334 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 335 | CLANG_WARN_EMPTY_BODY = YES; 336 | CLANG_WARN_ENUM_CONVERSION = YES; 337 | CLANG_WARN_INT_CONVERSION = YES; 338 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 339 | CLANG_WARN_UNREACHABLE_CODE = YES; 340 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 341 | CODE_SIGN_IDENTITY = "-"; 342 | COPY_PHASE_STRIP = NO; 343 | ENABLE_STRICT_OBJC_MSGSEND = YES; 344 | GCC_C_LANGUAGE_STANDARD = gnu99; 345 | GCC_DYNAMIC_NO_PIC = NO; 346 | GCC_OPTIMIZATION_LEVEL = 0; 347 | GCC_PREPROCESSOR_DEFINITIONS = ( 348 | "DEBUG=1", 349 | "$(inherited)", 350 | ); 351 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 352 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 353 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 354 | GCC_WARN_UNDECLARED_SELECTOR = YES; 355 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 356 | GCC_WARN_UNUSED_FUNCTION = YES; 357 | GCC_WARN_UNUSED_VARIABLE = YES; 358 | MACOSX_DEPLOYMENT_TARGET = 10.10; 359 | MTL_ENABLE_DEBUG_INFO = YES; 360 | ONLY_ACTIVE_ARCH = YES; 361 | SDKROOT = macosx; 362 | }; 363 | name = Debug; 364 | }; 365 | C3D4D81B1AF1D769004DE109 /* Release */ = { 366 | isa = XCBuildConfiguration; 367 | buildSettings = { 368 | ALWAYS_SEARCH_USER_PATHS = NO; 369 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 370 | CLANG_CXX_LIBRARY = "libc++"; 371 | CLANG_ENABLE_MODULES = YES; 372 | CLANG_ENABLE_OBJC_ARC = YES; 373 | CLANG_WARN_BOOL_CONVERSION = YES; 374 | CLANG_WARN_CONSTANT_CONVERSION = YES; 375 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 376 | CLANG_WARN_EMPTY_BODY = YES; 377 | CLANG_WARN_ENUM_CONVERSION = YES; 378 | CLANG_WARN_INT_CONVERSION = YES; 379 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 380 | CLANG_WARN_UNREACHABLE_CODE = YES; 381 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 382 | CODE_SIGN_IDENTITY = "-"; 383 | COPY_PHASE_STRIP = YES; 384 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 385 | ENABLE_NS_ASSERTIONS = NO; 386 | ENABLE_STRICT_OBJC_MSGSEND = YES; 387 | GCC_C_LANGUAGE_STANDARD = gnu99; 388 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 389 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 390 | GCC_WARN_UNDECLARED_SELECTOR = YES; 391 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 392 | GCC_WARN_UNUSED_FUNCTION = YES; 393 | GCC_WARN_UNUSED_VARIABLE = YES; 394 | MACOSX_DEPLOYMENT_TARGET = 10.10; 395 | MTL_ENABLE_DEBUG_INFO = NO; 396 | SDKROOT = macosx; 397 | }; 398 | name = Release; 399 | }; 400 | C3D4D81D1AF1D769004DE109 /* Debug */ = { 401 | isa = XCBuildConfiguration; 402 | buildSettings = { 403 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 404 | COMBINE_HIDPI_IMAGES = YES; 405 | INFOPLIST_FILE = WHC_DataModelFactory/Info.plist; 406 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 407 | MACOSX_DEPLOYMENT_TARGET = 10.10; 408 | PRODUCT_NAME = "$(TARGET_NAME)"; 409 | }; 410 | name = Debug; 411 | }; 412 | C3D4D81E1AF1D769004DE109 /* Release */ = { 413 | isa = XCBuildConfiguration; 414 | buildSettings = { 415 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 416 | COMBINE_HIDPI_IMAGES = YES; 417 | INFOPLIST_FILE = WHC_DataModelFactory/Info.plist; 418 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 419 | MACOSX_DEPLOYMENT_TARGET = 10.10; 420 | PRODUCT_NAME = "$(TARGET_NAME)"; 421 | }; 422 | name = Release; 423 | }; 424 | C3D4D8201AF1D769004DE109 /* Debug */ = { 425 | isa = XCBuildConfiguration; 426 | buildSettings = { 427 | BUNDLE_LOADER = "$(TEST_HOST)"; 428 | COMBINE_HIDPI_IMAGES = YES; 429 | FRAMEWORK_SEARCH_PATHS = ( 430 | "$(DEVELOPER_FRAMEWORKS_DIR)", 431 | "$(inherited)", 432 | ); 433 | GCC_PREPROCESSOR_DEFINITIONS = ( 434 | "DEBUG=1", 435 | "$(inherited)", 436 | ); 437 | INFOPLIST_FILE = WHC_DataModelFactoryTests/Info.plist; 438 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 439 | PRODUCT_NAME = "$(TARGET_NAME)"; 440 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WHC_DataModelFactory.app/Contents/MacOS/WHC_DataModelFactory"; 441 | }; 442 | name = Debug; 443 | }; 444 | C3D4D8211AF1D769004DE109 /* Release */ = { 445 | isa = XCBuildConfiguration; 446 | buildSettings = { 447 | BUNDLE_LOADER = "$(TEST_HOST)"; 448 | COMBINE_HIDPI_IMAGES = YES; 449 | FRAMEWORK_SEARCH_PATHS = ( 450 | "$(DEVELOPER_FRAMEWORKS_DIR)", 451 | "$(inherited)", 452 | ); 453 | INFOPLIST_FILE = WHC_DataModelFactoryTests/Info.plist; 454 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 455 | PRODUCT_NAME = "$(TARGET_NAME)"; 456 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WHC_DataModelFactory.app/Contents/MacOS/WHC_DataModelFactory"; 457 | }; 458 | name = Release; 459 | }; 460 | /* End XCBuildConfiguration section */ 461 | 462 | /* Begin XCConfigurationList section */ 463 | C3D4D7F71AF1D769004DE109 /* Build configuration list for PBXProject "WHC_DataModelFactory" */ = { 464 | isa = XCConfigurationList; 465 | buildConfigurations = ( 466 | C3D4D81A1AF1D769004DE109 /* Debug */, 467 | C3D4D81B1AF1D769004DE109 /* Release */, 468 | ); 469 | defaultConfigurationIsVisible = 0; 470 | defaultConfigurationName = Release; 471 | }; 472 | C3D4D81C1AF1D769004DE109 /* Build configuration list for PBXNativeTarget "WHC_DataModelFactory" */ = { 473 | isa = XCConfigurationList; 474 | buildConfigurations = ( 475 | C3D4D81D1AF1D769004DE109 /* Debug */, 476 | C3D4D81E1AF1D769004DE109 /* Release */, 477 | ); 478 | defaultConfigurationIsVisible = 0; 479 | defaultConfigurationName = Release; 480 | }; 481 | C3D4D81F1AF1D769004DE109 /* Build configuration list for PBXNativeTarget "WHC_DataModelFactoryTests" */ = { 482 | isa = XCConfigurationList; 483 | buildConfigurations = ( 484 | C3D4D8201AF1D769004DE109 /* Debug */, 485 | C3D4D8211AF1D769004DE109 /* Release */, 486 | ); 487 | defaultConfigurationIsVisible = 0; 488 | defaultConfigurationName = Release; 489 | }; 490 | /* End XCConfigurationList section */ 491 | }; 492 | rootObject = C3D4D7F41AF1D769004DE109 /* Project object */; 493 | } 494 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/WHC_AutoLayoutKit/UIView+WHC_AutoLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // WHC_VIEW+WHC_AutoLayout.h 3 | // 4 | // Github 5 | // 6 | // Created by 吴海超 on 16/2/17. 7 | // Copyright © 2016年 吴海超. All rights reserved. 8 | // 9 | 10 | // 11 | // Permission is hereby granted, free of charge, to any person obtaining a copy 12 | // of this software and associated documentation files (the "Software"), to deal 13 | // in the Software without restriction, including without limitation the rights 14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 | // copies of the Software, and to permit persons to whom the Software is 16 | // furnished to do so, subject to the following conditions: 17 | // 18 | // The above copyright notice and this permission notice shall be included in 19 | // all copies or substantial portions of the Software. 20 | // 21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 | // THE SOFTWARE. 28 | 29 | #import "WHC_AutoLayoutUtilities.h" 30 | 31 | /// 布局方向 32 | typedef NS_OPTIONS(NSUInteger, WHC_LayoutOrientationOptions) { 33 | /// 垂直布局 34 | Vertical = 1 << 0, 35 | /// 横向布局 36 | Horizontal = 1 << 1, 37 | /// 垂直布局和横向布局 38 | All = 1 << 2 39 | }; 40 | 41 | /// 布局类型 42 | typedef NS_OPTIONS(NSUInteger, WHC_LayoutTypeOptions) { 43 | /// 默认类型 44 | DefaultType = 1 << 0, 45 | /// 左右类型 46 | LeftRightType = 1 << 1, 47 | }; 48 | 49 | typedef WHC_VIEW * (^ResetConstraintAttribute)(); 50 | typedef WHC_VIEW * (^ClearConstraintAttribute)(); 51 | typedef WHC_VIEW * (^RemoveConstraintAttribute)(NSLayoutAttribute attributes, ...); 52 | typedef WHC_VIEW * (^RemoveConstraintFromViewAttribute)(WHC_VIEW * view, NSLayoutAttribute attributes, ...); 53 | 54 | typedef WHC_VIEW * (^PriorityLow)(); 55 | typedef WHC_VIEW * (^PriorityHigh)(); 56 | typedef WHC_VIEW * (^PriorityRequired)(); 57 | typedef WHC_VIEW * (^PriorityFitting)(); 58 | typedef WHC_VIEW * (^PriorityValue)(CGFloat value); 59 | 60 | typedef WHC_VIEW * (^LeftSpace)(CGFloat value); 61 | typedef WHC_VIEW * (^LeftSpaceToView)(CGFloat value , WHC_VIEW * toView); 62 | typedef WHC_VIEW * (^LeftSpaceEqualView)(WHC_VIEW * view); 63 | typedef WHC_VIEW * (^LeftSpaceEqualViewOffset)(WHC_VIEW * view, CGFloat offset); 64 | 65 | typedef WHC_VIEW * (^LeadingSpace)(CGFloat value); 66 | typedef WHC_VIEW * (^LeadingSpaceToView)(CGFloat value , WHC_VIEW * toView); 67 | typedef WHC_VIEW * (^LeadingSpaceEqualView)(WHC_VIEW * view); 68 | typedef WHC_VIEW * (^LeadingSpaceEqualViewOffset)(WHC_VIEW * view, CGFloat offset); 69 | 70 | typedef WHC_VIEW * (^TrailingSpace)(CGFloat value); 71 | typedef WHC_VIEW * (^TrailingSpaceToView)(CGFloat value , WHC_VIEW * toView); 72 | typedef WHC_VIEW * (^TrailingSpaceEqualView)(WHC_VIEW * view); 73 | typedef WHC_VIEW * (^TrailingSpaceEqualViewOffset)(WHC_VIEW * view, CGFloat offset); 74 | 75 | typedef WHC_VIEW * (^BaseLineSpace)(CGFloat value); 76 | typedef WHC_VIEW * (^BaseLineSpaceToView)(CGFloat value , WHC_VIEW * toView); 77 | typedef WHC_VIEW * (^BaseLineSpaceEqualView)(WHC_VIEW * view); 78 | typedef WHC_VIEW * (^BaseLineSpaceEqualViewOffset)(WHC_VIEW * view, CGFloat offset); 79 | 80 | typedef WHC_VIEW * (^RightSpace)(CGFloat value); 81 | typedef WHC_VIEW * (^RightSpaceToView)(CGFloat value , WHC_VIEW * toView); 82 | typedef WHC_VIEW * (^RightSpaceEqualView)(WHC_VIEW * view); 83 | typedef WHC_VIEW * (^RightSpaceEqualViewOffset)(WHC_VIEW * view, CGFloat offset); 84 | 85 | typedef WHC_VIEW * (^TopSpace)(CGFloat value); 86 | typedef WHC_VIEW * (^TopSpaceToView)(CGFloat value , WHC_VIEW * toView); 87 | typedef WHC_VIEW * (^TopSpaceEqualView)(WHC_VIEW * view); 88 | typedef WHC_VIEW * (^TopSpaceEqualViewOffset)(WHC_VIEW * view, CGFloat offset); 89 | 90 | typedef WHC_VIEW * (^BottomSpace)(CGFloat value); 91 | typedef WHC_VIEW * (^BottomSpaceToView)(CGFloat value , WHC_VIEW * toView); 92 | typedef WHC_VIEW * (^BottomSpaceEqualView)(WHC_VIEW * view); 93 | typedef WHC_VIEW * (^BottomSpaceEqualViewOffset)(WHC_VIEW * view, CGFloat offset); 94 | 95 | typedef WHC_VIEW * (^Width)(CGFloat value); 96 | typedef WHC_VIEW * (^WidthAuto)(); 97 | typedef WHC_VIEW * (^WidthEqualView)(WHC_VIEW * view); 98 | typedef WHC_VIEW * (^WidthEqualViewRatio)(WHC_VIEW * view, CGFloat ratio); 99 | typedef WHC_VIEW * (^WidthHeightRatio)(CGFloat ratio); 100 | 101 | typedef WHC_VIEW * (^Height)(CGFloat value); 102 | typedef WHC_VIEW * (^HeightAuto)(); 103 | typedef WHC_VIEW * (^HeightEqualView)(WHC_VIEW * view); 104 | typedef WHC_VIEW * (^HeightEqualViewRatio)(WHC_VIEW * view, CGFloat ratio); 105 | typedef WHC_VIEW * (^HeightWidthRatio)(CGFloat ratio); 106 | 107 | typedef WHC_VIEW * (^CenterX)(CGFloat value); 108 | typedef WHC_VIEW * (^CenterXToView)(CGFloat value, WHC_VIEW * toView); 109 | 110 | typedef WHC_VIEW * (^CenterY)(CGFloat value); 111 | typedef WHC_VIEW * (^CenterYToView)(CGFloat value, WHC_VIEW * toView); 112 | 113 | typedef WHC_VIEW * (^Center)(CGFloat x, CGFloat y); 114 | typedef WHC_VIEW * (^CenterToView)(CGPoint center, WHC_VIEW * toView); 115 | 116 | typedef WHC_VIEW * (^size)(CGFloat width, CGFloat height); 117 | typedef WHC_VIEW * (^SizeEqual)(WHC_VIEW * view); 118 | 119 | typedef WHC_VIEW * (^FrameEqual)(WHC_VIEW * view); 120 | 121 | #pragma mark - UI自动布局 - 122 | 123 | @interface WHC_VIEW (WHC_AutoLayout) 124 | 125 | #pragma mark - api version ~ 2.0 - 126 | 127 | /// 重置缓存约束 128 | @property (nonatomic ,copy , readonly)ResetConstraintAttribute whc_ResetConstraint; 129 | /// 清除所有约束 130 | @property (nonatomic ,copy , readonly)ClearConstraintAttribute whc_ClearLayoutAttr; 131 | /// 移除约束(NSLayoutAttribute attributes, ...) 132 | @property (nonatomic ,copy , readonly)RemoveConstraintAttribute whc_RemoveLayoutAttrs; 133 | /// 移除约束从指定视图上(WHC_VIEW * view, NSLayoutAttribute attributes, ...) 134 | @property (nonatomic ,copy , readonly)RemoveConstraintFromViewAttribute whc_RemoveFromLayoutAttrs; 135 | 136 | /// 设置当前约束的低优先级 137 | @property (nonatomic ,copy , readonly)PriorityLow whc_PriorityLow; 138 | /// 设置当前约束的高优先级 139 | @property (nonatomic ,copy , readonly)PriorityHigh whc_PriorityHigh; 140 | /// 设置当前约束的默认优先级 141 | @property (nonatomic ,copy , readonly)PriorityRequired whc_PriorityRequired; 142 | /// 设置当前约束的合适优先级 143 | @property (nonatomic ,copy , readonly)PriorityFitting whc_PriorityFitting; 144 | /// 设置当前约束的优先级 (CGFloat value): 优先级大小(0-1000) 145 | @property (nonatomic ,copy , readonly)PriorityValue whc_Priority; 146 | 147 | /// 与父视图左边间距(CGFloat value) 148 | @property (nonatomic ,copy , readonly)LeftSpace whc_LeftSpace; 149 | /// 与相对视图toView左边间距(CGFloat value,WHC_VIEW * toView) 150 | @property (nonatomic ,copy , readonly)LeftSpaceToView whc_LeftSpaceToView; 151 | /// 与视图view左边间距相等(WHC_VIEW * view) 152 | @property (nonatomic ,copy , readonly)LeftSpaceEqualView whc_LeftSpaceEqualView; 153 | /// 与视图view左边间距相等并偏移offset(WHC_VIEW * view, CGFloat offset) 154 | @property (nonatomic ,copy , readonly)LeftSpaceEqualViewOffset whc_LeftSpaceEqualViewOffset; 155 | 156 | /// 与父视图左边间距(CGFloat value) 157 | @property (nonatomic ,copy , readonly)LeadingSpace whc_LeadingSpace; 158 | /// 与相对视图toView左边间距(CGFloat value,WHC_VIEW * toView) 159 | @property (nonatomic ,copy , readonly)LeadingSpaceToView whc_LeadingSpaceToView; 160 | /// 与视图view左边间距相等(WHC_VIEW * view) 161 | @property (nonatomic ,copy , readonly)LeadingSpaceEqualView whc_LeadingSpaceEqualView; 162 | /// 与视图view左边间距相等并偏移offset (WHC_VIEW * view, CGFloat offset) 163 | @property (nonatomic ,copy , readonly)LeadingSpaceEqualViewOffset whc_LeadingSpaceEqualViewOffset; 164 | 165 | /// 与父视图右边间距(CGFloat value) 166 | @property (nonatomic ,copy , readonly)TrailingSpace whc_TrailingSpace; 167 | /// 与相对视图toView右边间距(CGFloat value,WHC_VIEW * toView) 168 | @property (nonatomic ,copy , readonly)TrailingSpaceToView whc_TrailingSpaceToView; 169 | /// 与视图view右边间距相等(WHC_VIEW * view) 170 | @property (nonatomic ,copy , readonly)TrailingSpaceEqualView whc_TrailingSpaceEqualView; 171 | /// 与视图view右边间距相等并偏移offset(WHC_VIEW * view, CGFloat offset) 172 | @property (nonatomic ,copy , readonly)TrailingSpaceEqualViewOffset whc_TrailingSpaceEqualViewOffset; 173 | 174 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 175 | /// 与父视图底边间距Y(CGFloat value) 176 | @property (nonatomic ,copy , readonly)BaseLineSpace whc_FirstBaseLine; 177 | /// 与相对视图toView底边间距Y(CGFloat value,WHC_VIEW * toView) 178 | @property (nonatomic ,copy , readonly)BaseLineSpaceToView whc_FirstBaseLineToView; 179 | /// 与视图view底边间距Y相等(WHC_VIEW * view) 180 | @property (nonatomic ,copy , readonly)BaseLineSpaceEqualView whc_FirstBaseLineEqualView; 181 | /// 与视图view底边间距Y相等并偏移offset(WHC_VIEW * view, CGFloat offset) 182 | @property (nonatomic ,copy , readonly)BaseLineSpaceEqualViewOffset whc_FirstBaseLineEqualViewOffset; 183 | #endif 184 | 185 | /// 与父视图底边间距Y(CGFloat value) 186 | @property (nonatomic ,copy , readonly)BaseLineSpace whc_LastBaseLine; 187 | /// 与相对视图toView底边间距Y(CGFloat value,WHC_VIEW * toView) 188 | @property (nonatomic ,copy , readonly)BaseLineSpaceToView whc_LastBaseLineToView; 189 | /// 与视图view底边间距Y相等(WHC_VIEW * view) 190 | @property (nonatomic ,copy , readonly)BaseLineSpaceEqualView whc_LastBaseLineEqualView; 191 | /// 与视图view底边间距Y相等并偏移offset(WHC_VIEW * view, CGFloat offset) 192 | @property (nonatomic ,copy , readonly)BaseLineSpaceEqualViewOffset whc_LastBaseLineEqualViewOffset; 193 | /// 与父视图右边间距(CGFloat value) 194 | @property (nonatomic ,copy , readonly)RightSpace whc_RightSpace; 195 | /// 与相对视图toView右边间距(CGFloat value,WHC_VIEW * toView) 196 | @property (nonatomic ,copy , readonly)RightSpaceToView whc_RightSpaceToView; 197 | /// 与相对视图toView右边间距相等(WHC_VIEW toView) 198 | @property (nonatomic ,copy , readonly)RightSpaceEqualView whc_RightSpaceEqualView; 199 | /// 与相对视图toView右边间距相等并偏移offset(WHC_VIEW toView, CGFloat offset) 200 | @property (nonatomic ,copy , readonly)RightSpaceEqualViewOffset whc_RightSpaceEqualViewOffset; 201 | 202 | /// 与父视图顶边间距(CGFloat value) 203 | @property (nonatomic ,copy , readonly)TopSpace whc_TopSpace; 204 | /// 与相对视图toView顶边间距(CGFloat value,WHC_VIEW * toView) 205 | @property (nonatomic ,copy , readonly)TopSpaceToView whc_TopSpaceToView; 206 | /// 与视图view顶边间距相等(WHC_VIEW * view) 207 | @property (nonatomic ,copy , readonly)TopSpaceEqualView whc_TopSpaceEqualView; 208 | /// 与视图view顶边间距相等并偏移offset(WHC_VIEW * view, CGFloat offset) 209 | @property (nonatomic ,copy , readonly)TopSpaceEqualViewOffset whc_TopSpaceEqualViewOffset; 210 | 211 | /// 与父视图底边间距(CGFloat value) 212 | @property (nonatomic ,copy , readonly)BottomSpace whc_BottomSpace; 213 | /// 与相对视图toView底边间距(CGFloat value,WHC_VIEW * toView) 214 | @property (nonatomic ,copy , readonly)BottomSpaceToView whc_BottomSpaceToView; 215 | /// 与相对视图toView底边间距相等(WHC_VIEW * toView) 216 | @property (nonatomic ,copy , readonly)BottomSpaceEqualView whc_BottomSpaceEqualView; 217 | /// 与相对视图toView底边间距相等并偏移offset(WHC_VIEW * toView, CGFloat offset) 218 | @property (nonatomic ,copy , readonly)BottomSpaceEqualViewOffset whc_BottomSpaceEqualViewOffset; 219 | 220 | /// 宽度(CGFloat value) 221 | @property (nonatomic ,copy , readonly)Width whc_Width; 222 | /// 宽度自动() 223 | @property (nonatomic ,copy , readonly)WidthAuto whc_WidthAuto; 224 | /// 宽度等于视图view(WHC_VIEW * view) 225 | @property (nonatomic ,copy , readonly)WidthEqualView whc_WidthEqualView; 226 | /// 宽度等于视图view 参照比例Ratio(WHC_VIEW * view ,CGFloat ratio) 227 | @property (nonatomic ,copy , readonly)WidthEqualViewRatio whc_WidthEqualViewRatio; 228 | /// 视图自身宽度与高度的比(CGFloat Ratio) 229 | @property (nonatomic ,copy , readonly)WidthHeightRatio whc_WidthHeightRatio; 230 | 231 | /// 高度(CGFloat value) 232 | @property (nonatomic ,copy , readonly)Height whc_Height; 233 | /// 高度自动() 234 | @property (nonatomic ,copy , readonly)HeightAuto whc_HeightAuto; 235 | /// 高度等于视图view(WHC_VIEW * view) 236 | @property (nonatomic ,copy , readonly)HeightEqualView whc_HeightEqualView; 237 | /// 高度等于视图view 参照比例Ratio(WHC_VIEW * view ,CGFloat ratio) 238 | @property (nonatomic ,copy , readonly)HeightEqualViewRatio whc_HeightEqualViewRatio; 239 | /// 视图自身高度与宽度的比(CGFloat Ratio) 240 | @property (nonatomic ,copy , readonly)HeightWidthRatio whc_HeightWidthRatio; 241 | 242 | /// 中心X与父视图偏移(CGFloat value) 243 | @property (nonatomic ,copy , readonly)CenterX whc_CenterX; 244 | /// 中心X与视图view偏移(CGFloat value , WHC_VIEW * toView) 245 | @property (nonatomic ,copy , readonly)CenterXToView whc_CenterXToView; 246 | 247 | /// 中心Y与父视图偏移(CGFloat value) 248 | @property (nonatomic ,copy , readonly)CenterY whc_CenterY; 249 | /// 中心Y与视图view偏移(CGFloat value , WHC_VIEW * toView) 250 | @property (nonatomic ,copy , readonly)CenterYToView whc_CenterYToView; 251 | 252 | /// 中心与父视图偏移(CGFloat value) 253 | @property (nonatomic ,copy , readonly)Center whc_Center; 254 | /// 中心与视图view偏移(CGFloat value , WHC_VIEW * toView) 255 | @property (nonatomic ,copy , readonly)CenterToView whc_CenterToView; 256 | 257 | /// size设置(CGFloat width, CGFloat height) 258 | @property (nonatomic ,copy , readonly)size whc_Size; 259 | /// size设置(WHC_VIEW * view) 260 | @property (nonatomic ,copy , readonly)SizeEqual whc_SizeEqualView; 261 | 262 | /// frame设置(WHC_VIEW * view) 263 | @property (nonatomic ,copy , readonly)FrameEqual whc_FrameEqualView; 264 | #pragma mark - api version ~ 1.0 - 265 | 266 | 267 | /** 268 | 重置缓存的约束,该方法在当前视图对象移除从父视图上可能需要调用清除与父视图之前旧约束缓存对象 269 | 270 | @return 返回当前视图 271 | */ 272 | - (WHC_VIEW *)whc_ResetConstraints; 273 | 274 | /** 275 | 清除所有布局属性 276 | 277 | @return 返回当前视图 278 | */ 279 | - (WHC_VIEW *)whc_ClearLayoutAttrs; 280 | 281 | /** 282 | 移除一个或者一组约束 283 | 284 | @param attributes 约束类型(可变参数) 285 | @return 返回当前视图 286 | */ 287 | - (WHC_VIEW *)whc_RemoveLayoutAttr:(NSLayoutAttribute)attributes, ...; 288 | 289 | 290 | /** 291 | 移除一个或者一组约束从指定的视图上 292 | 293 | @param view 指定视图 294 | @param attributes 约束类型(可变参数) 295 | @return 返回当前视图 296 | */ 297 | - (WHC_VIEW *)whc_RemoveFrom:(WHC_VIEW *)view layoutAttrs:(NSLayoutAttribute)attributes, ...; 298 | 299 | /** 300 | 设置当前约束的低优先级 301 | 302 | @return 返回当前视图 303 | */ 304 | - (WHC_VIEW *)whc_priorityLow; 305 | 306 | /** 307 | 设置当前约束的高优先级 308 | 309 | @return 返回当前视图 310 | */ 311 | - (WHC_VIEW *)whc_priorityHigh; 312 | 313 | /** 314 | 设置当前约束的默认优先级 315 | 316 | @return 返回当前视图 317 | */ 318 | - (WHC_VIEW *)whc_priorityRequired; 319 | 320 | /** 321 | 设置当前约束的合适优先级 322 | 323 | @return 返回当前视图 324 | */ 325 | - (WHC_VIEW *)whc_priorityFitting; 326 | 327 | /** 328 | 设置当前约束的优先级 329 | 330 | @param value 优先级大小(0-1000) 331 | @return 返回当前视图 332 | */ 333 | - (WHC_VIEW *)whc_priority:(CGFloat)value; 334 | 335 | /** 336 | 设置左边距(默认相对父视图) 337 | 338 | @param leftSpace 左边距 339 | @return 返回当前视图 340 | */ 341 | - (WHC_VIEW *)whc_LeftSpace:(CGFloat)leftSpace; 342 | 343 | 344 | /** 345 | 设置左边距 346 | 347 | @param leftSpace 左边距 348 | @param toView 相对视图 349 | @return 返回当前视图 350 | */ 351 | - (WHC_VIEW *)whc_LeftSpace:(CGFloat)leftSpace toView:(WHC_VIEW *)toView; 352 | 353 | /** 354 | 设置左边距与视图view左边距相等 355 | 356 | @param view 相对视图 357 | @return 返回当前视图 358 | */ 359 | - (WHC_VIEW *)whc_LeftSpaceEqualView:(WHC_VIEW *)view; 360 | 361 | /** 362 | 设置左边距与视图view左边距相等并偏移offset 363 | 364 | @param view 相对视图 365 | @param offset 偏移量 366 | @return 返回当前视图 367 | */ 368 | - (WHC_VIEW *)whc_LeftSpaceEqualView:(WHC_VIEW *)view offset:(CGFloat)offset; 369 | 370 | /** 371 | 设置右边距(默认相对父视图) 372 | 373 | @param rightSpace 右边距 374 | @return 返回当前视图 375 | */ 376 | - (WHC_VIEW *)whc_RightSpace:(CGFloat)rightSpace; 377 | 378 | /** 379 | 设置右边距 380 | 381 | @param rightSpace 右边距 382 | @param toView 相对视图 383 | @return 返回当前视图 384 | */ 385 | - (WHC_VIEW *)whc_RightSpace:(CGFloat)rightSpace toView:(WHC_VIEW *)toView; 386 | 387 | /** 388 | 设置右边距与视图view左对齐边距相等 389 | 390 | @param view 相对视图 391 | @return 返回当前视图 392 | */ 393 | - (WHC_VIEW *)whc_RightSpaceEqualView:(WHC_VIEW *)view; 394 | 395 | /** 396 | 设置右边距与视图view左对齐边距相等并偏移offset 397 | 398 | @param view 相对视图 399 | @param offset 偏移量 400 | @return 返回当前视图 401 | */ 402 | - (WHC_VIEW *)whc_RightSpaceEqualView:(WHC_VIEW *)view offset:(CGFloat)offset; 403 | 404 | /** 405 | 设置左对齐(默认相对父视图) 406 | 407 | @param leadingSpace 左边距 408 | @return 返回当前视图 409 | */ 410 | - (WHC_VIEW *)whc_LeadingSpace:(CGFloat)leadingSpace; 411 | 412 | /** 413 | 设置左对齐 414 | 415 | @param leadingSpace 左边距 416 | @param toView 相对视图 417 | @return 返回当前视图 418 | */ 419 | 420 | - (WHC_VIEW *)whc_LeadingSpace:(CGFloat)leadingSpace toView:(WHC_VIEW *)toView; 421 | 422 | /** 423 | 设置左对齐边距与某视图左对齐边距相等 424 | 425 | @param view 相对视图 426 | @return 返回当前视图 427 | */ 428 | - (WHC_VIEW *)whc_LeadingSpaceEqualView:(WHC_VIEW *)view; 429 | 430 | /** 431 | 设置左对齐边距与某视图左对齐边距相等并偏移offset 432 | 433 | @param view 相对视图 434 | @param offset 偏移量 435 | @return 返回当前视图 436 | */ 437 | - (WHC_VIEW *)whc_LeadingSpaceEqualView:(WHC_VIEW *)view offset:(CGFloat)offset; 438 | 439 | /** 440 | 设置右对齐(默认相对父视图) 441 | 442 | @param trailingSpace 右边距 443 | @return 返回当前视图 444 | */ 445 | - (WHC_VIEW *)whc_TrailingSpace:(CGFloat)trailingSpace; 446 | 447 | /** 448 | 设置右对齐 449 | 450 | @param trailingSpace 右边距 451 | @param toView 相对视图 452 | @return 返回当前视图 453 | */ 454 | - (WHC_VIEW *)whc_TrailingSpace:(CGFloat)trailingSpace toView:(WHC_VIEW *)toView; 455 | 456 | /** 457 | 设置右对齐边距与某视图右对齐边距相等 458 | 459 | @param view 相对视图 460 | @return 返回当前视图 461 | */ 462 | - (WHC_VIEW *)whc_TrailingSpaceEqualView:(WHC_VIEW *)view; 463 | 464 | /** 465 | 设置右对齐边距与某视图右对齐边距相等并偏移offset 466 | 467 | @param view 相对视图 468 | @param offset 偏移量 469 | @return 返回当前视图 470 | */ 471 | - (WHC_VIEW *)whc_TrailingSpaceEqualView:(WHC_VIEW *)view offset:(CGFloat)offset; 472 | 473 | /** 474 | 设置顶边距(默认相对父视图) 475 | 476 | @param topSpace 顶边距 477 | @return 返回当前视图 478 | */ 479 | - (WHC_VIEW *)whc_TopSpace:(CGFloat)topSpace; 480 | 481 | /** 482 | 设置顶边距 483 | 484 | @param topSpace 顶边距 485 | @param toView 相对视图 486 | @return 返回当前视图 487 | */ 488 | - (WHC_VIEW *)whc_TopSpace:(CGFloat)topSpace toView:(WHC_VIEW *)toView; 489 | 490 | /** 491 | 设置顶边距与视图view顶边距相等 492 | 493 | @param view 相对视图 494 | @return 返回当前视图 495 | */ 496 | - (WHC_VIEW *)whc_TopSpaceEqualView:(WHC_VIEW *)view; 497 | 498 | /** 499 | 设置顶边距与视图view顶边距相等并偏移offset 500 | 501 | @param view 相对视图 502 | @param offset 偏移量 503 | @return 返回当前视图 504 | */ 505 | - (WHC_VIEW *)whc_TopSpaceEqualView:(WHC_VIEW *)view offset:(CGFloat)offset; 506 | 507 | /** 508 | 设置底边距(默认相对父视图) 509 | 510 | @param bottomSpace 底边距 511 | @return 返回当前视图 512 | */ 513 | - (WHC_VIEW *)whc_BottomSpace:(CGFloat)bottomSpace; 514 | 515 | /** 516 | 设置底边距 517 | 518 | @param bottomSpace 底边距 519 | @param toView 相对视图 520 | @return 返回当前视图 521 | */ 522 | - (WHC_VIEW *)whc_BottomSpace:(CGFloat)bottomSpace toView:(WHC_VIEW *)toView; 523 | 524 | /** 525 | 设置底边距与视图view底边距相等 526 | 527 | @param view 相对视图 528 | @return 返回当前视图 529 | */ 530 | - (WHC_VIEW *)whc_BottomSpaceEqualView:(WHC_VIEW *)view; 531 | 532 | /** 533 | 设置底边距与视图view底边距相等并偏移offset 534 | 535 | @param view 相对视图 536 | @param offset 偏移量 537 | @return 返回当前视图 538 | */ 539 | - (WHC_VIEW *)whc_BottomSpaceEqualView:(WHC_VIEW *)view offset:(CGFloat)offset; 540 | 541 | /** 542 | 设置宽度 543 | 544 | @param width 宽度 545 | @return 返回当前视图 546 | */ 547 | - (WHC_VIEW *)whc_Width:(CGFloat)width; 548 | 549 | /** 550 | 设置宽度与某个视图相等 551 | 552 | @param view 相对视图 553 | @return 返回当前视图 554 | */ 555 | - (WHC_VIEW *)whc_WidthEqualView:(WHC_VIEW *)view; 556 | 557 | /** 558 | 设置宽度与视图view相等 559 | 560 | @param view 相对视图 561 | @param ratio 比例 562 | @return 返回当前视图 563 | */ 564 | - (WHC_VIEW *)whc_WidthEqualView:(WHC_VIEW *)view ratio:(CGFloat)ratio; 565 | 566 | /** 567 | 设置自动宽度 568 | 569 | @return 返回当前视图 570 | */ 571 | - (WHC_VIEW *)whc_AutoWidth; 572 | 573 | /** 574 | 设置视图自身宽度与高度的比 575 | 576 | @param ratio 比例 577 | @return 返回当前视图 578 | */ 579 | - (WHC_VIEW *)whc_WidthHeightRatio:(CGFloat)ratio; 580 | 581 | /** 582 | 设置高度 583 | 584 | @param height 高度 585 | @return 返回当前视图 586 | */ 587 | - (WHC_VIEW *)whc_Height:(CGFloat)height; 588 | 589 | /** 590 | 设置高度与视图view相等 591 | 592 | @param view 相对视图 593 | @return 返回当前视图 594 | */ 595 | - (WHC_VIEW *)whc_HeightEqualView:(WHC_VIEW *)view; 596 | 597 | /** 598 | 设置高度与视图view相等 599 | 600 | @param view 相对视图 601 | @param ratio 比例 602 | @return 返回当前视图 603 | */ 604 | - (WHC_VIEW *)whc_HeightEqualView:(WHC_VIEW *)view ratio:(CGFloat)ratio; 605 | 606 | /** 607 | 设置自动高度 608 | 609 | @return 返回当前视图 610 | */ 611 | - (WHC_VIEW *)whc_AutoHeight; 612 | 613 | /** 614 | 设置视图自身高度与宽度的比 615 | 616 | @param ratio 比例 617 | @return 返回当前视图 618 | */ 619 | - (WHC_VIEW *)whc_HeightWidthRatio:(CGFloat)ratio; 620 | 621 | /** 622 | 设置中心x与父视图中心的偏移 centerX = 0 与父视图中心x重合 623 | 624 | @param centerX 中心x坐标偏移 625 | @return 返回当前视图 626 | */ 627 | - (WHC_VIEW *)whc_CenterX:(CGFloat)centerX; 628 | 629 | /** 630 | 设置中心x与相对视图中心的偏移 centerX = 0 与相对视图中心x重合 631 | 632 | @param centerX 中心x坐标偏移 633 | @param toView 相对视图 634 | @return 返回当前视图 635 | */ 636 | - (WHC_VIEW *)whc_CenterX:(CGFloat)centerX toView:(WHC_VIEW *)toView; 637 | 638 | /** 639 | 设置中心y与父视图中心的偏移 centerY = 0 与父视图中心y重合 640 | 641 | @param centerY 中心y坐标偏移 642 | @return 返回当前视图 643 | */ 644 | - (WHC_VIEW *)whc_CenterY:(CGFloat)centerY; 645 | 646 | /** 647 | 设置中心y与相对视图中心的偏移 centerY = 0 与相对视图中心y重合 648 | 649 | @param centerY 中心y坐标偏移 650 | @param toView 相对视图 651 | @return 返回当前视图 652 | */ 653 | - (WHC_VIEW *)whc_CenterY:(CGFloat)centerY toView:(WHC_VIEW *)toView; 654 | 655 | #if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100) 656 | /** 657 | 设置顶部基线偏移(默认相对父视图) 658 | 659 | @param space 间隙 660 | @return 返回当前视图 661 | */ 662 | - (WHC_VIEW *)whc_FirstBaseLine:(CGFloat)space; 663 | 664 | /** 665 | 设置顶部基线与对象视图底部基线偏移 666 | 667 | @param space 间隙 668 | @param toView 相对视图 669 | @return 返回当前视图 670 | */ 671 | - (WHC_VIEW *)whc_FirstBaseLine:(CGFloat)space toView:(WHC_VIEW *)toView; 672 | 673 | /** 674 | 设置顶部基线与相对视图顶部基线相等 675 | 676 | @param view 相对视图 677 | @return 返回当前视图 678 | */ 679 | - (WHC_VIEW *)whc_FirstBaseLineEqualView:(WHC_VIEW *)view; 680 | 681 | /** 682 | 设置顶部基线与相对视图顶部基线相等并偏移offset 683 | 684 | @param view 相对视图 685 | @param offset 偏移量 686 | @return 返回当前视图 687 | */ 688 | - (WHC_VIEW *)whc_FirstBaseLineEqualView:(WHC_VIEW *)view offset:(CGFloat)offset; 689 | 690 | #endif 691 | 692 | /** 693 | 设置底部基线偏移(默认相对父视图) 694 | 695 | @param space 间隙 696 | @return 返回当前视图 697 | */ 698 | - (WHC_VIEW *)whc_LastBaseLine:(CGFloat)space; 699 | 700 | /** 701 | 设置底部基线与对象视图顶部基线偏移 702 | 703 | @param space 间隙 704 | @param toView 相对视图 705 | @return 返回当前视图 706 | */ 707 | - (WHC_VIEW *)whc_LastBaseLine:(CGFloat)space toView:(WHC_VIEW *)toView; 708 | 709 | /** 710 | 设置底部基线与相对视图底部基线相等 711 | 712 | @param view 相对视图 713 | @return 返回当前视图 714 | */ 715 | - (WHC_VIEW *)whc_LastBaseLineEqualView:(WHC_VIEW *)view; 716 | 717 | /** 718 | 设置底部基线与相对视图底部基线相等并偏移offset 719 | 720 | @param view 相对视图 721 | @param offset 偏移量 722 | @return 返回当前视图 723 | */ 724 | - (WHC_VIEW *)whc_LastBaseLineEqualView:(WHC_VIEW *)view offset:(CGFloat)offset; 725 | 726 | 727 | /** 728 | 设置中心偏移(默认相对父视图)center = CGPointZero 与父视图中心重合 729 | 730 | @param center 中心偏移xy 731 | @return 返回当前视图 732 | */ 733 | - (WHC_VIEW *)whc_Center:(CGPoint)center; 734 | 735 | /** 736 | 设置中心偏移(默认相对父视图)center = CGPointZero 与父视图中心重合 737 | 738 | @param center 中心偏移xy 739 | @param toView 相对视图 740 | @return 返回当前视图 741 | */ 742 | - (WHC_VIEW *)whc_Center:(CGPoint)center toView:(WHC_VIEW *)toView; 743 | 744 | /** 745 | 设置frame(默认相对父视图) 746 | 747 | @param left 左边距 748 | @param top 顶边距 749 | @param width 宽度 750 | @param height 高度 751 | @return 返回当前视图 752 | */ 753 | - (WHC_VIEW *)whc_Frame:(CGFloat)left top:(CGFloat)top width:(CGFloat)width height:(CGFloat)height; 754 | 755 | /** 756 | 设置frame (默认相对父视图) 757 | 758 | @param left 左边距 759 | @param top 顶边距 760 | @param right 右边距 761 | @param bottom 底边距 762 | @return 返回当前视图 763 | */ 764 | 765 | - (WHC_VIEW *)whc_AutoSize:(CGFloat)left top:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom; 766 | 767 | /** 768 | 设置frame 769 | 770 | @param left 左边距 771 | @param top 顶边距 772 | @param width 宽度 773 | @param height 高度 774 | @param toView 相对视图 775 | @return 返回当前视图 776 | */ 777 | 778 | - (WHC_VIEW *)whc_Frame:(CGFloat)left top:(CGFloat)top width:(CGFloat)width height:(CGFloat)height toView:(WHC_VIEW *)toView; 779 | 780 | /** 781 | 设置frame (默认相对父视图) 782 | 783 | @param left 左边距 784 | @param top 顶边距 785 | @param right 右边距 786 | @param height 高度 787 | @return 返回当前视图 788 | */ 789 | 790 | - (WHC_VIEW *)whc_AutoWidth:(CGFloat)left top:(CGFloat)top right:(CGFloat)right height:(CGFloat)height; 791 | 792 | /** 793 | 设置frame (默认相对父视图) 794 | 795 | @param left 左边距 796 | @param top 顶边距 797 | @param width 宽度 798 | @param bottom 底边距 799 | @return 返回当前视图 800 | */ 801 | 802 | - (WHC_VIEW *)whc_AutoHeight:(CGFloat)left top:(CGFloat)top width:(CGFloat)width bottom:(CGFloat)bottom; 803 | 804 | /** 805 | 设置frame 806 | 807 | @param left 左边距 808 | @param top 顶边距 809 | @param right 右边距 810 | @param bottom 底边距 811 | @param toView 相对视图 812 | @return 返回当前视图 813 | */ 814 | 815 | - (WHC_VIEW *)whc_AutoSize:(CGFloat)left top:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom toView:(WHC_VIEW *)toView; 816 | 817 | /** 818 | 设置frame 819 | 820 | @param left 左边距 821 | @param top 顶边距 822 | @param right 右边距 823 | @param height 高度 824 | @param toView 相对视图 825 | @return 返回当前视图 826 | */ 827 | 828 | - (WHC_VIEW *)whc_AutoWidth:(CGFloat)left top:(CGFloat)top right:(CGFloat)right height:(CGFloat)height toView:(WHC_VIEW *)toView; 829 | 830 | /** 831 | 设置frame (默认相对父视图) 832 | 833 | @param left 左边距 834 | @param top 顶边距 835 | @param width 宽度 836 | @param bottom 底边距 837 | @return 返回当前视图 838 | */ 839 | 840 | - (WHC_VIEW *)whc_AutoHeight:(CGFloat)left top:(CGFloat)top width:(CGFloat)width bottom:(CGFloat)bottom toView:(WHC_VIEW *)toView; 841 | 842 | /** 843 | 设置视图显示宽高 844 | 845 | @param size 视图宽高 846 | @return 返回当前视图 847 | */ 848 | 849 | - (WHC_VIEW *)whc_Size:(CGSize)size; 850 | 851 | /** 852 | 设置视图size等于view 853 | 854 | @param view 相对视图 855 | @return 返回当前视图 856 | */ 857 | - (WHC_VIEW *)whc_SizeEqualView:(WHC_VIEW *)view; 858 | 859 | /** 860 | 设置视图frame等于view 861 | @param view 相对视图 862 | @return 返回当前视图 863 | */ 864 | - (WHC_VIEW *)whc_FrameEqualView:(WHC_VIEW *)view; 865 | 866 | #if TARGET_OS_IPHONE || TARGET_OS_TV 867 | 868 | #pragma mark - Xib智能布局模块 - 869 | 870 | /** 871 | 对整个Xib(使用3.5寸xib)上UI控件垂直和横向智能添加约束进行布局(从此告别xib上拖拽添加约束方式) 872 | */ 873 | 874 | - (void)whc_AutoXibLayout; 875 | 876 | /** 877 | 对整个Xib(使用3.5寸xib)上UI控件横向智能添加约束进行布局(从此告别xib上拖拽添加约束方式) 878 | */ 879 | 880 | - (void)whc_AutoXibLayoutType:(WHC_LayoutTypeOptions)type; 881 | 882 | /** 883 | 对整个storyboard(使用4.7寸xib)上UI控件垂直和横向智能添加约束进行布局(从此告别xib上拖拽添加约束方式) 884 | */ 885 | 886 | - (void)whc_AutoSBLayout; 887 | 888 | /** 889 | 对整个storyboard(使用4.7寸xib)上UI控件横向智能添加约束进行布局(从此告别xib上拖拽添加约束方式) 890 | */ 891 | 892 | - (void)whc_AutoSBLayoutType:(WHC_LayoutTypeOptions)type; 893 | 894 | /** 895 | 对整个Xib(使用3.5寸xib)上UI控件横向智能添加约束进行布局(从此告别xib上拖拽添加约束方式) 896 | */ 897 | 898 | - (void)whc_AutoXibHorizontalLayout; 899 | 900 | /** 901 | 对整个Xib(使用3.5寸xib)上UI控件横向智能添加约束进行布局(从此告别xib上拖拽添加约束方式) 902 | */ 903 | 904 | - (void)whc_AutoXibHorizontalLayoutType:(WHC_LayoutTypeOptions)type; 905 | 906 | /** 907 | 对整个storyboard(使用4.7寸xib)上UI控件横向智能添加约束进行布局(从此告别xib上拖拽添加约束方式) 908 | */ 909 | 910 | - (void)whc_AutoSBHorizontalLayout; 911 | 912 | /** 913 | 对整个storyboard(使用4.7寸xib)上UI控件横向智能添加约束进行布局(从此告别xib上拖拽添加约束方式) 914 | */ 915 | 916 | - (void)whc_AutoSBHorizontalLayoutType:(WHC_LayoutTypeOptions)type; 917 | 918 | #pragma mark - 自动加边线模块 - 919 | 920 | /** 921 | 对视图底部加线 922 | 923 | @param value 线宽 924 | @param color 线的颜色 925 | @return 返回线视图 926 | */ 927 | 928 | - (WHC_VIEW *)whc_AddBottomLine:(CGFloat)value lineColor:(UIColor *)color; 929 | 930 | /** 931 | 对视图底部加线 932 | 933 | @param value 线宽 934 | @param color 线的颜色 935 | @param pading 内边距 936 | @return 返回线视图 937 | */ 938 | 939 | - (WHC_VIEW *)whc_AddBottomLine:(CGFloat)value lineColor:(UIColor *)color pading:(CGFloat)pading; 940 | 941 | /** 942 | 对视图顶部加线 943 | 944 | @param value 线宽 945 | @param color 线的颜色 946 | @return 返回线视图 947 | */ 948 | 949 | - (WHC_VIEW *)whc_AddTopLine:(CGFloat)value lineColor:(UIColor *)color; 950 | 951 | /** 952 | 对视图顶部加线 953 | 954 | @param value 线宽 955 | @param color 线的颜色 956 | @param pading 内边距 957 | @return 返回线视图 958 | */ 959 | 960 | - (WHC_VIEW *)whc_AddTopLine:(CGFloat)value lineColor:(UIColor *)color pading:(CGFloat)pading; 961 | 962 | /** 963 | 对视图左边加线 964 | 965 | @param value 线宽 966 | @param color 线的颜色 967 | @return 返回线视图 968 | */ 969 | 970 | 971 | - (WHC_VIEW *)whc_AddLeftLine:(CGFloat)value lineColor:(UIColor *)color; 972 | 973 | /** 974 | 对视图左边加线 975 | 976 | @param value 线宽 977 | @param color 线的颜色 978 | @param padding 边距 979 | @return 返回线视图 980 | */ 981 | - (WHC_VIEW *)whc_AddLeftLine:(CGFloat)value lineColor:(UIColor *)color padding:(CGFloat)padding; 982 | 983 | /** 984 | 对视图右边加线 985 | 986 | @param value 线宽 987 | @param color 线的颜色 988 | @return 返回线视图 989 | */ 990 | 991 | - (WHC_VIEW *)whc_AddRightLine:(CGFloat)value lineColor:(UIColor *)color; 992 | 993 | /** 994 | 对视图右边加线 995 | 996 | @param value 线宽 997 | @param color 线的颜色 998 | @param padding 边距 999 | @return 返回线视图 1000 | */ 1001 | 1002 | - (WHC_VIEW *)whc_AddRightLine:(CGFloat)value lineColor:(UIColor *)color padding:(CGFloat)padding; 1003 | #endif 1004 | @end 1005 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/WHC_AutoLayoutKit/WHC_StackView.m: -------------------------------------------------------------------------------- 1 | // 2 | // WHC_StackView.m 3 | // Github 4 | // 5 | // Created by 吴海超 on 16/2/17. 6 | // Copyright © 2016年 吴海超. All rights reserved. 7 | // 8 | 9 | // 10 | // Permission is hereby granted, free of charge, to any person obtaining a copy 11 | // of this software and associated documentation files (the "Software"), to deal 12 | // in the Software without restriction, including without limitation the rights 13 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | // copies of the Software, and to permit persons to whom the Software is 15 | // furnished to do so, subject to the following conditions: 16 | // 17 | // The above copyright notice and this permission notice shall be included in 18 | // all copies or substantial portions of the Software. 19 | // 20 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | // THE SOFTWARE. 27 | 28 | #import "WHC_StackView.h" 29 | #import 30 | #import "UIView+WHC_Frame.h" 31 | 32 | #if TARGET_OS_IPHONE || TARGET_OS_TV 33 | 34 | 35 | @implementation UIButton (WHC_StackView) 36 | 37 | - (CGSize)calcTextSize { 38 | if (self.titleLabel.text != nil) { 39 | return [self.titleLabel.text sizeWithAttributes:@{NSFontAttributeName: self.titleLabel.font}]; 40 | } 41 | return CGSizeZero; 42 | } 43 | 44 | - (void)whc_WidthAuto { 45 | if (self.titleEdgeInsets.left + self.titleEdgeInsets.right != 0) { 46 | [self whc_Width:[self calcTextSize].width + self.titleEdgeInsets.left + self.titleEdgeInsets.right]; 47 | }else { 48 | [super whc_AutoWidth]; 49 | } 50 | } 51 | 52 | - (void)whc_HeightAuto { 53 | if (self.titleEdgeInsets.top + self.titleEdgeInsets.bottom != 0) { 54 | [self whc_Height:[self calcTextSize].height + self.titleEdgeInsets.top + self.titleEdgeInsets.bottom]; 55 | }else { 56 | [super whc_AutoHeight]; 57 | } 58 | } 59 | 60 | @end 61 | 62 | @implementation UILabel (WHC_StackView) 63 | 64 | + (void)load { 65 | static dispatch_once_t onceToken; 66 | dispatch_once(&onceToken, ^{ 67 | Method drawTextInRect = class_getInstanceMethod(self, @selector(drawTextInRect:)); 68 | Method myDrawTextInRect = class_getInstanceMethod(self, @selector(myDrawTextInRect:)); 69 | Method textRectForBounds = class_getInstanceMethod(self, @selector(textRectForBounds:limitedToNumberOfLines:)); 70 | Method myTextRectForBounds = class_getInstanceMethod(self, @selector(myTextRectForBounds:limitedToNumberOfLines:)); 71 | method_exchangeImplementations(drawTextInRect, myDrawTextInRect); 72 | method_exchangeImplementations(textRectForBounds, myTextRectForBounds); 73 | }); 74 | } 75 | 76 | - (void)setWhc_LeftPadding:(CGFloat)whc_LeftPadding { 77 | objc_setAssociatedObject(self, @selector(whc_LeftPadding), @(whc_LeftPadding), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 78 | [self setNeedsDisplay]; 79 | } 80 | 81 | - (CGFloat)whc_LeftPadding { 82 | NSNumber * value = objc_getAssociatedObject(self, _cmd); 83 | return value == nil ? 0 : value.floatValue; 84 | } 85 | 86 | - (void)setWhc_TopPadding:(CGFloat)whc_TopPadding { 87 | objc_setAssociatedObject(self, @selector(whc_TopPadding), @(whc_TopPadding), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 88 | [self setNeedsDisplay]; 89 | } 90 | 91 | - (CGFloat)whc_TopPadding { 92 | NSNumber * value = objc_getAssociatedObject(self, _cmd); 93 | return value == nil ? 0 : value.floatValue; 94 | } 95 | 96 | - (void)setWhc_RightPadding:(CGFloat)whc_RightPadding { 97 | objc_setAssociatedObject(self, @selector(whc_RightPadding), @(whc_RightPadding), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 98 | [self setNeedsDisplay]; 99 | } 100 | 101 | - (CGFloat)whc_RightPadding { 102 | NSNumber * value = objc_getAssociatedObject(self, _cmd); 103 | return value == nil ? 0 : value.floatValue; 104 | } 105 | - (void)setWhc_BottomPadding:(CGFloat)whc_BottomPadding { 106 | objc_setAssociatedObject(self, @selector(whc_BottomPadding), @(whc_BottomPadding), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 107 | [self setNeedsDisplay]; 108 | } 109 | 110 | - (CGFloat)whc_BottomPadding { 111 | NSNumber * value = objc_getAssociatedObject(self, _cmd); 112 | return value == nil ? 0 : value.floatValue; 113 | } 114 | 115 | - (CGSize)calcTextSize { 116 | if (self.text != nil) { 117 | return [self.text sizeWithAttributes:@{NSFontAttributeName: self.font}]; 118 | } 119 | return CGSizeZero; 120 | } 121 | 122 | - (void)setWhc_VerticalAlignment:(WHC_UILabelVerticalAlignment)whc_VerticalAlignment { 123 | objc_setAssociatedObject(self, @selector(whc_VerticalAlignment), @(whc_VerticalAlignment), OBJC_ASSOCIATION_RETAIN_NONATOMIC); 124 | [self setNeedsDisplay]; 125 | } 126 | 127 | - (WHC_UILabelVerticalAlignment)whc_VerticalAlignment { 128 | NSNumber * value = objc_getAssociatedObject(self, _cmd); 129 | return value == nil ? Middle : value.integerValue; 130 | } 131 | 132 | 133 | - (HeightAuto)whc_HeightAuto { 134 | __weak typeof(self) weakSelf = self; 135 | return ^() { 136 | if (weakSelf.whc_TopPadding + weakSelf.whc_BottomPadding != 0) { 137 | [super whc_Height:[weakSelf calcTextSize].width + weakSelf.whc_TopPadding + weakSelf.whc_BottomPadding + 0.5]; 138 | }else { 139 | [super whc_AutoHeight]; 140 | } 141 | return weakSelf; 142 | }; 143 | } 144 | 145 | - (WidthAuto)whc_WidthAuto { 146 | __weak typeof(self) weakSelf = self; 147 | return ^() { 148 | if (weakSelf.whc_LeftPadding + weakSelf.whc_RightPadding != 0) { 149 | [super whc_Width:[weakSelf calcTextSize].width + weakSelf.whc_LeftPadding + weakSelf.whc_RightPadding + 0.5]; 150 | }else { 151 | [super whc_AutoWidth]; 152 | } 153 | return weakSelf; 154 | }; 155 | } 156 | 157 | - (void)myDrawTextInRect:(CGRect)rect { 158 | if (self.whc_VerticalAlignment != Middle) { 159 | CGRect textRect = [self textRectForBounds:rect limitedToNumberOfLines:self.numberOfLines]; 160 | textRect.size.width = CGRectGetWidth(rect); 161 | switch (self.whc_VerticalAlignment) { 162 | case Top: 163 | textRect.size.height += self.whc_TopPadding; 164 | break; 165 | case Bottom: 166 | textRect.origin.y -= self.whc_BottomPadding; 167 | textRect.size.height += self.whc_BottomPadding; 168 | break; 169 | default: 170 | break; 171 | } 172 | CGRect inRect = UIEdgeInsetsInsetRect(textRect, UIEdgeInsetsMake(self.whc_TopPadding, self.whc_LeftPadding, self.whc_BottomPadding, self.whc_RightPadding)); 173 | [self myDrawTextInRect:inRect]; 174 | }else { 175 | CGRect inRect = UIEdgeInsetsInsetRect(rect, UIEdgeInsetsMake(self.whc_TopPadding, self.whc_LeftPadding, self.whc_BottomPadding, self.whc_RightPadding)); 176 | [self myDrawTextInRect:inRect]; 177 | } 178 | } 179 | 180 | - (CGRect)myTextRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines { 181 | CGRect textRect = [self myTextRectForBounds:bounds limitedToNumberOfLines:numberOfLines]; 182 | switch (self.whc_VerticalAlignment) { 183 | case Top: 184 | break; 185 | case Middle: 186 | break; 187 | case Bottom: 188 | textRect.origin.y = bounds.origin.y + bounds.size.height - textRect.size.height; 189 | break; 190 | default: 191 | break; 192 | } 193 | return textRect; 194 | } 195 | 196 | 197 | @end 198 | 199 | #endif 200 | 201 | @implementation WHC_VIEW (WHC_StackViewCategory) 202 | 203 | - (void)setWhc_WidthWeight:(CGFloat)whc_WidthWeight { 204 | objc_setAssociatedObject(self, 205 | @selector(whc_WidthWeight), 206 | @(whc_WidthWeight), 207 | OBJC_ASSOCIATION_RETAIN_NONATOMIC); 208 | } 209 | 210 | - (CGFloat)whc_WidthWeight { 211 | CGFloat weight = [objc_getAssociatedObject(self, _cmd) floatValue]; 212 | if (weight == 0) { 213 | weight = 1; 214 | } 215 | return weight; 216 | } 217 | 218 | - (void)setWhc_HeightWeight:(CGFloat)whc_HeightWeight { 219 | objc_setAssociatedObject(self, 220 | @selector(whc_HeightWeight), 221 | @(whc_HeightWeight), 222 | OBJC_ASSOCIATION_RETAIN_NONATOMIC); 223 | } 224 | 225 | - (CGFloat)whc_HeightWeight { 226 | CGFloat weight = [objc_getAssociatedObject(self, _cmd) floatValue]; 227 | if (weight == 0) { 228 | weight = 1; 229 | } 230 | return weight; 231 | } 232 | 233 | @end 234 | 235 | /// 填充空白视图类 236 | @interface WHC_VacntView : WHC_VIEW 237 | 238 | @end 239 | 240 | @implementation WHC_VacntView 241 | 242 | @end 243 | 244 | /// 分割线视图 245 | @interface WHC_StackViewLineView : WHC_VIEW 246 | 247 | @end 248 | 249 | @implementation WHC_StackViewLineView 250 | 251 | @end 252 | 253 | @interface WHC_StackView () { 254 | BOOL _autoHeight; 255 | BOOL _autoWidth; 256 | NSInteger _lastRowVacantCount; 257 | } 258 | 259 | @end 260 | 261 | @implementation WHC_StackView 262 | 263 | - (instancetype)init { 264 | self = [super init]; 265 | if (self) { 266 | #if TARGET_OS_IPHONE || TARGET_OS_TV 267 | self.backgroundColor = [WHC_COLOR whiteColor]; 268 | #elif TARGET_OS_MAC 269 | self.makeBackingLayer.backgroundColor = [WHC_COLOR whiteColor].CGColor; 270 | #endif 271 | } 272 | return self; 273 | } 274 | 275 | - (instancetype)initWithFrame:(CGRect)frame { 276 | self = [super initWithFrame:frame]; 277 | if (self) { 278 | #if TARGET_OS_IPHONE || TARGET_OS_TV 279 | self.backgroundColor = [WHC_COLOR whiteColor]; 280 | #elif TARGET_OS_MAC 281 | self.makeBackingLayer.backgroundColor = [WHC_COLOR whiteColor].CGColor; 282 | #endif 283 | } 284 | return self; 285 | } 286 | 287 | - (void)setWhc_WidthWeight:(CGFloat)whc_WidthWeight { 288 | objc_setAssociatedObject(self, 289 | @selector(whc_WidthWeight), 290 | @(whc_WidthWeight), 291 | OBJC_ASSOCIATION_RETAIN_NONATOMIC); 292 | } 293 | 294 | - (void)setWhc_ElementHeightWidthRatio:(CGFloat)whc_ElementHeightWidthRatio { 295 | _whc_ElementHeightWidthRatio = whc_ElementHeightWidthRatio; 296 | _whc_ElementWidthHeightRatio = 0; 297 | } 298 | 299 | - (void)setWhc_ElementWidthHeightRatio:(CGFloat)whc_ElementWidthHeightRatio { 300 | _whc_ElementWidthHeightRatio = whc_ElementWidthHeightRatio; 301 | _whc_ElementHeightWidthRatio = 0; 302 | } 303 | 304 | - (NSInteger)whc_SubViewCount { 305 | if (self.whc_Orientation == All) { 306 | return MAX(0, self.subviews.count - _lastRowVacantCount); 307 | } 308 | return self.subviews.count; 309 | } 310 | 311 | - (NSInteger)whc_Column { 312 | return MAX(_whc_Column, 1); 313 | } 314 | 315 | - (void)whc_AutoHeight { 316 | [super whc_AutoHeight]; 317 | _autoHeight = YES; 318 | } 319 | 320 | - (HeightAuto)whc_HeightAuto { 321 | _autoHeight = YES; 322 | __weak typeof(self) weakSelf = self; 323 | return ^() { 324 | [super whc_AutoHeight]; 325 | return weakSelf; 326 | }; 327 | } 328 | 329 | - (void)whc_AutoWidth { 330 | [super whc_AutoWidth]; 331 | _autoWidth = YES; 332 | } 333 | 334 | - (WidthAuto)whc_WidthAuto { 335 | _autoWidth = YES; 336 | __weak typeof(self) weakSelf = self; 337 | return ^() { 338 | [super whc_AutoWidth]; 339 | return weakSelf; 340 | }; 341 | } 342 | 343 | - (void)whc_StartLayout { 344 | [self runStackLayoutEngine]; 345 | } 346 | 347 | - (WHC_StackViewLineView *)makeLine { 348 | WHC_StackViewLineView * lineView = [WHC_StackViewLineView new]; 349 | #if TARGET_OS_IPHONE || TARGET_OS_TV 350 | if (self.whc_SegmentLineColor) { 351 | lineView.backgroundColor = self.whc_SegmentLineColor; 352 | }else { 353 | lineView.backgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0]; 354 | } 355 | #elif TARGET_OS_MAC 356 | if (self.whc_SegmentLineColor) { 357 | lineView.makeBackingLayer.backgroundColor = self.whc_SegmentLineColor.CGColor; 358 | }else { 359 | lineView.makeBackingLayer.backgroundColor = [WHC_COLOR colorWithWhite:0.9 alpha:1.0].CGColor; 360 | } 361 | #endif 362 | return lineView; 363 | } 364 | 365 | - (void)whc_RemoveAllSubviews { 366 | [self.subviews enumerateObjectsUsingBlock:^(__kindof WHC_VIEW * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 367 | [obj removeFromSuperview]; 368 | }]; 369 | } 370 | 371 | - (void)whc_RemoveAllVacntView { 372 | _lastRowVacantCount = 0; 373 | [self.subviews enumerateObjectsUsingBlock:^(__kindof WHC_VIEW * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 374 | if ([obj isKindOfClass:[WHC_VacntView class]]) { 375 | [obj removeFromSuperview]; 376 | } 377 | }]; 378 | } 379 | 380 | - (void)removeAllSegmentLine { 381 | [self.subviews enumerateObjectsUsingBlock:^(__kindof WHC_VIEW * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { 382 | if ([obj isKindOfClass:[WHC_StackViewLineView class]]) { 383 | [obj removeFromSuperview]; 384 | } 385 | }]; 386 | } 387 | 388 | - (void)runStackLayoutEngine { 389 | [self removeAllSegmentLine]; 390 | NSArray * subViews = self.subviews; 391 | NSInteger count = subViews.count; 392 | if (count == 0) { 393 | return; 394 | } 395 | WHC_VIEW * toView = nil; 396 | WHC_LayoutOrientationOptions orientation = self.whc_Orientation; 397 | WHC_GOTO: 398 | switch (orientation) { 399 | case Horizontal: { 400 | for (int i = 0; i < count; i++) { 401 | WHC_VIEW * view = subViews[i]; 402 | WHC_VIEW * nextView = i < count - 1 ? subViews[i + 1] : nil; 403 | if (i == 0) { 404 | [view whc_LeftSpace:self.whc_Edge.left]; 405 | }else { 406 | if (self.whc_SegmentLineSize > 0.0) { 407 | WHC_StackViewLineView * lineView = [self makeLine]; 408 | [self addSubview:lineView]; 409 | [lineView whc_TopSpace:self.whc_SegmentLinePadding]; 410 | [lineView whc_BottomSpace:self.whc_SegmentLinePadding]; 411 | [lineView whc_LeftSpace:self.whc_HSpace / 2.0 toView:toView]; 412 | [lineView whc_Width:self.whc_SegmentLineSize]; 413 | [view whc_LeftSpace:self.whc_HSpace / 2.0 toView:lineView]; 414 | }else { 415 | [view whc_LeftSpace:self.whc_HSpace toView:toView]; 416 | } 417 | } 418 | [view whc_TopSpace:self.whc_Edge.top]; 419 | if (nextView) { 420 | if (self.whc_SubViewWidth > 0) { 421 | [view whc_Width:self.whc_SubViewWidth]; 422 | }else { 423 | if (_whc_ElementWidthHeightRatio > 0) { 424 | [view whc_WidthHeightRatio:_whc_ElementWidthHeightRatio]; 425 | }else { 426 | if (_autoWidth) { 427 | [view whc_WidthAuto]; 428 | }else { 429 | [view whc_WidthEqualView:nextView 430 | ratio:view.whc_WidthWeight / nextView.whc_WidthWeight]; 431 | } 432 | } 433 | } 434 | if (self.whc_SubViewHeight > 0) { 435 | [view whc_Height:self.whc_SubViewHeight]; 436 | }else { 437 | if (_whc_ElementHeightWidthRatio > 0) { 438 | [view whc_HeightWidthRatio:_whc_ElementHeightWidthRatio]; 439 | }else { 440 | if (_autoHeight) { 441 | [view whc_HeightAuto]; 442 | }else { 443 | [view whc_BottomSpace:self.whc_Edge.bottom]; 444 | } 445 | } 446 | } 447 | }else { 448 | if (self.whc_SubViewWidth > 0) { 449 | [view whc_Width:self.whc_SubViewWidth]; 450 | if (_autoWidth) { 451 | [view whc_RightSpace:self.whc_Edge.right]; 452 | } 453 | }else { 454 | if (_whc_ElementWidthHeightRatio > 0) { 455 | [view whc_WidthHeightRatio:_whc_ElementWidthHeightRatio]; 456 | if (_autoWidth) { 457 | [view whc_RightSpace:self.whc_Edge.right]; 458 | } 459 | }else { 460 | if (_autoWidth) { 461 | [view whc_WidthAuto]; 462 | } 463 | [view whc_RightSpace:self.whc_Edge.right]; 464 | } 465 | } 466 | if (self.whc_SubViewHeight > 0) { 467 | [view whc_Height:self.whc_SubViewHeight]; 468 | if (_autoHeight) { 469 | [view whc_BottomSpace:self.whc_Edge.bottom]; 470 | } 471 | }else { 472 | if (_whc_ElementHeightWidthRatio > 0) { 473 | [view whc_HeightWidthRatio:_whc_ElementHeightWidthRatio]; 474 | if (_autoHeight) { 475 | [view whc_BottomSpace:self.whc_Edge.bottom]; 476 | } 477 | }else { 478 | if (_autoHeight) { 479 | [view whc_HeightAuto]; 480 | } 481 | [view whc_BottomSpace:self.whc_Edge.bottom]; 482 | } 483 | } 484 | } 485 | toView = view; 486 | if ([toView isKindOfClass:[WHC_StackView class]]) { 487 | [((WHC_StackView *)toView) whc_StartLayout]; 488 | } 489 | } 490 | break; 491 | } 492 | case Vertical: { 493 | for (int i = 0; i < count; i++) { 494 | WHC_VIEW * view = subViews[i]; 495 | WHC_VIEW * nextView = i < count - 1 ? subViews[i + 1] : nil; 496 | if (i == 0) { 497 | [view whc_TopSpace:self.whc_Edge.top]; 498 | }else { 499 | if (self.whc_SegmentLineSize > 0.0) { 500 | WHC_StackViewLineView * lineView = [self makeLine]; 501 | [self addSubview:lineView]; 502 | [lineView whc_LeftSpace:self.whc_SegmentLinePadding]; 503 | [lineView whc_RightSpace:self.whc_SegmentLinePadding]; 504 | [lineView whc_Height:self.whc_SegmentLineSize]; 505 | [lineView whc_TopSpace:self.whc_VSpace / 2.0 toView:toView]; 506 | [view whc_TopSpace:self.whc_VSpace / 2.0 toView:lineView]; 507 | }else { 508 | [view whc_TopSpace:self.whc_VSpace toView:toView]; 509 | } 510 | } 511 | [view whc_LeftSpace:self.whc_Edge.left]; 512 | if (nextView) { 513 | if (self.whc_SubViewWidth > 0) { 514 | [view whc_Width:self.whc_SubViewWidth]; 515 | }else { 516 | if (_whc_ElementWidthHeightRatio > 0) { 517 | [view whc_WidthHeightRatio:_whc_ElementWidthHeightRatio]; 518 | }else { 519 | if (_autoWidth) { 520 | [view whc_WidthAuto]; 521 | }else { 522 | [view whc_RightSpace:self.whc_Edge.right]; 523 | } 524 | } 525 | } 526 | if (self.whc_SubViewHeight > 0) { 527 | [view whc_Height:self.whc_SubViewHeight]; 528 | }else { 529 | if (_whc_ElementHeightWidthRatio > 0) { 530 | [view whc_HeightWidthRatio:_whc_ElementHeightWidthRatio]; 531 | }else { 532 | if (_autoHeight) { 533 | [view whc_HeightAuto]; 534 | }else { 535 | [view whc_HeightEqualView:nextView 536 | ratio:view.whc_HeightWeight / nextView.whc_HeightWeight]; 537 | } 538 | } 539 | } 540 | }else { 541 | if (self.whc_SubViewWidth > 0) { 542 | [view whc_Width:self.whc_SubViewWidth]; 543 | if (_autoWidth) { 544 | [view whc_RightSpace:self.whc_Edge.right]; 545 | } 546 | }else { 547 | if (_whc_ElementWidthHeightRatio > 0) { 548 | [view whc_WidthHeightRatio:_whc_ElementWidthHeightRatio]; 549 | if (_autoWidth) { 550 | [view whc_RightSpace:self.whc_Edge.right]; 551 | } 552 | }else { 553 | if (_autoWidth) { 554 | [view whc_WidthAuto]; 555 | } 556 | [view whc_RightSpace:self.whc_Edge.right]; 557 | } 558 | } 559 | if (self.whc_SubViewHeight > 0) { 560 | [view whc_Height:self.whc_SubViewHeight]; 561 | if (_autoHeight) { 562 | [view whc_BottomSpace:self.whc_Edge.bottom]; 563 | } 564 | }else { 565 | if (_whc_ElementHeightWidthRatio > 0) { 566 | [view whc_HeightWidthRatio:_whc_ElementHeightWidthRatio]; 567 | if (_autoHeight) { 568 | [view whc_BottomSpace:self.whc_Edge.bottom]; 569 | } 570 | }else { 571 | if (_autoHeight) { 572 | [view whc_HeightAuto]; 573 | } 574 | [view whc_BottomSpace:self.whc_Edge.bottom]; 575 | } 576 | } 577 | } 578 | toView = view; 579 | if ([toView isKindOfClass:[WHC_StackView class]]) { 580 | [((WHC_StackView *)toView) whc_StartLayout]; 581 | } 582 | } 583 | break; 584 | } 585 | case All: { 586 | for (WHC_VIEW * view in self.subviews) { 587 | if ([view isKindOfClass:[WHC_VacntView class]]) { 588 | [view removeFromSuperview]; 589 | } 590 | } 591 | subViews = self.subviews; 592 | count = subViews.count; 593 | if (self.whc_Column < 2) { 594 | orientation = Vertical; 595 | goto WHC_GOTO; 596 | }else { 597 | NSInteger rowCount = count / self.whc_Column + (count % self.whc_Column == 0 ? 0 : 1); 598 | NSInteger index = 0; 599 | _lastRowVacantCount = rowCount * self.whc_Column - count; 600 | for (NSInteger i = 0; i < _lastRowVacantCount; i++) { 601 | WHC_VacntView * view = [WHC_VacntView new]; 602 | #if TARGET_OS_IPHONE || TARGET_OS_TV 603 | view.backgroundColor = [WHC_COLOR clearColor]; 604 | #elif TARGET_OS_MAC 605 | view.makeBackingLayer.backgroundColor = [WHC_COLOR clearColor].CGColor; 606 | #endif 607 | [self addSubview:view]; 608 | } 609 | if (_lastRowVacantCount > 0) { 610 | subViews = nil; 611 | subViews = self.subviews; 612 | count = subViews.count; 613 | } 614 | WHC_VIEW * frontRowView = nil; 615 | WHC_VIEW * frontColumnView = nil; 616 | 617 | WHC_StackViewLineView * columnLineView = nil; 618 | for (NSInteger row = 0; row < rowCount; row++) { 619 | WHC_VIEW * nextRowView = nil; 620 | WHC_VIEW * rowView = subViews[row * self.whc_Column]; 621 | NSInteger nextRow = (row + 1) * self.whc_Column; 622 | if (nextRow < count) { 623 | nextRowView = subViews[nextRow]; 624 | } 625 | WHC_StackViewLineView * rowLineView = nil; 626 | if (self.whc_SegmentLineSize > 0.0 && row > 0) { 627 | rowLineView = [self makeLine]; 628 | [self addSubview:rowLineView]; 629 | [rowLineView whc_LeftSpace:self.whc_SegmentLinePadding]; 630 | [rowLineView whc_RightSpace:self.whc_SegmentLinePadding]; 631 | [rowLineView whc_Height:self.whc_SegmentLineSize]; 632 | [rowLineView whc_TopSpace:self.whc_VSpace / 2.0 toView:frontRowView]; 633 | } 634 | for (NSInteger column = 0; column < self.whc_Column; column++) { 635 | index = row * self.whc_Column + column; 636 | WHC_VIEW * view = subViews[index]; 637 | WHC_VIEW * nextColumnView = nil; 638 | if (column > 0 && self.whc_SegmentLineSize > 0.0) { 639 | columnLineView = [self makeLine]; 640 | [self addSubview:columnLineView]; 641 | [columnLineView whc_LeftSpace:self.whc_HSpace / 2.0 toView:frontColumnView]; 642 | [columnLineView whc_TopSpace:self.whc_SegmentLinePadding]; 643 | [columnLineView whc_BottomSpace:self.whc_SegmentLinePadding]; 644 | [columnLineView whc_Width:self.whc_SegmentLineSize]; 645 | } 646 | if (column < self.whc_Column - 1 && index < count) { 647 | nextColumnView = subViews[index + 1]; 648 | } 649 | if (row == 0) { 650 | [view whc_TopSpace:self.whc_Edge.top]; 651 | }else { 652 | if (rowLineView) { 653 | [view whc_TopSpace:self.whc_VSpace / 2.0 toView:rowLineView]; 654 | }else { 655 | [view whc_TopSpace:self.whc_VSpace toView:frontRowView]; 656 | } 657 | } 658 | if (column == 0) { 659 | [view whc_LeftSpace:self.whc_Edge.left]; 660 | }else { 661 | if (columnLineView) { 662 | [view whc_LeftSpace:self.whc_HSpace / 2.0 toView:columnLineView]; 663 | }else { 664 | [view whc_LeftSpace:self.whc_HSpace toView:frontColumnView]; 665 | } 666 | 667 | } 668 | if (nextRowView) { 669 | if (self.whc_SubViewHeight > 0) { 670 | [view whc_Height:self.whc_SubViewHeight]; 671 | }else { 672 | if (_whc_ElementHeightWidthRatio > 0) { 673 | [view whc_HeightWidthRatio:_whc_ElementHeightWidthRatio]; 674 | }else { 675 | if (_autoHeight) { 676 | [view whc_HeightAuto]; 677 | }else { 678 | [view whc_HeightEqualView:nextRowView 679 | ratio:view.whc_HeightWeight / nextRowView.whc_HeightWeight]; 680 | } 681 | } 682 | } 683 | }else { 684 | if (self.whc_SubViewHeight > 0) { 685 | [view whc_Height:self.whc_SubViewHeight]; 686 | }else { 687 | if (_whc_ElementHeightWidthRatio > 0) { 688 | [view whc_HeightWidthRatio:_whc_ElementHeightWidthRatio]; 689 | }else { 690 | if (_autoHeight) { 691 | [view whc_HeightAuto]; 692 | }else { 693 | [view whc_BottomSpace:self.whc_Edge.bottom]; 694 | } 695 | } 696 | } 697 | } 698 | if (nextColumnView) { 699 | if (self.whc_SubViewWidth > 0) { 700 | [view whc_Width:self.whc_SubViewWidth]; 701 | }else { 702 | if (_whc_ElementWidthHeightRatio > 0) { 703 | [view whc_WidthHeightRatio:_whc_ElementWidthHeightRatio]; 704 | }else { 705 | if (_autoWidth) { 706 | [view whc_WidthAuto]; 707 | }else { 708 | [view whc_WidthEqualView:nextColumnView 709 | ratio:view.whc_WidthWeight / nextColumnView.whc_WidthWeight]; 710 | } 711 | } 712 | } 713 | }else { 714 | if (self.whc_SubViewWidth > 0) { 715 | [view whc_Width:self.whc_SubViewWidth]; 716 | }else { 717 | if (_whc_ElementWidthHeightRatio > 0) { 718 | [view whc_WidthHeightRatio:_whc_ElementWidthHeightRatio]; 719 | }else { 720 | if (_autoWidth) { 721 | [view whc_WidthAuto]; 722 | }else { 723 | [view whc_RightSpace:self.whc_Edge.right]; 724 | } 725 | } 726 | } 727 | } 728 | frontColumnView = view; 729 | if ([frontColumnView isKindOfClass:[WHC_StackView class]]) { 730 | [((WHC_StackView *)frontColumnView) whc_StartLayout]; 731 | } 732 | } 733 | frontRowView = rowView; 734 | } 735 | 736 | if (_autoWidth) { 737 | #if TARGET_OS_IPHONE || TARGET_OS_TV 738 | [self layoutIfNeeded]; 739 | #elif TARGET_OS_MAC 740 | [self.makeBackingLayer layoutIfNeeded]; 741 | #endif 742 | CGFloat rowLastColumnViewMaxX = 0; 743 | WHC_VIEW * rowLastColumnViewMaxXView; 744 | for (NSInteger r = 1; r <= rowCount; r++) { 745 | NSInteger index = r * _whc_Column - 1; 746 | WHC_VIEW * maxWidthView = self.subviews[index]; 747 | #if TARGET_OS_IPHONE || TARGET_OS_TV 748 | [maxWidthView layoutIfNeeded]; 749 | #elif TARGET_OS_MAC 750 | [maxWidthView.makeBackingLayer layoutIfNeeded]; 751 | #endif 752 | if (maxWidthView.whc_maxX > rowLastColumnViewMaxX) { 753 | rowLastColumnViewMaxX = maxWidthView.whc_maxX; 754 | rowLastColumnViewMaxXView = maxWidthView; 755 | } 756 | } 757 | [rowLastColumnViewMaxXView whc_RightSpace:_whc_Edge.right]; 758 | } 759 | 760 | if (_autoHeight) { 761 | #if TARGET_OS_IPHONE || TARGET_OS_TV 762 | [self layoutIfNeeded]; 763 | #elif TARGET_OS_MAC 764 | [self.makeBackingLayer layoutIfNeeded]; 765 | #endif 766 | CGFloat columnLastRowViewMaxY = 0; 767 | WHC_VIEW * columnLastRowViewMaxYView; 768 | for (NSInteger r = 1; r <= rowCount; r++) { 769 | NSInteger index = r * _whc_Column - 1; 770 | WHC_VIEW * maxHeightView = self.subviews[index]; 771 | #if TARGET_OS_IPHONE || TARGET_OS_TV 772 | [maxHeightView layoutIfNeeded]; 773 | #elif TARGET_OS_MAC 774 | [maxHeightView.makeBackingLayer layoutIfNeeded]; 775 | #endif 776 | if (maxHeightView.whc_maxY > columnLastRowViewMaxY) { 777 | columnLastRowViewMaxY = maxHeightView.whc_maxY; 778 | columnLastRowViewMaxYView = maxHeightView; 779 | } 780 | } 781 | [columnLastRowViewMaxYView whc_BottomSpace:_whc_Edge.bottom]; 782 | } 783 | } 784 | break; 785 | } 786 | default: 787 | break; 788 | } 789 | } 790 | 791 | 792 | @end 793 | -------------------------------------------------------------------------------- /WHC_DataModelFactory/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // WHC_DataModelFactory 4 | // 5 | // Created by 吴海超 on 15/4/30. 6 | // Copyright (c) 2015年 吴海超. All rights reserved. 7 | // 8 | 9 | 10 | // Github 11 | 12 | // 13 | // Permission is hereby granted, free of charge, to any person obtaining a copy 14 | // of this software and associated documentation files (the "Software"), to deal 15 | // in the Software without restriction, including without limitation the rights 16 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | // copies of the Software, and to permit persons to whom the Software is 18 | // furnished to do so, subject to the following conditions: 19 | // 20 | // The above copyright notice and this permission notice shall be included in 21 | // all copies or substantial portions of the Software. 22 | // 23 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | // THE SOFTWARE. 30 | // VERSON (1.8.4) 31 | 32 | #import "ViewController.h" 33 | #import "WHC_XMLParser.h" 34 | #import 35 | #import "WHC_AutoLayout.h" 36 | 37 | 38 | #define kWHC_DEFAULT_CLASS_NAME @("WHC") 39 | #define kWHC_CLASS @("\n@interface %@ :NSObject\n%@\n@end\n") 40 | #define kWHC_CodingCLASS @("\n@interface %@ :NSObject \n%@\n@end\n") 41 | #define kWHC_CopyingCLASS @("\n@interface %@ :NSObject \n%@\n@end\n") 42 | #define kWHC_CodingAndCopyingCLASS @("\n@interface %@ :NSObject \n%@\n@end\n") 43 | 44 | #define kWHC_PROPERTY(s) ((s) == 'c' ? @("@property (nonatomic , copy) %@ * %@;\n") : @("@property (nonatomic , strong) %@ * %@;\n")) 45 | #define kWHC_ASSIGN_PROPERTY @("@property (nonatomic , assign) %@ %@;\n") 46 | #define kWHC_CLASS_M @("@implementation %@\n\n@end\n") 47 | #define kWHC_CodingCLASS_M @("@implementation %@\n- (id)initWithCoder:(NSCoder *)decoder {\n if (self = [super init]) { \n [self whc_Decode:decoder]; \n }\n return self;\n \n} \n- (void)encodeWithCoder:(NSCoder *)encoder {\n [self whc_Encode:encoder]; \n} \n\n\n@end\n\n") 48 | 49 | #define kWHC_CopyingCLASS_M @("@implementation %@ \n- (id)copyWithZone:(NSZone *)zone { \n return [self whc_Copy]; \n} \n\n\n@end\n\n") 50 | #define kWHC_CodingAndCopyingCLASS_M @("@implementation %@ \n- (id)initWithCoder:(NSCoder *)decoder {\n if (self = [super init]) { \n [self whc_Decode:decoder]; \n }\n return self;\n } \n\n- (void)encodeWithCoder:(NSCoder *)encoder {\n [self whc_Encode:encoder]; \n} \n\n - (id)copyWithZone:(NSZone *)zone { \n return [self whc_Copy]; \n} \n \n@end\n\n") 51 | 52 | #define kWHC_CLASS_Prefix_M @("@implementation %@\n+ (NSString *)prefix {\n return @\"%@\";\n}\n\n@end\n\n") 53 | 54 | #define kWHC_Prefix_H_Func @("\n+ (NSString *)prefix;\n") 55 | 56 | #define kSWHC_Prefix_Func @("class func prefix() -> String {\n return \"%@\"\n}\n") 57 | 58 | #define kSWHC_CLASS @("\nclass %@ :NSObject {\n%@\n}\n") 59 | #define kSexyJson_Class @("\nclass %@: SexyJson {\n%@\n}\n") 60 | #define kSexyJson_Struct @("\nstruct %@: SexyJson {\n%@\n}\n") 61 | 62 | #define kSexyJson_FuncMap (@"\n public func sexyMap(_ map: [String : Any]) {\n %@ \n }\n") 63 | #define kSexyJson_Struct_FuncMap (@"\n public mutating func sexyMap(_ map: [String : Any]) {\n %@ \n }\n") 64 | #define kSexyJson_Map (@"\n %@ <<< map[\"%@\"]") 65 | 66 | #define kSexyJson_CodingCLASS @("\nclass %@ :NSObject, SexyJson, NSCoding {\n \n required init(coder decoder: NSCoder) {\n super.init()\n self.sexy_decode(decoder)\n }\n\n func encode(with aCoder: NSCoder) {\n self.sexy_encode(aCoder)\n }\n\n required override init() {} \n\n%@\n}\n") 67 | 68 | #define kSexyJson_CopyingCLASS @("\nclass %@ :NSObject, SexyJson, NSCopying {\n \n func copy(with zone: NSZone? = nil) -> Any {\n return self.sexy_copy()\n }\n\n required override init() {} \n\n %@\n}\n") 69 | 70 | #define kSexyJson_CodingAndCopyingCLASS @("\nclass %@ :NSObject, SexyJson, NSCoding, NSCopying {\n\n required init(coder decoder: NSCoder) {\n super.init()\n self.sexy_decode(decoder)\n }\n\n func encode(with aCoder: NSCoder) {\n self.sexy_encode(aCoder)\n } \n\n func copy(with zone: NSZone? = nil) -> Any {\n return self.sexy_copy()\n }\n\n required override init() {} \n\n%@\n}\n") 71 | 72 | #define kSWHC_CodingCLASS @("\nclass %@ :NSObject, NSCoding {\n \n required init(coder aDecoder: NSCoder) {\n super.init()\n self.whc_Decode(aDecoder)\n }\n\n func encode(with aCoder: NSCoder) {\n self.whc_Encode(aCoder)\n } \n\n%@\n}\n") 73 | 74 | #define kSWHC_CopyingCLASS @("\nclass %@ :NSObject, NSCopying {\n \n func copy(with zone: NSZone? = nil) -> Any {\n return self.whc_Copy()\n } \n\n %@\n}\n") 75 | 76 | #define kSWHC_CodingAndCopyingCLASS @("\nclass %@ :NSObject, NSCoding, NSCopying {\n\n required init(coder aDecoder: NSCoder) {\n super.init()\n self.whc_Decode(aDecoder)\n }\n\n func encode(with aCoder: NSCoder) {\n self.whc_Encode(aCoder)\n } \n\n func copy(zone: NSZone? = nil) -> Any {\n return self.whc_Copy()\n } \n\n%@\n}\n") 77 | 78 | #define kSWHC_PROPERTY @(" var %@: %@?\n") 79 | #define kSWHC_ASSGIN_PROPERTY @(" var %@: %@\n") 80 | 81 | #define kInputJsonPlaceholdText @("请输入json或者xml字符串") 82 | #define kSourcePlaceholdText @("自动生成对象模型类源文件") 83 | #define kHeaderPlaceholdText @("自动生成对象模型类头文件") 84 | 85 | 86 | typedef enum : NSUInteger { 87 | Objc = 0, 88 | Swift, 89 | SexyJson_struct, 90 | SexyJson_class 91 | } WHCModelType; 92 | 93 | @interface ViewController (){ 94 | NSMutableString * _classString; //存类头文件内容 95 | NSMutableString * _classMString; //存类源文件内容 96 | NSString * _classPrefixName; //类前缀 97 | BOOL _didMake; 98 | BOOL _firstLower; //首字母小写 99 | } 100 | @property (weak) IBOutlet NSLayoutConstraint *classMHeightConstraint; 101 | 102 | @property (nonatomic , strong)IBOutlet NSTextField * classNameField; 103 | @property (nonatomic , strong)IBOutlet NSTextView * jsonField; 104 | @property (nonatomic , strong)IBOutlet NSTextView * classField; 105 | @property (nonatomic , strong)IBOutlet NSTextView * classMField; 106 | @property (nonatomic , strong)IBOutlet NSComboBox * comboBox; 107 | @property (nonatomic , strong)IBOutlet NSButton * codingCheckBox; 108 | @property (nonatomic , strong)IBOutlet NSButton * copyingCheckBox; 109 | @property (nonatomic , strong)IBOutlet NSButton * checkUpdateButton; 110 | 111 | @property (nonatomic , strong) NSArray * comboxTitles; 112 | @property (nonatomic , assign) BOOL isSwift; 113 | @property (nonatomic , assign) WHCModelType index; 114 | @end 115 | 116 | @implementation ViewController 117 | 118 | - (void)viewDidLoad { 119 | [super viewDidLoad]; 120 | 121 | _classString = [NSMutableString new]; 122 | _classMString = [NSMutableString new]; 123 | _classField.editable = NO; 124 | _classMField.editable = NO; 125 | _firstLower = YES; 126 | // Do any additional setup after loading the view. 127 | [self setTextViewStyle]; 128 | [self setClassSourceContent:kSourcePlaceholdText]; 129 | [self setClassHeaderContent:kHeaderPlaceholdText]; 130 | NSRect frmae = self.view.frame; 131 | frmae.size.height = 800; 132 | self.view.frame = frmae; 133 | 134 | _comboxTitles = @[@"Objective-c",@"Swift",@"SexyJson(struct)",@"SexyJson(class)"]; 135 | [_comboBox addItemsWithObjectValues:_comboxTitles]; 136 | [_comboBox selectItemWithObjectValue:@"Objective-c"]; 137 | 138 | 139 | } 140 | 141 | - (void)setJsonContent:(NSString *)content { 142 | if (content != nil) { 143 | NSMutableAttributedString * attrContent = [[NSMutableAttributedString alloc] initWithString:content]; 144 | [_jsonField.textStorage setAttributedString:attrContent]; 145 | [_jsonField.textStorage setFont:[NSFont systemFontOfSize:14]]; 146 | [_jsonField.textStorage setForegroundColor:[NSColor orangeColor]]; 147 | } 148 | } 149 | 150 | - (NSString *)copyingRight { 151 | NSMutableString * value = [NSMutableString string]; 152 | NSDate * date = [NSDate date]; 153 | NSDateFormatter * dateFormatter = [NSDateFormatter new]; 154 | dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss"; 155 | NSString * dateStr = [dateFormatter stringFromDate:date]; 156 | [value appendString:@"\n\n/**\n * Copyright "]; 157 | [value appendString:[dateStr componentsSeparatedByString:@"-"].firstObject]; 158 | [value appendString:@" WHC_DataModelFactory\n * Auto-generated: "]; 159 | [value appendString:dateStr]; 160 | [value appendString:@"\n *\n"]; 161 | [value appendString:@" * @author netyouli (whc)\n"]; 162 | [value appendString:@" * @website http://wuhaichao.com\n"]; 163 | [value appendString:@" * @github https://github.com/netyouli\n */\n\n\n"]; 164 | return value; 165 | } 166 | 167 | - (void)setClassHeaderContent:(NSString *)content { 168 | if (content != nil) { 169 | NSMutableAttributedString * attrContent = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@%@",[content isEqualToString:kHeaderPlaceholdText] ? @"" : [self copyingRight],content]]; 170 | [_classField.textStorage setAttributedString:attrContent]; 171 | [_classField.textStorage setFont:[NSFont systemFontOfSize:14]]; 172 | [_classField.textStorage setForegroundColor:[NSColor colorWithRed:61.0 / 255.0 green:160.0 / 255.0 blue:151.0 / 255.0 alpha:1.0]]; 173 | } 174 | } 175 | 176 | - (void)setClassSourceContent:(NSString *)content { 177 | if (content != nil) { 178 | NSMutableAttributedString * attrContent = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@%@",[content isEqualToString:kSourcePlaceholdText] ? @"" : [self copyingRight],content]]; 179 | [_classMField.textStorage setAttributedString:attrContent]; 180 | [_classMField.textStorage setFont:[NSFont systemFontOfSize:14]]; 181 | [_classMField.textStorage setForegroundColor:[NSColor colorWithRed:61.0 / 255.0 green:160.0 / 255.0 blue:151.0 / 255.0 alpha:1.0]]; 182 | } 183 | } 184 | 185 | - (void)setTextViewStyle { 186 | _jsonField.font = [NSFont systemFontOfSize:14]; 187 | _jsonField.textColor = [NSColor colorWithRed:198.0 / 255.0 green:77.0 / 255.0 blue:21.0 / 255.0 alpha:1.0]; 188 | _jsonField.backgroundColor = [NSColor colorWithRed:40.0 / 255.0 green:40.0 / 255.0 blue:40.0 / 255.0 alpha:1.0]; 189 | _classMField.backgroundColor = _jsonField.backgroundColor; 190 | _classField.backgroundColor = _jsonField.backgroundColor; 191 | } 192 | 193 | - (IBAction)clickCheckUpdate:(NSButton *)sender { 194 | if (sender.tag == 1) { 195 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.wuhaichao.com"]]; 196 | }else if (sender.tag == 2) { 197 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://www.wuhaichao.com/pay/"]]; 198 | } 199 | } 200 | 201 | - (IBAction)clickFirstLower:(NSButton *)sender { 202 | _firstLower = sender.state == 1; 203 | NSString * json = _jsonField.textStorage.string; 204 | if (json && json.length > 0) { 205 | [self clickMakeButton:nil]; 206 | } 207 | 208 | } 209 | 210 | - (IBAction)clickRadioButtone:(NSButton *)sender{ 211 | NSString * json = _jsonField.textStorage.string; 212 | if (json && json.length > 0) { 213 | [self clickMakeButton:nil]; 214 | } 215 | 216 | } 217 | - (IBAction)clickChangeComboBox:(NSComboBox *)sender { 218 | _index = sender.indexOfSelectedItem; 219 | _isSwift = _index != 0; 220 | _classMHeightConstraint.constant = (self.isSwift ? 0 : 180); 221 | NSString * json = _jsonField.textStorage.string; 222 | if (json && json.length > 0) { 223 | [self clickMakeButton:nil]; 224 | } 225 | } 226 | 227 | - (IBAction)clickMakeButton:(NSButton*)sender{ 228 | _didMake = YES; 229 | [_classString deleteCharactersInRange:NSMakeRange(0, _classString.length)]; 230 | [_classMString deleteCharactersInRange:NSMakeRange(0, _classMString.length)]; 231 | NSString * className = _classNameField.stringValue; 232 | NSString * json = _jsonField.textStorage.string; 233 | _classPrefixName = @""; 234 | if(className == nil){ 235 | className = kWHC_DEFAULT_CLASS_NAME; 236 | } 237 | if(className.length == 0){ 238 | className = kWHC_DEFAULT_CLASS_NAME; 239 | } 240 | if(json && json.length){ 241 | NSDictionary * dict = nil; 242 | if([json hasPrefix:@"<"]){ 243 | //xml 244 | dict = [WHC_XMLParser dictionaryForXMLString:json]; 245 | }else{ 246 | //json 247 | NSData * jsonData = [json dataUsingEncoding:NSUTF8StringEncoding]; 248 | id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil]; 249 | if (jsonObject) { 250 | NSData * formatJsonData = [NSJSONSerialization dataWithJSONObject:jsonObject options:NSJSONWritingPrettyPrinted error:nil]; 251 | [self setJsonContent:[[NSString alloc] initWithData:formatJsonData encoding:NSUTF8StringEncoding]]; 252 | } 253 | dict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:NULL]; 254 | if (dict == nil) { 255 | NSError *error; 256 | NSPropertyListFormat plistFormat; 257 | dict = [NSPropertyListSerialization propertyListWithData:jsonData options:NSPropertyListMutableContainers format:&plistFormat error:&error]; 258 | } 259 | } 260 | if (dict == nil || ![NSJSONSerialization isValidJSONObject:dict]) { 261 | #pragma clang diagnostic push 262 | #pragma clang diagnostic ignored"-Wdeprecated-declarations" 263 | NSAlert * alert = [NSAlert alertWithMessageText:@"WHC" defaultButton:@"确定" alternateButton:nil otherButton:nil informativeTextWithFormat:@"未知数据格式无法解析(请提供json字符串或者dictionary字符串)"]; 264 | [alert runModal]; 265 | #pragma clang diagnostic pop 266 | return; 267 | } 268 | NSString * classContent = [self handleDataEngine:dict key:@""]; 269 | if(!self.isSwift){ 270 | if (_classPrefixName.length > 0) { 271 | [_classMString appendFormat:kWHC_CLASS_Prefix_M,className,_classPrefixName]; 272 | }else { 273 | if (_codingCheckBox.state != 0 && _copyingCheckBox.state != 0) { 274 | [_classMString appendFormat:kWHC_CodingAndCopyingCLASS_M,className]; 275 | }else if (_codingCheckBox.state != 0) { 276 | [_classMString appendFormat:kWHC_CodingCLASS_M,className]; 277 | }else if (_copyingCheckBox.state != 0) { 278 | [_classMString appendFormat:kWHC_CopyingCLASS_M,className]; 279 | }else { 280 | [_classMString appendFormat:kWHC_CLASS_M,className]; 281 | } 282 | } 283 | if (_codingCheckBox.state != 0 && _copyingCheckBox.state != 0) { 284 | [_classString appendFormat:kWHC_CodingAndCopyingCLASS,className,classContent]; 285 | }else if (_codingCheckBox.state != 0) { 286 | [_classString appendFormat:kWHC_CodingCLASS,className,classContent]; 287 | }else if (_copyingCheckBox.state != 0) { 288 | [_classString appendFormat:kWHC_CopyingCLASS,className,classContent]; 289 | }else { 290 | [_classString appendFormat:kWHC_CLASS,className,classContent]; 291 | } 292 | }else{ 293 | switch (_index) { 294 | case SexyJson_class: { 295 | if (_codingCheckBox.state != 0 && _copyingCheckBox.state != 0) { 296 | [_classString appendFormat:kSexyJson_CodingAndCopyingCLASS,className,classContent]; 297 | }else if (_codingCheckBox.state != 0) { 298 | [_classString appendFormat:kSexyJson_CodingCLASS,className,classContent]; 299 | }else if (_copyingCheckBox.state != 0) { 300 | [_classString appendFormat:kSexyJson_CopyingCLASS,className,classContent]; 301 | }else { 302 | [_classString appendFormat:kSexyJson_Class,className,classContent]; 303 | } 304 | } 305 | break; 306 | case SexyJson_struct: 307 | [_classString appendFormat:kSexyJson_Struct,className,classContent]; 308 | break; 309 | default: 310 | if (_codingCheckBox.state != 0 && _copyingCheckBox.state != 0) { 311 | [_classString appendFormat:kSWHC_CodingAndCopyingCLASS,className,classContent]; 312 | }else if (_codingCheckBox.state != 0) { 313 | 314 | [_classString appendFormat:kSWHC_CodingCLASS,className,classContent]; 315 | }else if (_copyingCheckBox.state != 0) { 316 | [_classString appendFormat:kSWHC_CopyingCLASS,className,classContent]; 317 | }else { 318 | [_classString appendFormat:kSWHC_CLASS,className,classContent]; 319 | } 320 | break; 321 | } 322 | } 323 | [self setClassHeaderContent:_classString]; 324 | [self setClassSourceContent:_classMString]; 325 | }else{ 326 | #pragma clang diagnostic push 327 | #pragma clang diagnostic ignored"-Wdeprecated-declarations" 328 | NSAlert * alert = [NSAlert alertWithMessageText:@"WHC" defaultButton:@"确定" alternateButton:nil otherButton:nil informativeTextWithFormat:@"json或者xml数据不能为空"]; 329 | [alert runModal]; 330 | #pragma clang diagnostic pop 331 | } 332 | } 333 | 334 | - (NSString *)handleAfterClassName:(NSString *)className { 335 | if (className != nil && className.length > 0) { 336 | NSString * first = [className substringToIndex:1]; 337 | NSString * other = [className substringFromIndex:1]; 338 | return [NSString stringWithFormat:@"%@%@%@",_classPrefixName,[first uppercaseString],other]; 339 | } 340 | return className; 341 | } 342 | 343 | - (NSString *)handlePropertyName:(NSString *)propertyName { 344 | if (_firstLower) { 345 | if (propertyName != nil && propertyName.length > 0) { 346 | NSString * first = [propertyName substringToIndex:1]; 347 | NSString * other = [propertyName substringFromIndex:1]; 348 | return [NSString stringWithFormat:@"%@%@",[first lowercaseString],other]; 349 | } 350 | } 351 | return propertyName; 352 | } 353 | 354 | #pragma mark -解析处理引擎- 355 | 356 | - (NSString*)handleDataEngine:(id)object key:(NSString*)key{ 357 | if(object){ 358 | NSMutableString * property = [NSMutableString new]; 359 | NSMutableString * propertyMap = [NSMutableString new]; 360 | if([object isKindOfClass:[NSDictionary class]]){ 361 | NSDictionary * dict = object; 362 | if (_classPrefixName.length > 0) { 363 | if (!self.isSwift) { 364 | [property appendFormat:kWHC_Prefix_H_Func,_classPrefixName]; 365 | }else { 366 | [property appendFormat:kSWHC_Prefix_Func,_classPrefixName]; 367 | } 368 | } 369 | [dict enumerateKeysAndObjectsUsingBlock:^(NSString * key, id _Nonnull subObject, BOOL * _Nonnull stop) { 370 | NSString * className = [self handleAfterClassName:key]; 371 | NSString * propertyName = [self handlePropertyName:key]; 372 | if([subObject isKindOfClass:[NSDictionary class]]){ 373 | NSString * classContent = [self handleDataEngine:subObject key:key]; 374 | if(!self.isSwift) { 375 | [property appendFormat:kWHC_PROPERTY('s'),className,propertyName]; 376 | if (_codingCheckBox.state != 0 && _copyingCheckBox.state != 0) { 377 | [_classString appendFormat:kWHC_CodingAndCopyingCLASS,className,classContent]; 378 | }else if (_codingCheckBox.state != 0) { 379 | [_classString appendFormat:kWHC_CodingCLASS,className,classContent]; 380 | }else if (_copyingCheckBox.state != 0) { 381 | [_classString appendFormat:kWHC_CopyingCLASS,className,classContent]; 382 | }else { 383 | [_classString appendFormat:kWHC_CLASS,className,classContent]; 384 | } 385 | if (_classPrefixName.length > 0) { 386 | [_classMString appendFormat:kWHC_CLASS_Prefix_M,className,_classPrefixName]; 387 | }else { 388 | if (_codingCheckBox.state != 0 && _copyingCheckBox.state != 0) { 389 | [_classMString appendFormat:kWHC_CodingAndCopyingCLASS_M,className]; 390 | }else if (_codingCheckBox.state != 0) { 391 | [_classMString appendFormat:kWHC_CodingCLASS_M,className]; 392 | }else if (_copyingCheckBox.state != 0) { 393 | [_classMString appendFormat:kWHC_CopyingCLASS_M,className]; 394 | }else { 395 | [_classMString appendFormat:kWHC_CLASS_M,className]; 396 | } 397 | } 398 | }else{ 399 | 400 | [property appendFormat:kSWHC_PROPERTY,propertyName,className]; 401 | switch (_index) { 402 | case SexyJson_class: 403 | if (_codingCheckBox.state != 0 && _copyingCheckBox.state != 0) { 404 | [_classString appendFormat:kSexyJson_CodingAndCopyingCLASS,className,classContent]; 405 | }else if (_codingCheckBox.state != 0) { 406 | 407 | [_classString appendFormat:kSexyJson_CodingCLASS,className,classContent]; 408 | }else if (_copyingCheckBox.state != 0) { 409 | [_classString appendFormat:kSexyJson_CopyingCLASS,className,classContent]; 410 | }else { 411 | [_classString appendFormat:kSexyJson_Class,className,classContent]; 412 | } 413 | [propertyMap appendFormat:kSexyJson_Map,propertyName,key]; 414 | break; 415 | case SexyJson_struct: 416 | [_classString appendFormat:kSexyJson_Struct,className,classContent]; 417 | [propertyMap appendFormat:kSexyJson_Map,propertyName,key]; 418 | break; 419 | default: 420 | if (_codingCheckBox.state != 0 && _copyingCheckBox.state != 0) { 421 | [_classString appendFormat:kSWHC_CodingAndCopyingCLASS,className,classContent]; 422 | }else if (_codingCheckBox.state != 0) { 423 | 424 | [_classString appendFormat:kSWHC_CodingCLASS,className,classContent]; 425 | }else if (_copyingCheckBox.state != 0) { 426 | [_classString appendFormat:kSWHC_CopyingCLASS,className,classContent]; 427 | }else { 428 | [_classString appendFormat:kSWHC_CLASS,className,classContent]; 429 | } 430 | break; 431 | } 432 | 433 | } 434 | }else if ([subObject isKindOfClass:[NSArray class]]){ 435 | id firstValue = nil; 436 | NSString * classContent = nil; 437 | if (((NSArray *)subObject).count > 0) { 438 | firstValue = ((NSArray *)subObject).firstObject; 439 | }else { 440 | goto ARRAY_PASER; 441 | } 442 | if ([firstValue isKindOfClass:[NSString class]] || 443 | [firstValue isKindOfClass:[NSNumber class]]) { 444 | if ([firstValue isKindOfClass:[NSString class]]) { 445 | if(!self.isSwift){ 446 | [property appendFormat:kWHC_PROPERTY('c'),[NSString stringWithFormat:@"NSArray<%@ *>",@"NSString"],key]; 447 | }else{ 448 | [property appendFormat:kSWHC_PROPERTY,propertyName,[NSString stringWithFormat:@"[%@]",@"String"]]; 449 | [propertyMap appendFormat:kSexyJson_Map,propertyName,key]; 450 | } 451 | }else { 452 | if(!self.isSwift){ 453 | [property appendFormat:kWHC_PROPERTY('c'),[NSString stringWithFormat:@"NSArray<%@ *>",@"NSNumber"],key]; 454 | }else{ 455 | [propertyMap appendFormat:kSexyJson_Map,propertyName,key]; 456 | if (strcmp([firstValue objCType], @encode(float)) == 0 || 457 | strcmp([firstValue objCType], @encode(CGFloat)) == 0) { 458 | [property appendFormat:kSWHC_PROPERTY,propertyName,[NSString stringWithFormat:@"[%@]",@"CGFloat"]]; 459 | }else if (strcmp([firstValue objCType], @encode(double)) == 0) { 460 | [property appendFormat:kSWHC_PROPERTY,propertyName,[NSString stringWithFormat:@"[%@]",@"double"]]; 461 | }else if (strcmp([firstValue objCType], @encode(BOOL)) == 0) { 462 | [property appendFormat:kSWHC_PROPERTY,propertyName,[NSString stringWithFormat:@"[%@]",@"Bool"]]; 463 | }else { 464 | [property appendFormat:kSWHC_PROPERTY,propertyName,[NSString stringWithFormat:@"[%@]",@"Int"]]; 465 | } 466 | } 467 | } 468 | }else { 469 | ARRAY_PASER: 470 | classContent = [self handleDataEngine:subObject key:key]; 471 | if(!self.isSwift){ 472 | [property appendFormat:kWHC_PROPERTY('c'),[NSString stringWithFormat:@"NSArray<%@ *>",className],propertyName]; 473 | if (_codingCheckBox.state != 0 && _copyingCheckBox.state != 0) { 474 | [_classString appendFormat:kWHC_CodingAndCopyingCLASS,className,classContent]; 475 | }else if (_codingCheckBox.state != 0) { 476 | [_classString appendFormat:kWHC_CodingCLASS,className,classContent]; 477 | }else if (_copyingCheckBox.state != 0) { 478 | [_classString appendFormat:kWHC_CopyingCLASS,className,classContent]; 479 | }else { 480 | [_classString appendFormat:kWHC_CLASS,className,classContent]; 481 | } 482 | if (_classPrefixName.length > 0) { 483 | [_classMString appendFormat:kWHC_CLASS_Prefix_M,className,_classPrefixName]; 484 | }else { 485 | if (_codingCheckBox.state != 0 && _copyingCheckBox.state != 0) { 486 | [_classMString appendFormat:kWHC_CodingAndCopyingCLASS_M,className]; 487 | }else if (_codingCheckBox.state != 0) { 488 | [_classMString appendFormat:kWHC_CodingCLASS_M,className]; 489 | }else if (_copyingCheckBox.state != 0) { 490 | [_classMString appendFormat:kWHC_CopyingCLASS_M,className]; 491 | }else { 492 | [_classMString appendFormat:kWHC_CLASS_M,className]; 493 | } 494 | } 495 | }else{ 496 | [property appendFormat:kSWHC_PROPERTY,propertyName,[NSString stringWithFormat:@"[%@]",className]]; 497 | switch (_index) { 498 | case SexyJson_class: 499 | if (_codingCheckBox.state != 0 && _copyingCheckBox.state != 0) { 500 | [_classString appendFormat:kSexyJson_CodingAndCopyingCLASS,className,classContent]; 501 | }else if (_codingCheckBox.state != 0) { 502 | 503 | [_classString appendFormat:kSexyJson_CodingCLASS,className,classContent]; 504 | }else if (_copyingCheckBox.state != 0) { 505 | [_classString appendFormat:kSexyJson_CopyingCLASS,className,classContent]; 506 | }else { 507 | [_classString appendFormat:kSexyJson_Class,className,classContent]; 508 | } 509 | [propertyMap appendFormat:kSexyJson_Map,propertyName,key]; 510 | break; 511 | case SexyJson_struct: 512 | [_classString appendFormat:kSexyJson_Struct,className,classContent]; 513 | [propertyMap appendFormat:kSexyJson_Map,propertyName,key]; 514 | break; 515 | default: 516 | if (_codingCheckBox.state != 0 && _copyingCheckBox.state != 0) { 517 | [_classString appendFormat:kSWHC_CodingAndCopyingCLASS,className,classContent]; 518 | }else if (_codingCheckBox.state != 0) { 519 | 520 | [_classString appendFormat:kSWHC_CodingCLASS,className,classContent]; 521 | }else if (_copyingCheckBox.state != 0) { 522 | [_classString appendFormat:kSWHC_CopyingCLASS,className,classContent]; 523 | }else { 524 | [_classString appendFormat:kSWHC_CLASS,className,classContent]; 525 | } 526 | break; 527 | } 528 | } 529 | } 530 | }else if ([subObject isKindOfClass:[NSString class]]){ 531 | if(!self.isSwift){ 532 | [property appendFormat:kWHC_PROPERTY('c'),@"NSString",propertyName]; 533 | }else{ 534 | [property appendFormat:kSWHC_PROPERTY,propertyName,@"String"]; 535 | [propertyMap appendFormat:kSexyJson_Map,propertyName,key]; 536 | } 537 | }else if ([subObject isKindOfClass:[NSNumber class]]){ 538 | if(!self.isSwift){ 539 | if (strcmp([subObject objCType], @encode(float)) == 0 || 540 | strcmp([subObject objCType], @encode(CGFloat)) == 0) { 541 | [property appendFormat:kWHC_ASSIGN_PROPERTY,@"CGFloat",propertyName]; 542 | }else if (strcmp([subObject objCType], @encode(double)) == 0) { 543 | [property appendFormat:kWHC_ASSIGN_PROPERTY,@"double",propertyName]; 544 | }else if (strcmp([subObject objCType], @encode(BOOL)) == 0) { 545 | [property appendFormat:kWHC_ASSIGN_PROPERTY,@"BOOL",propertyName]; 546 | }else { 547 | [property appendFormat:kWHC_ASSIGN_PROPERTY,@"NSInteger",propertyName]; 548 | } 549 | }else{ 550 | [propertyMap appendFormat:kSexyJson_Map,propertyName,key]; 551 | if (strcmp([subObject objCType], @encode(float)) == 0 || 552 | strcmp([subObject objCType], @encode(CGFloat)) == 0) { 553 | [property appendFormat:kSWHC_ASSGIN_PROPERTY,propertyName,@"CGFloat = 0.0"]; 554 | }else if (strcmp([subObject objCType], @encode(double)) == 0) { 555 | [property appendFormat:kSWHC_ASSGIN_PROPERTY,propertyName,@"Double = 0.0"]; 556 | }else if (strcmp([subObject objCType], @encode(BOOL)) == 0) { 557 | [property appendFormat:kSWHC_ASSGIN_PROPERTY,propertyName,@"Bool = false"]; 558 | }else { 559 | [property appendFormat:kSWHC_ASSGIN_PROPERTY,propertyName,@"Int = 0"]; 560 | } 561 | } 562 | }else{ 563 | if(subObject == nil){ 564 | if(!self.isSwift){ 565 | [property appendFormat:kWHC_PROPERTY('c'),@"NSString",propertyName]; 566 | }else{ 567 | [property appendFormat:kSWHC_PROPERTY,propertyName,@"String"]; 568 | [propertyMap appendFormat:kSexyJson_Map,propertyName,key]; 569 | } 570 | }else if([subObject isKindOfClass:[NSNull class]]){ 571 | if(!self.isSwift){ 572 | [property appendFormat:kWHC_PROPERTY('c'),@"NSString",propertyName]; 573 | }else{ 574 | [property appendFormat:kSWHC_PROPERTY,propertyName,@"String"]; 575 | [propertyMap appendFormat:kSexyJson_Map,propertyName,key]; 576 | } 577 | } 578 | } 579 | }]; 580 | }else if ([object isKindOfClass:[NSArray class]]){ 581 | NSArray * dictArr = object; 582 | NSUInteger count = dictArr.count; 583 | if(count){ 584 | NSObject * tempObject = dictArr[0]; 585 | for (NSInteger i = 0; i < dictArr.count; i++) { 586 | NSObject * subObject = dictArr[i]; 587 | if([subObject isKindOfClass:[NSDictionary class]]){ 588 | if(((NSDictionary *)subObject).count > ((NSDictionary *)tempObject).count){ 589 | tempObject = subObject; 590 | } 591 | } 592 | if([subObject isKindOfClass:[NSDictionary class]]){ 593 | if(((NSArray *)subObject).count > ((NSArray *)tempObject).count){ 594 | tempObject = subObject; 595 | } 596 | } 597 | } 598 | [property appendString:[self handleDataEngine:tempObject key:key]]; 599 | } 600 | }else{ 601 | NSLog(@"key = %@",key); 602 | } 603 | switch (_index) { 604 | case SexyJson_struct: 605 | if (![property containsString:@"public mutating func sexyMap(_ map: [String : Any])"]) { 606 | [property appendFormat:kSexyJson_Struct_FuncMap,[self autoAlign:propertyMap]]; 607 | } 608 | break; 609 | case SexyJson_class: 610 | if (![property containsString:@"public func sexyMap(_ map: [String : Any])"]) { 611 | [property appendFormat:kSexyJson_FuncMap,[self autoAlign:propertyMap]]; 612 | } 613 | break; 614 | default: 615 | break; 616 | } 617 | return property; 618 | } 619 | return @""; 620 | } 621 | 622 | - (NSString *)autoAlign:(NSString *)content { 623 | NSMutableString * newContent = [NSMutableString new]; 624 | if (content) { 625 | NSArray * rows = [content componentsSeparatedByString:@"\n"]; 626 | NSInteger maxLen = 0; 627 | for (NSString * row in rows) { 628 | NSRange range = [row rangeOfString:@"<<<"]; 629 | if (range.location != NSNotFound) { 630 | maxLen = MAX([row rangeOfString:@"<<<"].location, maxLen); 631 | } 632 | } 633 | for (NSString * row in rows) { 634 | NSInteger rowindex = [row rangeOfString:@"<<<"].location; 635 | if (rowindex < maxLen && rowindex != NSNotFound) { 636 | NSInteger dindex = maxLen - rowindex; 637 | NSMutableString * blank = [NSMutableString new]; 638 | for (int i = 0; i < dindex; i++) { 639 | [blank appendString:@" "]; 640 | } 641 | NSMutableString * mrow = row.mutableCopy; 642 | [mrow insertString:blank atIndex:rowindex]; 643 | [newContent appendString:mrow]; 644 | [newContent appendString:@"\n"]; 645 | }else { 646 | [newContent appendString:row]; 647 | [newContent appendString:@"\n"]; 648 | } 649 | } 650 | } 651 | return newContent; 652 | } 653 | 654 | - (void)setRepresentedObject:(id)representedObject { 655 | [super setRepresentedObject:representedObject]; 656 | 657 | // Update the view, if already loaded. 658 | } 659 | 660 | @end 661 | --------------------------------------------------------------------------------