├── .gitignore ├── LICENSE ├── README.md ├── WTSDK.podspec ├── WTSDK.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── WTSDK ├── Category │ ├── NS │ │ ├── NSArray+WT.h │ │ ├── NSArray+WT.m │ │ ├── NSDate+WT.h │ │ ├── NSDate+WT.m │ │ ├── NSString+WT.h │ │ ├── NSString+WT.m │ │ ├── NSTimer+WT.h │ │ └── NSTimer+WT.m │ └── UI │ │ ├── CALayer+WT.h │ │ ├── CALayer+WT.m │ │ ├── Checkmark_failure_white@2x.png │ │ ├── Checkmark_success_white@2x.png │ │ ├── UIBarButtonItem+WT.h │ │ ├── UIBarButtonItem+WT.m │ │ ├── UIButton+WT.h │ │ ├── UIButton+WT.m │ │ ├── UIImage+WT.h │ │ ├── UIImage+WT.m │ │ ├── UILabel+WT.h │ │ ├── UILabel+WT.m │ │ ├── UITextView+WT.h │ │ ├── UITextView+WT.m │ │ ├── UIView+WT.h │ │ └── UIView+WT.m ├── Tool │ ├── Singleton.h │ ├── WTConst.h │ ├── WTUtility.h │ └── WTUtility.m └── View │ ├── WTLabel.h │ ├── WTLabel.m │ ├── WTTextField.h │ ├── WTTextField.m │ ├── WTTextView.h │ └── WTTextView.m └── WTSDKExample ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets └── AppIcon.appiconset │ └── Contents.json ├── Base.lproj ├── LaunchScreen.storyboard └── Main.storyboard ├── Info.plist ├── TestViewController.h ├── TestViewController.m ├── ViewController.h ├── ViewController.m └── main.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## mac 6 | .DS_Store 7 | 8 | ## Build generated 9 | build/ 10 | DerivedData 11 | 12 | ## Various settings 13 | *.pbxuser 14 | !default.pbxuser 15 | *.mode1v3 16 | !default.mode1v3 17 | *.mode2v3 18 | !default.mode2v3 19 | *.perspectivev3 20 | !default.perspectivev3 21 | xcuserdata 22 | 23 | ## Other 24 | *.xccheckout 25 | *.moved-aside 26 | *.xcuserstate 27 | *.xcscmblueprint 28 | 29 | ## Obj-C/Swift specific 30 | *.hmap 31 | *.ipa 32 | 33 | # CocoaPods 34 | # 35 | # We recommend against adding the Pods directory to your .gitignore. However 36 | # you should judge for yourself, the pros and cons are mentioned at: 37 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 38 | # 39 | # Pods/ 40 | 41 | # Carthage 42 | # 43 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 44 | # Carthage/Checkouts 45 | 46 | Carthage/Build 47 | 48 | # fastlane 49 | # 50 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 51 | # screenshots whenever they are needed. 52 | # For more information about the recommended setup visit: 53 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md 54 | 55 | fastlane/report.xml 56 | fastlane/screenshots 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 ibireme 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WTSDK 2 | 开发项目积累的一些category、tools、自定义控件 (OC版本) 3 | 4 | 详情进入blog中查看:http://www.jianshu.com/p/ec1684b0fad9 5 | 6 | ### CocoaPods 7 | ``` 8 | target '' do 9 | pod 'WTSDK' 10 | end 11 | ``` 12 | -------------------------------------------------------------------------------- /WTSDK.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'WTSDK' 3 | spec.version = '1.1.0' 4 | spec.summary = '开发项目积累的一些category、tools、自定义控件(OC版本)' 5 | spec.homepage = 'https://github.com/Tate-zwt/WTSDK.git' 6 | spec.license = 'MIT' 7 | spec.authors = { "Tate" => "weitingzhang.tate@gmail.com" } 8 | spec.platform = :ios, '9.0' 9 | spec.source = {:git => 'https://github.com/Tate-zwt/WTSDK.git', :tag => spec.version} 10 | spec.requires_arc = true 11 | spec.frameworks = 'UIKit', 'Foundation', 'CoreFoundation','CoreText', 'QuartzCore', 'Accelerate', 'MobileCoreServices' 12 | 13 | # 资源文件引用 14 | # spec.resources = "WTSDK/source.bundle" 15 | # spec.resources = "WTSDK/images/*.png" 16 | 17 | # 引用所有文件不分模块(文件夹) 18 | spec.source_files = 'WTSDK/**/*.{h,m}' 19 | 20 | end -------------------------------------------------------------------------------- /WTSDK.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 5D3EC954271EA18100F72541 /* UITextView+WT.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D3EC953271EA18100F72541 /* UITextView+WT.m */; }; 11 | 5DCF0649271D6400008382A3 /* TestViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF0639271D63FF008382A3 /* TestViewController.m */; }; 12 | 5DCF064A271D6400008382A3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5DCF063B271D63FF008382A3 /* Assets.xcassets */; }; 13 | 5DCF064B271D6400008382A3 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF063C271D63FF008382A3 /* ViewController.m */; }; 14 | 5DCF064C271D6400008382A3 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5DCF063D271D63FF008382A3 /* LaunchScreen.storyboard */; }; 15 | 5DCF064D271D6400008382A3 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5DCF063F271D63FF008382A3 /* Main.storyboard */; }; 16 | 5DCF064F271D6400008382A3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF0644271D63FF008382A3 /* main.m */; }; 17 | 5DCF0650271D6400008382A3 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF0646271D63FF008382A3 /* AppDelegate.m */; }; 18 | 5DCF067C271D640A008382A3 /* Checkmark_success_white@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5DCF0655271D6409008382A3 /* Checkmark_success_white@2x.png */; }; 19 | 5DCF067E271D640A008382A3 /* UIButton+WT.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF065D271D6409008382A3 /* UIButton+WT.m */; }; 20 | 5DCF067F271D640A008382A3 /* UIBarButtonItem+WT.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF065E271D6409008382A3 /* UIBarButtonItem+WT.m */; }; 21 | 5DCF0681271D640A008382A3 /* Checkmark_failure_white@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 5DCF0660271D6409008382A3 /* Checkmark_failure_white@2x.png */; }; 22 | 5DCF0682271D640A008382A3 /* UIImage+WT.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF0662271D6409008382A3 /* UIImage+WT.m */; }; 23 | 5DCF0683271D640A008382A3 /* CALayer+WT.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF0663271D6409008382A3 /* CALayer+WT.m */; }; 24 | 5DCF0684271D640A008382A3 /* UILabel+WT.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF0665271D6409008382A3 /* UILabel+WT.m */; }; 25 | 5DCF0685271D640A008382A3 /* UIView+WT.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF0666271D6409008382A3 /* UIView+WT.m */; }; 26 | 5DCF0686271D640A008382A3 /* NSString+WT.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF066B271D6409008382A3 /* NSString+WT.m */; }; 27 | 5DCF0687271D640A008382A3 /* NSDate+WT.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF066C271D6409008382A3 /* NSDate+WT.m */; }; 28 | 5DCF0688271D640A008382A3 /* NSArray+WT.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF066D271D6409008382A3 /* NSArray+WT.m */; }; 29 | 5DCF0689271D640A008382A3 /* NSTimer+WT.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF066F271D6409008382A3 /* NSTimer+WT.m */; }; 30 | 5DCF068A271D640A008382A3 /* WTLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF0673271D6409008382A3 /* WTLabel.m */; }; 31 | 5DCF068C271D640A008382A3 /* WTTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF0675271D6409008382A3 /* WTTextField.m */; }; 32 | 5DCF068D271D640A008382A3 /* WTUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF067B271D640A008382A3 /* WTUtility.m */; }; 33 | 5DCF0694271D7472008382A3 /* WTTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DCF0692271D7472008382A3 /* WTTextView.m */; }; 34 | /* End PBXBuildFile section */ 35 | 36 | /* Begin PBXFileReference section */ 37 | 57C10D0E1C20F61F00511EBC /* WTSDK.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WTSDK.app; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 5D3EC952271EA18100F72541 /* UITextView+WT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITextView+WT.h"; sourceTree = ""; }; 39 | 5D3EC953271EA18100F72541 /* UITextView+WT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextView+WT.m"; sourceTree = ""; }; 40 | 5DCF0639271D63FF008382A3 /* TestViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TestViewController.m; sourceTree = ""; }; 41 | 5DCF063A271D63FF008382A3 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 42 | 5DCF063B271D63FF008382A3 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 5DCF063C271D63FF008382A3 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 44 | 5DCF063E271D63FF008382A3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 45 | 5DCF0640271D63FF008382A3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 46 | 5DCF0644271D63FF008382A3 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 47 | 5DCF0645271D63FF008382A3 /* TestViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestViewController.h; sourceTree = ""; }; 48 | 5DCF0646271D63FF008382A3 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 49 | 5DCF0647271D63FF008382A3 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50 | 5DCF0648271D6400008382A3 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 51 | 5DCF0655271D6409008382A3 /* Checkmark_success_white@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Checkmark_success_white@2x.png"; sourceTree = ""; }; 52 | 5DCF0656271D6409008382A3 /* UIBarButtonItem+WT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIBarButtonItem+WT.h"; sourceTree = ""; }; 53 | 5DCF0658271D6409008382A3 /* UIImage+WT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+WT.h"; sourceTree = ""; }; 54 | 5DCF065A271D6409008382A3 /* UIView+WT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+WT.h"; sourceTree = ""; }; 55 | 5DCF065B271D6409008382A3 /* UILabel+WT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UILabel+WT.h"; sourceTree = ""; }; 56 | 5DCF065C271D6409008382A3 /* CALayer+WT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CALayer+WT.h"; sourceTree = ""; }; 57 | 5DCF065D271D6409008382A3 /* UIButton+WT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIButton+WT.m"; sourceTree = ""; }; 58 | 5DCF065E271D6409008382A3 /* UIBarButtonItem+WT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIBarButtonItem+WT.m"; sourceTree = ""; }; 59 | 5DCF0660271D6409008382A3 /* Checkmark_failure_white@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Checkmark_failure_white@2x.png"; sourceTree = ""; }; 60 | 5DCF0662271D6409008382A3 /* UIImage+WT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+WT.m"; sourceTree = ""; }; 61 | 5DCF0663271D6409008382A3 /* CALayer+WT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CALayer+WT.m"; sourceTree = ""; }; 62 | 5DCF0664271D6409008382A3 /* UIButton+WT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIButton+WT.h"; sourceTree = ""; }; 63 | 5DCF0665271D6409008382A3 /* UILabel+WT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UILabel+WT.m"; sourceTree = ""; }; 64 | 5DCF0666271D6409008382A3 /* UIView+WT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+WT.m"; sourceTree = ""; }; 65 | 5DCF0668271D6409008382A3 /* NSDate+WT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDate+WT.h"; sourceTree = ""; }; 66 | 5DCF0669271D6409008382A3 /* NSArray+WT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+WT.h"; sourceTree = ""; }; 67 | 5DCF066A271D6409008382A3 /* NSTimer+WT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTimer+WT.h"; sourceTree = ""; }; 68 | 5DCF066B271D6409008382A3 /* NSString+WT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+WT.m"; sourceTree = ""; }; 69 | 5DCF066C271D6409008382A3 /* NSDate+WT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+WT.m"; sourceTree = ""; }; 70 | 5DCF066D271D6409008382A3 /* NSArray+WT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+WT.m"; sourceTree = ""; }; 71 | 5DCF066E271D6409008382A3 /* NSString+WT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+WT.h"; sourceTree = ""; }; 72 | 5DCF066F271D6409008382A3 /* NSTimer+WT.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSTimer+WT.m"; sourceTree = ""; }; 73 | 5DCF0671271D6409008382A3 /* WTTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTTextField.h; sourceTree = ""; }; 74 | 5DCF0673271D6409008382A3 /* WTLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WTLabel.m; sourceTree = ""; }; 75 | 5DCF0675271D6409008382A3 /* WTTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WTTextField.m; sourceTree = ""; }; 76 | 5DCF0676271D6409008382A3 /* WTLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTLabel.h; sourceTree = ""; }; 77 | 5DCF0678271D6409008382A3 /* WTConst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTConst.h; sourceTree = ""; }; 78 | 5DCF0679271D640A008382A3 /* Singleton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Singleton.h; sourceTree = ""; }; 79 | 5DCF067A271D640A008382A3 /* WTUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTUtility.h; sourceTree = ""; }; 80 | 5DCF067B271D640A008382A3 /* WTUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WTUtility.m; sourceTree = ""; }; 81 | 5DCF0692271D7472008382A3 /* WTTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WTTextView.m; sourceTree = ""; }; 82 | 5DCF0693271D7472008382A3 /* WTTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTTextView.h; sourceTree = ""; }; 83 | /* End PBXFileReference section */ 84 | 85 | /* Begin PBXFrameworksBuildPhase section */ 86 | 57C10D0B1C20F61F00511EBC /* Frameworks */ = { 87 | isa = PBXFrameworksBuildPhase; 88 | buildActionMask = 2147483647; 89 | files = ( 90 | ); 91 | runOnlyForDeploymentPostprocessing = 0; 92 | }; 93 | /* End PBXFrameworksBuildPhase section */ 94 | 95 | /* Begin PBXGroup section */ 96 | 57C10D051C20F61F00511EBC = { 97 | isa = PBXGroup; 98 | children = ( 99 | 5DCF0638271D63FF008382A3 /* WTSDKExample */, 100 | 57C10D0F1C20F61F00511EBC /* Products */, 101 | ); 102 | sourceTree = ""; 103 | }; 104 | 57C10D0F1C20F61F00511EBC /* Products */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 57C10D0E1C20F61F00511EBC /* WTSDK.app */, 108 | ); 109 | name = Products; 110 | sourceTree = ""; 111 | }; 112 | 5DCF0638271D63FF008382A3 /* WTSDKExample */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 5DCF0652271D6409008382A3 /* WTSDK */, 116 | 5DCF0639271D63FF008382A3 /* TestViewController.m */, 117 | 5DCF063A271D63FF008382A3 /* AppDelegate.h */, 118 | 5DCF063B271D63FF008382A3 /* Assets.xcassets */, 119 | 5DCF063C271D63FF008382A3 /* ViewController.m */, 120 | 5DCF063D271D63FF008382A3 /* LaunchScreen.storyboard */, 121 | 5DCF063F271D63FF008382A3 /* Main.storyboard */, 122 | 5DCF0644271D63FF008382A3 /* main.m */, 123 | 5DCF0645271D63FF008382A3 /* TestViewController.h */, 124 | 5DCF0646271D63FF008382A3 /* AppDelegate.m */, 125 | 5DCF0647271D63FF008382A3 /* Info.plist */, 126 | 5DCF0648271D6400008382A3 /* ViewController.h */, 127 | ); 128 | path = WTSDKExample; 129 | sourceTree = ""; 130 | }; 131 | 5DCF0652271D6409008382A3 /* WTSDK */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 5DCF0653271D6409008382A3 /* Category */, 135 | 5DCF0670271D6409008382A3 /* View */, 136 | 5DCF0677271D6409008382A3 /* Tool */, 137 | ); 138 | path = WTSDK; 139 | sourceTree = SOURCE_ROOT; 140 | }; 141 | 5DCF0653271D6409008382A3 /* Category */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 5DCF0654271D6409008382A3 /* UI */, 145 | 5DCF0667271D6409008382A3 /* NS */, 146 | ); 147 | path = Category; 148 | sourceTree = ""; 149 | }; 150 | 5DCF0654271D6409008382A3 /* UI */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 5D3EC952271EA18100F72541 /* UITextView+WT.h */, 154 | 5D3EC953271EA18100F72541 /* UITextView+WT.m */, 155 | 5DCF065C271D6409008382A3 /* CALayer+WT.h */, 156 | 5DCF0663271D6409008382A3 /* CALayer+WT.m */, 157 | 5DCF0660271D6409008382A3 /* Checkmark_failure_white@2x.png */, 158 | 5DCF0655271D6409008382A3 /* Checkmark_success_white@2x.png */, 159 | 5DCF0656271D6409008382A3 /* UIBarButtonItem+WT.h */, 160 | 5DCF065E271D6409008382A3 /* UIBarButtonItem+WT.m */, 161 | 5DCF0664271D6409008382A3 /* UIButton+WT.h */, 162 | 5DCF065D271D6409008382A3 /* UIButton+WT.m */, 163 | 5DCF0658271D6409008382A3 /* UIImage+WT.h */, 164 | 5DCF0662271D6409008382A3 /* UIImage+WT.m */, 165 | 5DCF065B271D6409008382A3 /* UILabel+WT.h */, 166 | 5DCF0665271D6409008382A3 /* UILabel+WT.m */, 167 | 5DCF065A271D6409008382A3 /* UIView+WT.h */, 168 | 5DCF0666271D6409008382A3 /* UIView+WT.m */, 169 | ); 170 | path = UI; 171 | sourceTree = ""; 172 | }; 173 | 5DCF0667271D6409008382A3 /* NS */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | 5DCF0668271D6409008382A3 /* NSDate+WT.h */, 177 | 5DCF0669271D6409008382A3 /* NSArray+WT.h */, 178 | 5DCF066A271D6409008382A3 /* NSTimer+WT.h */, 179 | 5DCF066B271D6409008382A3 /* NSString+WT.m */, 180 | 5DCF066C271D6409008382A3 /* NSDate+WT.m */, 181 | 5DCF066D271D6409008382A3 /* NSArray+WT.m */, 182 | 5DCF066E271D6409008382A3 /* NSString+WT.h */, 183 | 5DCF066F271D6409008382A3 /* NSTimer+WT.m */, 184 | ); 185 | path = NS; 186 | sourceTree = ""; 187 | }; 188 | 5DCF0670271D6409008382A3 /* View */ = { 189 | isa = PBXGroup; 190 | children = ( 191 | 5DCF0693271D7472008382A3 /* WTTextView.h */, 192 | 5DCF0692271D7472008382A3 /* WTTextView.m */, 193 | 5DCF0676271D6409008382A3 /* WTLabel.h */, 194 | 5DCF0673271D6409008382A3 /* WTLabel.m */, 195 | 5DCF0671271D6409008382A3 /* WTTextField.h */, 196 | 5DCF0675271D6409008382A3 /* WTTextField.m */, 197 | ); 198 | path = View; 199 | sourceTree = ""; 200 | }; 201 | 5DCF0677271D6409008382A3 /* Tool */ = { 202 | isa = PBXGroup; 203 | children = ( 204 | 5DCF0678271D6409008382A3 /* WTConst.h */, 205 | 5DCF0679271D640A008382A3 /* Singleton.h */, 206 | 5DCF067A271D640A008382A3 /* WTUtility.h */, 207 | 5DCF067B271D640A008382A3 /* WTUtility.m */, 208 | ); 209 | path = Tool; 210 | sourceTree = ""; 211 | }; 212 | /* End PBXGroup section */ 213 | 214 | /* Begin PBXNativeTarget section */ 215 | 57C10D0D1C20F61F00511EBC /* WTSDK */ = { 216 | isa = PBXNativeTarget; 217 | buildConfigurationList = 57C10D251C20F61F00511EBC /* Build configuration list for PBXNativeTarget "WTSDK" */; 218 | buildPhases = ( 219 | 57C10D0A1C20F61F00511EBC /* Sources */, 220 | 57C10D0B1C20F61F00511EBC /* Frameworks */, 221 | 57C10D0C1C20F61F00511EBC /* Resources */, 222 | ); 223 | buildRules = ( 224 | ); 225 | dependencies = ( 226 | ); 227 | name = WTSDK; 228 | productName = WTSDK; 229 | productReference = 57C10D0E1C20F61F00511EBC /* WTSDK.app */; 230 | productType = "com.apple.product-type.application"; 231 | }; 232 | /* End PBXNativeTarget section */ 233 | 234 | /* Begin PBXProject section */ 235 | 57C10D061C20F61F00511EBC /* Project object */ = { 236 | isa = PBXProject; 237 | attributes = { 238 | LastUpgradeCheck = 0720; 239 | ORGANIZATIONNAME = zwt; 240 | TargetAttributes = { 241 | 57C10D0D1C20F61F00511EBC = { 242 | CreatedOnToolsVersion = 7.2; 243 | }; 244 | }; 245 | }; 246 | buildConfigurationList = 57C10D091C20F61F00511EBC /* Build configuration list for PBXProject "WTSDK" */; 247 | compatibilityVersion = "Xcode 3.2"; 248 | developmentRegion = English; 249 | hasScannedForEncodings = 0; 250 | knownRegions = ( 251 | English, 252 | en, 253 | Base, 254 | da, 255 | de, 256 | "es-ES", 257 | es, 258 | fr, 259 | ja, 260 | pt, 261 | "zh-Hans", 262 | "zh-Hant", 263 | ); 264 | mainGroup = 57C10D051C20F61F00511EBC; 265 | productRefGroup = 57C10D0F1C20F61F00511EBC /* Products */; 266 | projectDirPath = ""; 267 | projectRoot = ""; 268 | targets = ( 269 | 57C10D0D1C20F61F00511EBC /* WTSDK */, 270 | ); 271 | }; 272 | /* End PBXProject section */ 273 | 274 | /* Begin PBXResourcesBuildPhase section */ 275 | 57C10D0C1C20F61F00511EBC /* Resources */ = { 276 | isa = PBXResourcesBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | 5DCF067C271D640A008382A3 /* Checkmark_success_white@2x.png in Resources */, 280 | 5DCF064D271D6400008382A3 /* Main.storyboard in Resources */, 281 | 5DCF064A271D6400008382A3 /* Assets.xcassets in Resources */, 282 | 5DCF064C271D6400008382A3 /* LaunchScreen.storyboard in Resources */, 283 | 5DCF0681271D640A008382A3 /* Checkmark_failure_white@2x.png in Resources */, 284 | ); 285 | runOnlyForDeploymentPostprocessing = 0; 286 | }; 287 | /* End PBXResourcesBuildPhase section */ 288 | 289 | /* Begin PBXSourcesBuildPhase section */ 290 | 57C10D0A1C20F61F00511EBC /* Sources */ = { 291 | isa = PBXSourcesBuildPhase; 292 | buildActionMask = 2147483647; 293 | files = ( 294 | 5DCF068C271D640A008382A3 /* WTTextField.m in Sources */, 295 | 5DCF0682271D640A008382A3 /* UIImage+WT.m in Sources */, 296 | 5DCF064B271D6400008382A3 /* ViewController.m in Sources */, 297 | 5DCF0694271D7472008382A3 /* WTTextView.m in Sources */, 298 | 5DCF0687271D640A008382A3 /* NSDate+WT.m in Sources */, 299 | 5DCF067F271D640A008382A3 /* UIBarButtonItem+WT.m in Sources */, 300 | 5DCF064F271D6400008382A3 /* main.m in Sources */, 301 | 5DCF0684271D640A008382A3 /* UILabel+WT.m in Sources */, 302 | 5DCF068A271D640A008382A3 /* WTLabel.m in Sources */, 303 | 5DCF067E271D640A008382A3 /* UIButton+WT.m in Sources */, 304 | 5DCF0649271D6400008382A3 /* TestViewController.m in Sources */, 305 | 5DCF068D271D640A008382A3 /* WTUtility.m in Sources */, 306 | 5D3EC954271EA18100F72541 /* UITextView+WT.m in Sources */, 307 | 5DCF0689271D640A008382A3 /* NSTimer+WT.m in Sources */, 308 | 5DCF0685271D640A008382A3 /* UIView+WT.m in Sources */, 309 | 5DCF0683271D640A008382A3 /* CALayer+WT.m in Sources */, 310 | 5DCF0688271D640A008382A3 /* NSArray+WT.m in Sources */, 311 | 5DCF0686271D640A008382A3 /* NSString+WT.m in Sources */, 312 | 5DCF0650271D6400008382A3 /* AppDelegate.m in Sources */, 313 | ); 314 | runOnlyForDeploymentPostprocessing = 0; 315 | }; 316 | /* End PBXSourcesBuildPhase section */ 317 | 318 | /* Begin PBXVariantGroup section */ 319 | 5DCF063D271D63FF008382A3 /* LaunchScreen.storyboard */ = { 320 | isa = PBXVariantGroup; 321 | children = ( 322 | 5DCF063E271D63FF008382A3 /* Base */, 323 | ); 324 | name = LaunchScreen.storyboard; 325 | sourceTree = ""; 326 | }; 327 | 5DCF063F271D63FF008382A3 /* Main.storyboard */ = { 328 | isa = PBXVariantGroup; 329 | children = ( 330 | 5DCF0640271D63FF008382A3 /* Base */, 331 | ); 332 | name = Main.storyboard; 333 | sourceTree = ""; 334 | }; 335 | /* End PBXVariantGroup section */ 336 | 337 | /* Begin XCBuildConfiguration section */ 338 | 57C10D231C20F61F00511EBC /* Debug */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | ALWAYS_SEARCH_USER_PATHS = NO; 342 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 343 | CLANG_CXX_LIBRARY = "libc++"; 344 | CLANG_ENABLE_MODULES = YES; 345 | CLANG_ENABLE_OBJC_ARC = YES; 346 | CLANG_WARN_BOOL_CONVERSION = YES; 347 | CLANG_WARN_CONSTANT_CONVERSION = YES; 348 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 349 | CLANG_WARN_EMPTY_BODY = YES; 350 | CLANG_WARN_ENUM_CONVERSION = YES; 351 | CLANG_WARN_INT_CONVERSION = YES; 352 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 353 | CLANG_WARN_UNREACHABLE_CODE = YES; 354 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 355 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 356 | COPY_PHASE_STRIP = NO; 357 | DEBUG_INFORMATION_FORMAT = dwarf; 358 | ENABLE_STRICT_OBJC_MSGSEND = YES; 359 | ENABLE_TESTABILITY = YES; 360 | GCC_C_LANGUAGE_STANDARD = gnu99; 361 | GCC_DYNAMIC_NO_PIC = NO; 362 | GCC_NO_COMMON_BLOCKS = YES; 363 | GCC_OPTIMIZATION_LEVEL = 0; 364 | GCC_PREPROCESSOR_DEFINITIONS = ( 365 | "DEBUG=1", 366 | "$(inherited)", 367 | ); 368 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 369 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 370 | GCC_WARN_UNDECLARED_SELECTOR = YES; 371 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 372 | GCC_WARN_UNUSED_FUNCTION = YES; 373 | GCC_WARN_UNUSED_VARIABLE = YES; 374 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 375 | MTL_ENABLE_DEBUG_INFO = YES; 376 | ONLY_ACTIVE_ARCH = YES; 377 | SDKROOT = iphoneos; 378 | }; 379 | name = Debug; 380 | }; 381 | 57C10D241C20F61F00511EBC /* Release */ = { 382 | isa = XCBuildConfiguration; 383 | buildSettings = { 384 | ALWAYS_SEARCH_USER_PATHS = NO; 385 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 386 | CLANG_CXX_LIBRARY = "libc++"; 387 | CLANG_ENABLE_MODULES = YES; 388 | CLANG_ENABLE_OBJC_ARC = YES; 389 | CLANG_WARN_BOOL_CONVERSION = YES; 390 | CLANG_WARN_CONSTANT_CONVERSION = YES; 391 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 392 | CLANG_WARN_EMPTY_BODY = YES; 393 | CLANG_WARN_ENUM_CONVERSION = YES; 394 | CLANG_WARN_INT_CONVERSION = YES; 395 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 396 | CLANG_WARN_UNREACHABLE_CODE = YES; 397 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 398 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 399 | COPY_PHASE_STRIP = NO; 400 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 401 | ENABLE_NS_ASSERTIONS = NO; 402 | ENABLE_STRICT_OBJC_MSGSEND = YES; 403 | GCC_C_LANGUAGE_STANDARD = gnu99; 404 | GCC_NO_COMMON_BLOCKS = YES; 405 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 406 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 407 | GCC_WARN_UNDECLARED_SELECTOR = YES; 408 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 409 | GCC_WARN_UNUSED_FUNCTION = YES; 410 | GCC_WARN_UNUSED_VARIABLE = YES; 411 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 412 | MTL_ENABLE_DEBUG_INFO = NO; 413 | SDKROOT = iphoneos; 414 | VALIDATE_PRODUCT = YES; 415 | }; 416 | name = Release; 417 | }; 418 | 57C10D261C20F61F00511EBC /* Debug */ = { 419 | isa = XCBuildConfiguration; 420 | buildSettings = { 421 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 422 | INFOPLIST_FILE = "$(SRCROOT)/WTSDKExample/Info.plist"; 423 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 424 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 425 | PRODUCT_BUNDLE_IDENTIFIER = cn.zwt.com.WTSDK; 426 | PRODUCT_NAME = "$(TARGET_NAME)"; 427 | }; 428 | name = Debug; 429 | }; 430 | 57C10D271C20F61F00511EBC /* Release */ = { 431 | isa = XCBuildConfiguration; 432 | buildSettings = { 433 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 434 | INFOPLIST_FILE = "$(SRCROOT)/WTSDKExample/Info.plist"; 435 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 436 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 437 | PRODUCT_BUNDLE_IDENTIFIER = cn.zwt.com.WTSDK; 438 | PRODUCT_NAME = "$(TARGET_NAME)"; 439 | }; 440 | name = Release; 441 | }; 442 | /* End XCBuildConfiguration section */ 443 | 444 | /* Begin XCConfigurationList section */ 445 | 57C10D091C20F61F00511EBC /* Build configuration list for PBXProject "WTSDK" */ = { 446 | isa = XCConfigurationList; 447 | buildConfigurations = ( 448 | 57C10D231C20F61F00511EBC /* Debug */, 449 | 57C10D241C20F61F00511EBC /* Release */, 450 | ); 451 | defaultConfigurationIsVisible = 0; 452 | defaultConfigurationName = Release; 453 | }; 454 | 57C10D251C20F61F00511EBC /* Build configuration list for PBXNativeTarget "WTSDK" */ = { 455 | isa = XCConfigurationList; 456 | buildConfigurations = ( 457 | 57C10D261C20F61F00511EBC /* Debug */, 458 | 57C10D271C20F61F00511EBC /* Release */, 459 | ); 460 | defaultConfigurationIsVisible = 0; 461 | defaultConfigurationName = Release; 462 | }; 463 | /* End XCConfigurationList section */ 464 | }; 465 | rootObject = 57C10D061C20F61F00511EBC /* Project object */; 466 | } 467 | -------------------------------------------------------------------------------- /WTSDK.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WTSDK.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /WTSDK/Category/NS/NSArray+WT.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // NSArray+WT.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSArray (WT) 12 | 13 | /** 14 | * 检查是否越界和NSNull如果是返回nil 15 | */ 16 | - (id)objectAtIndexCheck:(NSUInteger)index; 17 | 18 | #pragma mark - 19 | /** 20 | * 是否真是数组 [self isKindOfClass:[NSArray class]] 21 | */ 22 | @property (nonatomic, assign, readonly) BOOL isAClass; 23 | /** 24 | * 数组 转为 JsonStr 25 | */ 26 | @property (nonatomic, copy, readonly) NSString *jsonStr; 27 | /** 28 | * 根据一个字符串来将数组连接成一个新的字符串,这里根据逗号 29 | */ 30 | @property (nonatomic, copy, readonly) NSString *combinStr; 31 | /** 32 | * 请接收返回的数组 按 字段 给数组排序 33 | */ 34 | - (NSArray *)sortbyKey:(NSString *)key asc:(BOOL)ascend; 35 | 36 | /** 37 | * 数组比较 38 | */ 39 | - (BOOL)compareIgnoreObjectOrderWithArray:(NSArray *)array; 40 | 41 | /** 42 | * 数组计算交集 43 | */ 44 | - (NSArray *)arrayForIntersectionWithOtherArray:(NSArray *)otherArray; 45 | 46 | /** 47 | * 数组计算差集 48 | */ 49 | - (NSArray *)arrayForMinusWithOtherArray:(NSArray *)otherArray; 50 | 51 | @end 52 | 53 | 54 | -------------------------------------------------------------------------------- /WTSDK/Category/NS/NSArray+WT.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // NSArray+WT.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "NSArray+WT.h" 10 | @implementation NSArray (WT) 11 | 12 | - (id)objectAtIndexCheck:(NSUInteger)index { 13 | if (index < self.count) { 14 | return self[index]; 15 | } else { 16 | //数组越界了就返回nil 17 | return nil; 18 | } 19 | } 20 | /** 21 | * [self isKindOfClass:[NSArray class]] 22 | */ 23 | - (BOOL)isAClass { 24 | return [self isKindOfClass:[NSArray class]]; 25 | } 26 | 27 | /** 28 | * 数组 转为 JsonStr 29 | */ 30 | - (NSString *)jsonStr { 31 | return [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:self options:0 error:NULL] encoding:NSUTF8StringEncoding]; 32 | } 33 | /** 34 | * 根据一个字符串来将数组连接成一个新的字符串,这里根据逗号 35 | */ 36 | - (NSString *)combinStr { 37 | return [self componentsJoinedByString:@","]; 38 | } 39 | 40 | /** 41 | * 请接收返回的数组 按 字段 给数组排序 42 | */ 43 | - (NSArray *)sortbyKey:(NSString *)key asc:(BOOL)ascend { 44 | return [self sortedArrayUsingDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:key ascending:ascend]]]; 45 | } 46 | 47 | #pragma mark 数组比较 48 | - (BOOL)compareIgnoreObjectOrderWithArray:(NSArray *)array { 49 | NSSet *set1 = [NSSet setWithArray:self]; 50 | NSSet *set2 = [NSSet setWithArray:array]; 51 | return [set1 isEqualToSet:set2]; 52 | } 53 | 54 | /** 55 | * 数组计算交集 56 | */ 57 | - (NSArray *)arrayForIntersectionWithOtherArray:(NSArray *)otherArray { 58 | NSMutableArray *intersectionArray = [NSMutableArray array]; 59 | if (self.count == 0) return nil; 60 | if (otherArray == nil) return nil; 61 | //遍历 62 | for (id obj in self) { 63 | if (![otherArray containsObject:obj]) continue; 64 | //添加 65 | [intersectionArray addObject:obj]; 66 | } 67 | 68 | return intersectionArray; 69 | } 70 | 71 | /** 72 | * 数组计算差集 73 | */ 74 | - (NSArray *)arrayForMinusWithOtherArray:(NSArray *)otherArray { 75 | if (self == nil) return nil; 76 | if (otherArray == nil) return self; 77 | NSMutableArray *minusArray = [NSMutableArray arrayWithArray:self]; 78 | //遍历 79 | for (id obj in otherArray) { 80 | if (![self containsObject:obj]) continue; 81 | //移除 82 | [minusArray removeObject:obj]; 83 | } 84 | return minusArray; 85 | } 86 | 87 | @end 88 | 89 | -------------------------------------------------------------------------------- /WTSDK/Category/NS/NSDate+WT.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // NSDate+WT.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDate (WT) 12 | /** 13 | * 判断某个时间是否为今年 14 | */ 15 | - (BOOL)isThisYear; 16 | /** 17 | * 判断某个时间是否为昨天 18 | */ 19 | - (BOOL)isYesterday; 20 | /** 21 | * 判断某个时间是否为今天 22 | */ 23 | - (BOOL)isToday; 24 | 25 | /** 字符串时间戳。 */ 26 | @property (nonatomic, copy, readonly) NSString *timeStampStr; 27 | 28 | /** 29 | * 长型时间戳 30 | */ 31 | @property (nonatomic, assign, readonly) double timeStamp; 32 | 33 | /** 34 | * 时间成分 35 | */ 36 | @property (nonatomic, strong, readonly) NSDateComponents *components; 37 | 38 | /** 比较两个日期的大小 0 : 相同 1 : oneDay 大 2 : anotherDay 大*/ 39 | + (NSInteger)compareOneDay:(NSDate *)oneDay withAnotherDay:(NSDate *)anotherDay; 40 | /** 41 | * 两个时间比较 42 | * 43 | * @param unit 成分单元 44 | * @param fromDate 起点时间 45 | * @param toDate 终点时间 46 | * 47 | * @return 时间成分对象 48 | */ 49 | + (NSDateComponents *)dateComponents:(NSCalendarUnit)unit fromDate:(NSDate *)fromDate toDate:(NSDate *)toDate; 50 | 51 | /** 52 | *@Description:根据年份、月份、日期、小时数、分钟数、秒数返回NSDate 53 | *@Params: 54 | * year:年份 55 | * month:月份 56 | * day:日期 57 | * hour:小时数 58 | * minute:分钟数 59 | * second:秒数 60 | *@Return: 61 | */ 62 | + (NSDate *)dateWithYear:(NSUInteger)year 63 | Month:(NSUInteger)month 64 | Day:(NSUInteger)day 65 | Hour:(NSUInteger)hour 66 | Minute:(NSUInteger)minute 67 | Second:(NSUInteger)second; 68 | 69 | /** 70 | *@Description:实现dateFormatter单例方法 71 | *@Params:nil 72 | *Return:相应格式的NSDataFormatter对象 73 | */ 74 | + (NSDateFormatter *)defaultDateFormatterWithFormatYYYYMMddHHmmss; 75 | + (NSDateFormatter *)defaultDateFormatterWithFormatYYYYMMdd; 76 | + (NSDateFormatter *)defaultDateFormatterWithFormatMMddHHmm; 77 | 78 | + (NSDateFormatter *)defaultDateFormatterWithFormatYYYYMMddHHmmInChinese; 79 | + (NSDateFormatter *)defaultDateFormatterWithFormatMMddHHmmInChinese; 80 | 81 | /** 82 | *@Description:获取当天的包括“年”,“月”,“日”,“周”,“时”,“分”,“秒”的NSDateComponents 83 | *@Params:nil 84 | *@Return:当天的包括“年”,“月”,“日”,“周”,“时”,“分”,“秒”的NSDateComponents 85 | */ 86 | - (NSDateComponents *)componentsOfDay; 87 | 88 | /** 89 | *@Description:获得NSDate对应的年份 90 | *@Params:nil 91 | *@Return:NSDate对应的年份 92 | **/ 93 | - (NSUInteger)year; 94 | 95 | /** 96 | *@Description:获得NSDate对应的月份 97 | *@Params:nil 98 | *@Return:NSDate对应的月份 99 | */ 100 | - (NSUInteger)month; 101 | 102 | /** 103 | *@Description:获得NSDate对应的日期 104 | *@Params:nil 105 | *@Return:NSDate对应的日期 106 | */ 107 | - (NSUInteger)day; 108 | 109 | /** 110 | *@Description:获得NSDate对应的小时数 111 | *@Params:nil 112 | *@Return:NSDate对应的小时数 113 | */ 114 | - (NSUInteger)hour; 115 | 116 | /** 117 | *@Description:获得NSDate对应的分钟数 118 | *@Params:nil 119 | *@Return:NSDate对应的分钟数 120 | */ 121 | - (NSUInteger)minute; 122 | 123 | /** 124 | *@Description:获得NSDate对应的秒数 125 | *@Params:nil 126 | *@Return:NSDate对应的秒数 127 | */ 128 | - (NSUInteger)second; 129 | 130 | /** 131 | *@Description:获得NSDate对应的星期 132 | *@Params:nil 133 | *@Return:NSDate对应的星期 134 | */ 135 | - (NSUInteger)weekday; 136 | 137 | /** 138 | *@Description:获取当天是当年的第几周 139 | *@Params:nil 140 | *@Return:当天是当年的第几周 141 | */ 142 | - (NSUInteger)weekOfDayInYear; 143 | 144 | /** 145 | *@Description:获得一般当天的工作开始时间 146 | *@Params:nil 147 | *@Return:一般当天的工作开始时间 148 | */ 149 | - (NSDate *)workBeginTime; 150 | 151 | /** 152 | *@Description:获得一般当天的工作结束时间 153 | *@Params:nil 154 | *@Return:一般当天的工作结束时间 155 | */ 156 | - (NSDate *)workEndTime; 157 | 158 | /** 159 | *@Description:获取一小时后的时间 160 | *@Params:nil 161 | *@Return:一小时后的时间 162 | **/ 163 | - (NSDate *)oneHourLater; 164 | 165 | /** 166 | *@Description:获得某一天的这个时刻 167 | *@Params:nil 168 | *@Return:某一天的这个时刻 169 | */ 170 | - (NSDate *)sameTimeOfDate; 171 | 172 | /** 173 | *@Description:判断与某一天是否为同一天 174 | *@Params: 175 | * otherDate:某一天 176 | *@Return:YES-同一天;NO-不同一天 177 | */ 178 | - (BOOL)sameDayWithDate:(NSDate *)otherDate; 179 | 180 | /** 181 | *@Description:判断与某一天是否为同一周 182 | *@Params: 183 | * otherDate:某一天 184 | *@Return:YES-同一周;NO-不同一周 185 | */ 186 | - (BOOL)sameWeekWithDate:(NSDate *)otherDate; 187 | 188 | /** 189 | *@Description:判断与某一天是否为同一月 190 | *@Params: 191 | * otherDate:某一天 192 | *@Return:YES-同一月;NO-不同一月 193 | */ 194 | - (BOOL)sameMonthWithDate:(NSDate *)otherDate; 195 | 196 | /** 多久以前呢 ? 1分钟内 X分钟前 X天前 */ 197 | - (NSString *)whatTimeAgo; 198 | 199 | /** 前段时间日期的描述 上午?? 星期二 下午?? */ 200 | - (NSString *)whatTimeBefore; 201 | 202 | /** 203 | * 今天星期几来着? 204 | */ 205 | - (NSString *)whatDayTheWeek; 206 | 207 | /** YYYY-MM-dd HH:mm:ss */ 208 | - (NSString *)WT_YYYYMMddHHmmss; 209 | /** YYYY.MM.dd */ 210 | - (NSString *)WT_YYYYMMdd; 211 | /** YYYY-MM-dd */ 212 | - (NSString *)WT_YYYYMMdd__; 213 | /** HH:mm */ 214 | - (NSString *)WT_HHmm; 215 | 216 | - (NSString *)MMddHHmm; 217 | - (NSString *)YYYYMMddHHmmInChinese; 218 | - (NSString *)MMddHHmmInChinese; 219 | 220 | @end 221 | -------------------------------------------------------------------------------- /WTSDK/Category/NS/NSDate+WT.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // NSDate+WT.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "NSDate+WT.h" 10 | 11 | @implementation NSDate (WT) 12 | 13 | /** 14 | * 判断某个时间是否为今年 15 | */ 16 | - (BOOL)isThisYear { 17 | NSCalendar *calendar = [NSCalendar currentCalendar]; 18 | // 获得某个时间的年月日时分秒 19 | NSDateComponents *dateCmps = [calendar components:NSCalendarUnitYear fromDate:self]; 20 | NSDateComponents *nowCmps = [calendar components:NSCalendarUnitYear fromDate:[NSDate date]]; 21 | return dateCmps.year == nowCmps.year; 22 | } 23 | 24 | /** 25 | * 判断某个时间是否为昨天 26 | */ 27 | - (BOOL)isYesterday { 28 | NSDate *now = [NSDate date]; 29 | 30 | // date == 2014-04-30 10:05:28 --> 2014-04-30 00:00:00 31 | // now == 2014-05-01 09:22:10 --> 2014-05-01 00:00:00 32 | NSDateFormatter *fmt = [[NSDateFormatter alloc] init]; 33 | fmt.dateFormat = @"yyyy-MM-dd"; 34 | 35 | // 2014-04-30 36 | NSString *dateStr = [fmt stringFromDate:self]; 37 | // 2014-10-18 38 | NSString *nowStr = [fmt stringFromDate:now]; 39 | 40 | // 2014-10-30 00:00:00 41 | NSDate *date = [fmt dateFromString:dateStr]; 42 | // 2014-10-18 00:00:00 43 | now = [fmt dateFromString:nowStr]; 44 | 45 | NSCalendar *calendar = [NSCalendar currentCalendar]; 46 | 47 | NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay; 48 | NSDateComponents *cmps = [calendar components:unit fromDate:date toDate:now options:0]; 49 | 50 | return cmps.year == 0 && cmps.month == 0 && cmps.day == 1; 51 | } 52 | 53 | /** 54 | * 判断某个时间是否为今天 55 | */ 56 | - (BOOL)isToday { 57 | NSDate *now = [NSDate date]; 58 | NSDateFormatter *fmt = [[NSDateFormatter alloc] init]; 59 | fmt.dateFormat = @"yyyy-MM-dd"; 60 | 61 | NSString *dateStr = [fmt stringFromDate:self]; 62 | NSString *nowStr = [fmt stringFromDate:now]; 63 | 64 | return [dateStr isEqualToString:nowStr]; 65 | } 66 | 67 | /** 字符时间戳 */ 68 | - (NSString *)timeStampStr { 69 | return [@([self timeIntervalSince1970]).stringValue copy]; 70 | } 71 | /** 72 | * 长型时间戳 73 | */ 74 | - (double)timeStamp{ 75 | return [self timeIntervalSince1970]; 76 | } 77 | 78 | /* 79 | * 时间成分 80 | */ 81 | - (NSDateComponents *)components { 82 | //创建日历 83 | NSCalendar *calendar = [NSCalendar currentCalendar]; 84 | //定义成分 85 | NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; 86 | return [calendar components:unit fromDate:self]; 87 | } 88 | 89 | - (BOOL)calWithValue:(NSInteger)value { 90 | 91 | //得到给定时间的处理后的时间的components 92 | NSDateComponents *dateComponents = self.ymdDate.components; 93 | 94 | //得到当前时间的处理后的时间的components 95 | NSDateComponents *nowComponents = [NSDate date].ymdDate.components; 96 | 97 | //比较 98 | BOOL res = dateComponents.year == nowComponents.year && dateComponents.month == nowComponents.month && (dateComponents.day + value) == nowComponents.day; 99 | 100 | return res; 101 | } 102 | 103 | /* 104 | * 清空时分秒,保留年月日 105 | */ 106 | - (NSDate *)ymdDate { 107 | 108 | //定义fmt 109 | NSDateFormatter *fmt = [[NSDateFormatter alloc] init]; 110 | 111 | //设置格式:去除时分秒 112 | fmt.dateFormat = @"yyyy-MM-dd"; 113 | 114 | //得到字符串格式的时间 115 | NSString *dateString = [fmt stringFromDate:self]; 116 | 117 | //再转为date 118 | NSDate *date = [fmt dateFromString:dateString]; 119 | 120 | return date; 121 | } 122 | 123 | /** 比较两个日期的大小 0 : 相同 1 : oneDay 大 2 : anotherDay 大*/ 124 | + (NSInteger)compareOneDay:(NSDate *)oneDay withAnotherDay:(NSDate *)anotherDay 125 | { 126 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 127 | [dateFormatter setDateFormat:@"dd-MM-yyyy"]; 128 | NSString *oneDayStr = [dateFormatter stringFromDate:oneDay]; 129 | NSString *anotherDayStr = [dateFormatter stringFromDate:anotherDay]; 130 | NSDate *dateA = [dateFormatter dateFromString:oneDayStr]; 131 | NSDate *dateB = [dateFormatter dateFromString:anotherDayStr]; 132 | NSComparisonResult result = [dateA compare:dateB]; 133 | if (result == NSOrderedDescending) { 134 | //NSLog(@"oneDay is in the future"); 135 | return 1; 136 | } 137 | else if (result == NSOrderedAscending){ 138 | //NSLog(@"oneDay is in the past"); 139 | return 2; 140 | } 141 | //NSLog(@"Both dates are the same"); 142 | return 0; 143 | } 144 | 145 | 146 | /** 147 | * 两个时间比较 148 | * 149 | * @param unit 成分单元 150 | * @param fromDate 起点时间 151 | * @param toDate 终点时间 152 | * 153 | * @return 时间成分对象 154 | */ 155 | + (NSDateComponents *)dateComponents:(NSCalendarUnit)unit fromDate:(NSDate *)fromDate toDate:(NSDate *)toDate { 156 | 157 | //创建日历 158 | NSCalendar *calendar = [NSCalendar currentCalendar]; 159 | 160 | //直接计算 161 | NSDateComponents *components = [calendar components:unit fromDate:fromDate toDate:toDate options:0]; 162 | 163 | return components; 164 | } 165 | 166 | /** 167 | *@Description:根据年份、月份、日期、小时数、分钟数、秒数返回NSDate 168 | *@Params: 169 | * year:年份 170 | * month:月份 171 | * day:日期 172 | * hour:小时数 173 | * minute:分钟数 174 | * second:秒数 175 | * @return: 176 | */ 177 | + (NSDate *)dateWithYear:(NSUInteger)year 178 | Month:(NSUInteger)month 179 | Day:(NSUInteger)day 180 | Hour:(NSUInteger)hour 181 | Minute:(NSUInteger)minute 182 | Second:(NSUInteger)second { 183 | NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond fromDate:[NSDate date]]; 184 | dateComponents.year = year; 185 | dateComponents.month = month; 186 | dateComponents.day = day; 187 | dateComponents.hour = hour; 188 | dateComponents.minute = minute; 189 | dateComponents.second = second; 190 | 191 | return [[NSCalendar currentCalendar] dateFromComponents:dateComponents]; 192 | } 193 | 194 | /** 195 | *@Description:实现dateFormatter单例方法 196 | *@Params:nil 197 | *Return:相应格式的NSDataFormatter对象 198 | */ 199 | + (NSDateFormatter *)defaultDateFormatterWithFormatYYYYMMddHHmmss { 200 | static NSDateFormatter *staticDateFormatterWithFormatYYYYMMddHHmmss; 201 | if (!staticDateFormatterWithFormatYYYYMMddHHmmss) { 202 | staticDateFormatterWithFormatYYYYMMddHHmmss = [[NSDateFormatter alloc] init]; 203 | [staticDateFormatterWithFormatYYYYMMddHHmmss setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; 204 | } 205 | 206 | return staticDateFormatterWithFormatYYYYMMddHHmmss; 207 | } 208 | 209 | + (NSDateFormatter *)defaultDateFormatterWithFormatYYYYMMdd { 210 | static NSDateFormatter *staticDateFormatterWithFormatYYYYMMddHHmmss; 211 | if (!staticDateFormatterWithFormatYYYYMMddHHmmss) { 212 | staticDateFormatterWithFormatYYYYMMddHHmmss = [[NSDateFormatter alloc] init]; 213 | [staticDateFormatterWithFormatYYYYMMddHHmmss setDateFormat:@"YYYY.MM.dd"]; 214 | } 215 | 216 | return staticDateFormatterWithFormatYYYYMMddHHmmss; 217 | } 218 | 219 | + (NSDateFormatter *)defaultDateFormatterWithFormatYYYYMMdd__ { 220 | static NSDateFormatter *staticDateFormatterWithFormatYYYYMMddHHmmss__; 221 | if (!staticDateFormatterWithFormatYYYYMMddHHmmss__) { 222 | staticDateFormatterWithFormatYYYYMMddHHmmss__ = [[NSDateFormatter alloc] init]; 223 | [staticDateFormatterWithFormatYYYYMMddHHmmss__ setDateFormat:@"YYYY-MM-dd"]; 224 | } 225 | 226 | return staticDateFormatterWithFormatYYYYMMddHHmmss__; 227 | } 228 | 229 | + (NSDateFormatter *)defaultDateFormatterWithFormatMMddHHmm { 230 | static NSDateFormatter *staticDateFormatterWithFormatMMddHHmm; 231 | if (!staticDateFormatterWithFormatMMddHHmm) { 232 | staticDateFormatterWithFormatMMddHHmm = [[NSDateFormatter alloc] init]; 233 | [staticDateFormatterWithFormatMMddHHmm setDateFormat:@"MM-dd HH:mm"]; 234 | } 235 | 236 | return staticDateFormatterWithFormatMMddHHmm; 237 | } 238 | 239 | + (NSDateFormatter *)defaultDateFormatterWithFormatHHmm { 240 | static NSDateFormatter *staticDateFormatterWithFormatHHmm; 241 | if (!staticDateFormatterWithFormatHHmm) { 242 | staticDateFormatterWithFormatHHmm = [[NSDateFormatter alloc] init]; 243 | [staticDateFormatterWithFormatHHmm setDateFormat:@"HH:mm"]; 244 | } 245 | 246 | return staticDateFormatterWithFormatHHmm; 247 | } 248 | 249 | + (NSDateFormatter *)defaultDateFormatterWithFormatYYYYMMddHHmmInChinese { 250 | static NSDateFormatter *staticDateFormatterWithFormatYYYYMMddHHmmssInChines; 251 | if (!staticDateFormatterWithFormatYYYYMMddHHmmssInChines) { 252 | staticDateFormatterWithFormatYYYYMMddHHmmssInChines = [[NSDateFormatter alloc] init]; 253 | [staticDateFormatterWithFormatYYYYMMddHHmmssInChines setDateFormat:@"YYYY年MM月dd日 HH:mm"]; 254 | } 255 | 256 | return staticDateFormatterWithFormatYYYYMMddHHmmssInChines; 257 | } 258 | 259 | + (NSDateFormatter *)defaultDateFormatterWithFormatMMddHHmmInChinese { 260 | static NSDateFormatter *staticDateFormatterWithFormatMMddHHmmInChinese; 261 | if (!staticDateFormatterWithFormatMMddHHmmInChinese) { 262 | staticDateFormatterWithFormatMMddHHmmInChinese = [[NSDateFormatter alloc] init]; 263 | [staticDateFormatterWithFormatMMddHHmmInChinese setDateFormat:@"MM月dd日 HH:mm"]; 264 | } 265 | 266 | return staticDateFormatterWithFormatMMddHHmmInChinese; 267 | } 268 | 269 | /********************************************************** 270 | *@Description:获取当天的包括“年”,“月”,“日”,“周”,“时”,“分”,“秒”的NSDateComponents 271 | *@Params:nil 272 | *@Return:当天的包括“年”,“月”,“日”,“周”,“时”,“分”,“秒”的NSDateComponents 273 | ***********************************************************/ 274 | - (NSDateComponents *)componentsOfDay { 275 | return [[NSCalendar currentCalendar] components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond fromDate:self]; 276 | } 277 | 278 | // --------------------------NSDate--------------------------- 279 | /**************************************************** 280 | *@Description:获得NSDate对应的年份 281 | *@Params:nil 282 | *@Return:NSDate对应的年份 283 | ****************************************************/ 284 | - (NSUInteger)year { 285 | return [self componentsOfDay].year; 286 | } 287 | 288 | /**************************************************** 289 | *@Description:获得NSDate对应的月份 290 | *@Params:nil 291 | *@Return:NSDate对应的月份 292 | ****************************************************/ 293 | - (NSUInteger)month { 294 | return [self componentsOfDay].month; 295 | } 296 | 297 | /**************************************************** 298 | *@Description:获得NSDate对应的日期 299 | *@Params:nil 300 | *@Return:NSDate对应的日期 301 | ****************************************************/ 302 | - (NSUInteger)day { 303 | return [self componentsOfDay].day; 304 | } 305 | 306 | /**************************************************** 307 | *@Description:获得NSDate对应的小时数 308 | *@Params:nil 309 | *@Return:NSDate对应的小时数 310 | ****************************************************/ 311 | - (NSUInteger)hour { 312 | return [self componentsOfDay].hour; 313 | } 314 | 315 | /**************************************************** 316 | *@Description:获得NSDate对应的分钟数 317 | *@Params:nil 318 | *@Return:NSDate对应的分钟数 319 | ****************************************************/ 320 | - (NSUInteger)minute { 321 | return [self componentsOfDay].minute; 322 | } 323 | 324 | /**************************************************** 325 | *@Description:获得NSDate对应的秒数 326 | *@Params:nil 327 | *@Return:NSDate对应的秒数 328 | ****************************************************/ 329 | - (NSUInteger)second { 330 | return [self componentsOfDay].second; 331 | } 332 | 333 | /**************************************************** 334 | *@Description:获得NSDate对应的星期 335 | *@Params:nil 336 | *@Return:NSDate对应的星期 337 | ****************************************************/ 338 | - (NSUInteger)weekday { 339 | return [self componentsOfDay].weekday; 340 | } 341 | 342 | /****************************************** 343 | *@Description:获取当天是当年的第几周 344 | *@Params:nil 345 | *@Return:当天是当年的第几周 346 | ******************************************/ 347 | - (NSUInteger)weekOfDayInYear { 348 | return [[NSCalendar currentCalendar] ordinalityOfUnit:NSCalendarUnitWeekOfYear inUnit:NSCalendarUnitYear forDate:self]; 349 | } 350 | 351 | /**************************************************** 352 | *@Description:获得一般当天的工作开始时间 353 | *@Params:nil 354 | *@Return:一般当天的工作开始时间 355 | ****************************************************/ 356 | - (NSDate *)workBeginTime { 357 | unsigned int flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; 358 | NSDateComponents *components = [[NSCalendar currentCalendar] components:flags fromDate:self]; 359 | [components setHour:9]; 360 | [components setMinute:30]; 361 | [components setSecond:0]; 362 | 363 | return [[NSCalendar currentCalendar] dateFromComponents:components]; 364 | } 365 | 366 | /**************************************************** 367 | *@Description:获得一般当天的工作结束时间 368 | *@Params:nil 369 | *@Return:一般当天的工作结束时间 370 | ****************************************************/ 371 | - (NSDate *)workEndTime { 372 | unsigned int flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; 373 | NSDateComponents *components = [[NSCalendar currentCalendar] components:flags fromDate:self]; 374 | [components setHour:18]; 375 | [components setMinute:0]; 376 | [components setSecond:0]; 377 | 378 | return [[NSCalendar currentCalendar] dateFromComponents:components]; 379 | } 380 | 381 | /**************************************************** 382 | *@Description:获取一小时后的时间 383 | *@Params:nil 384 | *@Return:一小时后的时间 385 | ****************************************************/ 386 | - (NSDate *)oneHourLater { 387 | return [NSDate dateWithTimeInterval:3600 sinceDate:self]; 388 | } 389 | 390 | /**************************************************** 391 | *@Description:获得某一天的这个时刻 392 | *@Params:nil 393 | *@Return:某一天的这个时刻 394 | ****************************************************/ 395 | - (NSDate *)sameTimeOfDate { 396 | unsigned int flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; 397 | NSDateComponents *components = [[NSCalendar currentCalendar] components:flags fromDate:self]; 398 | [components setHour:[[NSDate date] hour]]; 399 | [components setMinute:[[NSDate date] minute]]; 400 | [components setSecond:[[NSDate date] second]]; 401 | 402 | return [[NSCalendar currentCalendar] dateFromComponents:components]; 403 | } 404 | 405 | /****************************************** 406 | *@Description:判断与某一天是否为同一天 407 | *@Params: 408 | * otherDate:某一天 409 | *@Return:YES-同一天;NO-不同一天 410 | ******************************************/ 411 | - (BOOL)sameDayWithDate:(NSDate *)otherDate { 412 | if (self.year == otherDate.year && self.month == otherDate.month && self.day == otherDate.day) { 413 | return YES; 414 | } else { 415 | return NO; 416 | } 417 | } 418 | 419 | /****************************************** 420 | *@Description:判断与某一天是否为同一周 421 | *@Params: 422 | * otherDate:某一天 423 | *@Return:YES-同一周;NO-不同一周 424 | ******************************************/ 425 | - (BOOL)sameWeekWithDate:(NSDate *)otherDate { 426 | if (self.year == otherDate.year && self.month == otherDate.month && self.weekOfDayInYear == otherDate.weekOfDayInYear) { 427 | return YES; 428 | } else { 429 | return NO; 430 | } 431 | } 432 | 433 | /****************************************** 434 | *@Description:判断与某一天是否为同一月 435 | *@Params: 436 | * otherDate:某一天 437 | *@Return:YES-同一月;NO-不同一月 438 | ******************************************/ 439 | - (BOOL)sameMonthWithDate:(NSDate *)otherDate { 440 | if (self.year == otherDate.year && self.month == otherDate.month) { 441 | return YES; 442 | } else { 443 | return NO; 444 | } 445 | } 446 | 447 | /** 多久以前呢 ? 1分钟内 X分钟前 X天前 */ 448 | - (NSString *)whatTimeAgo { 449 | if (self == nil) { 450 | return @""; 451 | } 452 | NSTimeInterval timeInterval = -[self timeIntervalSinceNow]; 453 | long temp = 0; 454 | NSString *result; 455 | if (timeInterval < 60) { 456 | result = [NSString stringWithFormat:@"1分钟内"]; 457 | } else if ((temp = timeInterval / 60) < 60) { 458 | result = [NSString stringWithFormat:@"%ld分钟前", temp]; 459 | } else if ((temp = temp / 60) < 24) { 460 | result = [NSString stringWithFormat:@"%ld小时前", temp]; 461 | } else if ((temp = temp / 24) < 30) { 462 | result = [NSString stringWithFormat:@"%ld天前", temp]; 463 | } else if ((temp = temp / 30) < 12) { 464 | result = [NSString stringWithFormat:@"%ld个月前", temp]; 465 | } else { 466 | temp = temp / 12; 467 | result = [NSString stringWithFormat:@"%ld年前", temp]; 468 | } 469 | return result; 470 | } 471 | 472 | //凌晨(3:00—6:00) 早上(6:00—8:00) 上午(8:00—11:00) 中午(11:00—14:00) 下午(14:00—19:00) 晚上(19:00—24:00) 深夜0:00—3:00) JE准则 473 | /** 前段时间日期的描述 上午?? 星期二 下午?? */ 474 | - (NSString *)whatTimeBefore { 475 | if (self == nil) { 476 | return @""; 477 | } 478 | NSDate *yesterday = [[NSDate date] dateByAddingTimeInterval:-(24 * 60 * 60)]; 479 | 480 | NSCalendar *calendar = [NSCalendar currentCalendar]; 481 | NSUInteger unitFlags = /*NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitHour |NSCalendarUnitMinute | */ NSCalendarUnitDay; 482 | NSDateComponents *Compareday = [calendar components:unitFlags fromDate:self]; 483 | NSDateComponents *Yesterday = [calendar components:unitFlags fromDate:yesterday]; 484 | NSDateComponents *Today = [calendar components:unitFlags fromDate:[NSDate date]]; 485 | 486 | NSDateFormatter *F_Mon_Day = [[NSDateFormatter alloc] init]; 487 | [F_Mon_Day setDateFormat:@"MM-dd"]; 488 | NSDateFormatter *F_H_M = [[NSDateFormatter alloc] init]; 489 | [F_H_M setDateFormat:@"HH:mm"]; 490 | NSString *S_H = [[F_H_M stringFromDate:self] substringWithRange:NSMakeRange(0, 2)]; 491 | NSString *S_M = [[F_H_M stringFromDate:self] substringWithRange:NSMakeRange(3, 2)]; 492 | NSString *sunormoon = @""; 493 | NSInteger Hour = [S_H integerValue]; 494 | 495 | if (Hour >= 3 && Hour < 6) { 496 | sunormoon = @"凌晨"; 497 | } else if (Hour >= 6 && Hour < 8) { 498 | sunormoon = @"早上"; 499 | } else if (Hour >= 8 && Hour < 11) { 500 | sunormoon = @"上午"; 501 | } else if (Hour >= 11 && Hour < 14) { 502 | sunormoon = @"中午"; 503 | } else if (Hour >= 14 && Hour < 19) { 504 | sunormoon = @"下午"; 505 | } else if (Hour >= 19 /*&& Hour < 23*/) { 506 | sunormoon = @"晚上"; 507 | } else if (Hour >= 0 && Hour < 3) { 508 | sunormoon = @"深夜"; 509 | } 510 | 511 | if (Hour > 12) { 512 | Hour = Hour - 12; 513 | } 514 | 515 | NSString *Mon_Day = [F_Mon_Day stringFromDate:self]; 516 | NSString *Hou_Min = [NSString stringWithFormat:@"%@ %d:%@", sunormoon, (int) Hour, S_M]; 517 | NSString *Week = [self whatDayTheWeek]; 518 | NSTimeInterval oldtime = [self timeIntervalSince1970]; 519 | NSTimeInterval nowTime = [[NSDate date] timeIntervalSince1970]; 520 | 521 | if ([[[NSCalendar autoupdatingCurrentCalendar] components:NSCalendarUnitYear fromDate:self] year] != [[[NSCalendar autoupdatingCurrentCalendar] components:NSCalendarUnitYear fromDate:[NSDate date]] year]) { 522 | [F_Mon_Day setDateFormat:@"YYYY-MM-dd"]; 523 | Mon_Day = [F_Mon_Day stringFromDate:self]; 524 | } 525 | 526 | if ([Today day] == [Compareday day]) { 527 | return [NSString stringWithFormat:@"%@", Hou_Min]; 528 | } 529 | 530 | if ([Yesterday day] == [Compareday day]) { 531 | return [NSString stringWithFormat:@"昨天 %@", Hou_Min]; 532 | } 533 | 534 | if ((nowTime - oldtime) / 60 / 60 / 24 >= 7) { 535 | return [NSString stringWithFormat:@"%@ %@", Mon_Day, Hou_Min]; 536 | } 537 | 538 | if ((nowTime - oldtime) / 60 / 60 / 24 < 7) { 539 | return [NSString stringWithFormat:@"%@ %@", Week, Hou_Min]; 540 | } 541 | 542 | return [NSString stringWithFormat:@"%@ %@", Mon_Day, Hou_Min]; 543 | } 544 | 545 | /** 546 | * 今天星期几来着? 547 | */ 548 | - (NSString *)whatDayTheWeek { 549 | NSDateComponents *componets = [[NSCalendar autoupdatingCurrentCalendar] components:NSCalendarUnitWeekday fromDate:self]; 550 | int weekday = (int) [componets weekday]; //a就是星期几,1代表星期日,2代表星期一,后面依次 551 | switch (weekday) { 552 | case 1: 553 | return @"星期日"; 554 | break; 555 | case 2: 556 | return @"星期一"; 557 | break; 558 | case 3: 559 | return @"星期二"; 560 | break; 561 | case 4: 562 | return @"星期三"; 563 | break; 564 | case 5: 565 | return @"星期四"; 566 | break; 567 | case 6: 568 | return @"星期五"; 569 | break; 570 | case 7: 571 | return @"星期六"; 572 | break; 573 | 574 | default: 575 | break; 576 | } 577 | 578 | return @""; 579 | } 580 | 581 | /**************************************************** 582 | *@Description:获取时间的字符串格式 583 | *@Params:nil 584 | *@Return:时间的字符串格式 585 | ****************************************************/ 586 | - (NSString *)WT_YYYYMMddHHmmss { 587 | return [[NSDate defaultDateFormatterWithFormatYYYYMMddHHmmss] stringFromDate:self]; 588 | } 589 | 590 | - (NSString *)WT_YYYYMMdd { 591 | return [[NSDate defaultDateFormatterWithFormatYYYYMMdd] stringFromDate:self]; 592 | } 593 | - (NSString *)WT_YYYYMMdd__ { 594 | return [[NSDate defaultDateFormatterWithFormatYYYYMMdd__] stringFromDate:self]; 595 | } 596 | - (NSString *)MMddHHmm { 597 | return [[NSDate defaultDateFormatterWithFormatMMddHHmm] stringFromDate:self]; 598 | } 599 | 600 | - (NSString *)WT_HHmm { 601 | return [[NSDate defaultDateFormatterWithFormatHHmm] stringFromDate:self]; 602 | } 603 | 604 | - (NSString *)YYYYMMddHHmmInChinese { 605 | return [[NSDate defaultDateFormatterWithFormatYYYYMMddHHmmInChinese] stringFromDate:self]; 606 | } 607 | 608 | - (NSString *)MMddHHmmInChinese { 609 | return [[NSDate defaultDateFormatterWithFormatMMddHHmmInChinese] stringFromDate:self]; 610 | } 611 | 612 | @end 613 | -------------------------------------------------------------------------------- /WTSDK/Category/NS/NSString+WT.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // NSString+WT.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface NSDictionary (WT) 13 | /** 字典 转为 jsonStr */ 14 | @property (nonatomic, copy, readonly) NSString *jsonStr; 15 | 16 | @end 17 | 18 | @interface NSString (WT) 19 | // 😀😉😌😰😂 Emoji start 20 | /** 21 | * 将十六进制的编码转为emoji字符 22 | */ 23 | + (NSString *)emojiWithIntCode:(int)intCode; 24 | 25 | /** 26 | * 将十六进制的编码转为emoji字符 27 | */ 28 | + (NSString *)emojiWithStringCode:(NSString *)stringCode; 29 | - (NSString *)emoji; 30 | 31 | /** 32 | * 是否为emoji字符 33 | */ 34 | - (BOOL)isEmoji; 35 | /** 去掉 表情符号 可能漏了一些 */ 36 | - (NSString *)disableEmoji; 37 | // 😀😉😌😰😂 Emoji end 38 | 39 | /** 去空格 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; */ 40 | @property (nonatomic, copy, readonly) NSString *delBlank; 41 | 42 | /** 去空格 stringByReplacingOccurrencesOfString:@" " withString:@"" */ 43 | @property (nonatomic, copy, readonly) NSString *delSpace; 44 | 45 | /** 长时间戳对应的NSDate */ 46 | @property (nonatomic, strong, readonly) NSDate *date; 47 | 48 | /** YYYY-MM-dd 对应的NSDate */ 49 | @property (nonatomic, strong, readonly) NSDate *date__YMd; 50 | 51 | /** YYYY.MM.dd 对应的NSDate */ 52 | @property (nonatomic, strong, readonly) NSDate *date__YMd_Dot; 53 | 54 | /** YYYY-MM-dd HH:mm:ss对应的NSDate */ 55 | @property (nonatomic, strong, readonly) NSDate *date__YMdHMS; 56 | 57 | /** 转为 Data */ 58 | @property (nonatomic, copy, readonly) NSData *data; 59 | 60 | /** 转为 base64string后的Data */ 61 | @property (nonatomic, copy, readonly) NSData *base64Data; 62 | 63 | /** 转为 base64String */ 64 | @property (nonatomic, copy, readonly) NSString *base64Str; 65 | 66 | /** 解 base64str 为 Str 解不了就返回原始的数值 */ 67 | @property (nonatomic, copy, readonly) NSString *decodeBase64; 68 | 69 | /** 解 为字典 if 有 */ 70 | @property (nonatomic, strong, readonly) NSDictionary *jsonDic; 71 | 72 | /** 解 为数组 if 有 */ 73 | @property (nonatomic, strong, readonly) NSArray *jsonArr; 74 | 75 | /** 按字符串的,逗号分割为数组 */ 76 | @property (nonatomic, strong, readonly) NSArray *combinArr; 77 | 78 | /** 32位MD5加密 */ 79 | @property (nonatomic, copy, readonly) NSString *MD5; 80 | /** SHA1加密 */ 81 | @property (nonatomic, copy, readonly) NSString *SHA1; 82 | 83 | /** URLencode */ 84 | @property (nonatomic, copy, readonly) NSString *encodeString; 85 | /** URLdecode */ 86 | @property (nonatomic, copy, readonly) NSString *decodeString; 87 | 88 | #pragma mark - function😂 89 | /** 适合的高度 默认 font 宽 */ 90 | - (CGFloat)heightWithFont:(NSInteger)font w:(CGFloat)w; 91 | 92 | /** 适合的宽度 默认 font 高 */ 93 | - (CGFloat)widthWithFont:(NSInteger)font h:(CGFloat)h; 94 | 95 | /** 根据字体大小与最大宽度 返回对应的size*/ 96 | - (CGSize)sizeWithFont:(UIFont *)font maxW:(CGFloat)maxW; 97 | /** 计算富(有间距)文本的NSString高度 */ 98 | - (CGFloat)sizeWithFont:(UIFont *)font maxW:(CGFloat)maxW lineSpacing:(NSInteger)lineSpacing; 99 | /** 根据字体大小 返回对应的size*/ 100 | - (CGSize)sizeWithFont:(UIFont *)font; 101 | 102 | /** 是否包含对应字符 */ 103 | - (BOOL)containStr:(NSString *)subString; 104 | 105 | /** 拼上字符串 */ 106 | - (NSString *)addStr:(NSString *)string; 107 | 108 | /** 拼上int字符串 */ 109 | - (NSString *)addInt:(int)string; 110 | 111 | /** 二维码图片 可以 再用resize>>放大一下 */ 112 | - (UIImage *)qrCode; 113 | 114 | /** 是否中文 */ 115 | - (BOOL)isChinese; 116 | 117 | /** 计算字符串长度 1个中文算2 个字符 */ 118 | - (int)textLength; 119 | 120 | /** 限制的最大显示长度字符 */ 121 | - (NSString *)limitMaxTextShow:(NSInteger)limit; 122 | 123 | /** 验证邮箱是否合法 */ 124 | - (BOOL)validateEmail; 125 | 126 | /** 验证手机号码合法性 */ 127 | - (BOOL)checkPhoneNumInput; 128 | 129 | /** 是否ASCII码 */ 130 | - (BOOL)isASCII; 131 | 132 | /** 是含本方法定义的 “特殊字符” */ 133 | - (BOOL)isSpecialCharacter; 134 | 135 | /** 验证是否是数字 */ 136 | - (BOOL)isNumber; 137 | 138 | /** 是否是纯浮点数 这里也可以拆分成纯数字判断*/ 139 | - (BOOL)isFloat; 140 | 141 | /** 验证字符串里面是否都是数字*/ 142 | - (BOOL)isPureNumber; 143 | /** 获取UUID */ 144 | + (NSString *)UUID; 145 | 146 | @end 147 | -------------------------------------------------------------------------------- /WTSDK/Category/NS/NSString+WT.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // NSString+WT.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "NSString+WT.h" 10 | #import 11 | #define EmojiCodeToSymbol(c) ((((0x808080F0 | (c & 0x3F000) >> 4) | (c & 0xFC0) << 10) | (c & 0x1C0000) << 18) | (c & 0x3F) << 24) 12 | @implementation NSString (WT) 13 | // 😀😉😌😰😂 Emoji start 14 | + (NSString *)emojiWithIntCode:(int)intCode { 15 | int symbol = EmojiCodeToSymbol(intCode); 16 | NSString *string = [[NSString alloc] initWithBytes:&symbol length:sizeof(symbol) encoding:NSUTF8StringEncoding]; 17 | if (string == nil) { // 新版Emoji 18 | string = [NSString stringWithFormat:@"%C", (unichar) intCode]; 19 | } 20 | return string; 21 | } 22 | 23 | - (NSString *)emoji { 24 | return [NSString emojiWithStringCode:self]; 25 | } 26 | 27 | + (NSString *)emojiWithStringCode:(NSString *)stringCode { 28 | char *charCode = (char *) stringCode.UTF8String; 29 | int intCode = (int) strtol(charCode, NULL, 16); 30 | return [self emojiWithIntCode:intCode]; 31 | } 32 | 33 | // 判断是否是 emoji表情 34 | - (BOOL)isEmoji { 35 | BOOL returnValue = NO; 36 | 37 | const unichar hs = [self characterAtIndex:0]; 38 | // surrogate pair 39 | if (0xd800 <= hs && hs <= 0xdbff) { 40 | if (self.length > 1) { 41 | const unichar ls = [self characterAtIndex:1]; 42 | const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000; 43 | if (0x1d000 <= uc && uc <= 0x1f77f) { 44 | returnValue = YES; 45 | } 46 | } 47 | } else if (self.length > 1) { 48 | const unichar ls = [self characterAtIndex:1]; 49 | if (ls == 0x20e3) { 50 | returnValue = YES; 51 | } 52 | } else { 53 | // non surrogate 54 | if (0x2100 <= hs && hs <= 0x27ff) { 55 | returnValue = YES; 56 | } else if (0x2B05 <= hs && hs <= 0x2b07) { 57 | returnValue = YES; 58 | } else if (0x2934 <= hs && hs <= 0x2935) { 59 | returnValue = YES; 60 | } else if (0x3297 <= hs && hs <= 0x3299) { 61 | returnValue = YES; 62 | } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) { 63 | returnValue = YES; 64 | } 65 | } 66 | 67 | return returnValue; 68 | } 69 | // 😀😉😌😰😂 Emoji end 70 | 71 | /** 72 | * 得到文字和字体就能计算文字尺寸 73 | * 74 | * @param text 需要计算尺寸的文字 75 | * @param font 文字的字体 76 | * @param maxW 最大的宽度 77 | * 78 | * @return 79 | */ 80 | - (CGSize)sizeWithFont:(UIFont *)font maxW:(CGFloat)maxW { 81 | NSMutableDictionary *attrs = [NSMutableDictionary dictionary]; 82 | attrs[NSFontAttributeName] = font; 83 | CGSize maxSize = CGSizeMake(maxW, MAXFLOAT); 84 | 85 | NSLog(@"IOS7以上的系统"); 86 | return [self boundingRectWithSize:maxSize options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesFontLeading |NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size; 87 | } 88 | 89 | /** 计算富(有间距)文本的NSString高度 */ 90 | - (CGFloat)sizeWithFont:(UIFont *)font maxW:(CGFloat)maxW lineSpacing:(NSInteger)lineSpacing{ 91 | NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 92 | [paragraphStyle setLineSpacing:lineSpacing]; 93 | NSDictionary *attributeDict = [NSDictionary dictionaryWithObjectsAndKeys: 94 | font,NSFontAttributeName, 95 | paragraphStyle,NSParagraphStyleAttributeName,nil]; 96 | CGRect rect = [self boundingRectWithSize:CGSizeMake(maxW, MAXFLOAT)//限制最大的宽度和高度 97 | options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesFontLeading |NSStringDrawingUsesLineFragmentOrigin//采用换行模式 98 | attributes:attributeDict//传入的字体字典 99 | context:nil]; 100 | 101 | return rect.size.height; 102 | } 103 | 104 | 105 | - (CGSize)sizeWithFont:(UIFont *)font { 106 | return [self sizeWithFont:font maxW:MAXFLOAT]; 107 | } 108 | 109 | //适合的高度 默认 systemFontOfSize:font 110 | - (CGFloat)heightWithFont:(NSInteger)font w:(CGFloat)w { 111 | return [self boundingRectWithSize:CGSizeMake(w, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName : [UIFont systemFontOfSize:font] } context:nil].size.height; 112 | } 113 | 114 | //适合的宽度 默认 systemFontOfSize:font 115 | - (CGFloat)widthWithFont:(NSInteger)font h:(CGFloat)h { 116 | return [self boundingRectWithSize:CGSizeMake(MAXFLOAT, h) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{ NSFontAttributeName : [UIFont systemFontOfSize:font] } context:nil].size.width; 117 | } 118 | 119 | //去空格 120 | - (NSString *)delSpace { 121 | return [self stringByReplacingOccurrencesOfString:@" " withString:@""]; 122 | } 123 | //去空格 124 | - (NSString *)delBlank { 125 | return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 126 | } 127 | 128 | //时间戳对应的NSDate 129 | - (NSDate *)date { 130 | return [NSDate dateWithTimeIntervalSince1970:self.floatValue]; 131 | } 132 | 133 | static NSDateFormatter *YYYYMMddHHmmss; 134 | //YYYY-MM-dd HH:mm:ss对应的NSDate 135 | - (NSDate *)date__YMdHMS { 136 | if (!YYYYMMddHHmmss) { 137 | YYYYMMddHHmmss = [[NSDateFormatter alloc] init]; 138 | [YYYYMMddHHmmss setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; 139 | } 140 | return [YYYYMMddHHmmss dateFromString:self]; 141 | } 142 | 143 | static NSDateFormatter *YYYYMMdd; 144 | //YYYY-MM-dd 对应的NSDate 145 | - (NSDate *)date__YMd { 146 | if (!YYYYMMdd) { 147 | YYYYMMdd = [[NSDateFormatter alloc] init]; 148 | [YYYYMMdd setDateFormat:@"YYYY-MM-dd"]; 149 | } 150 | return [YYYYMMdd dateFromString:self]; 151 | } 152 | static NSDateFormatter *YYYYMMddDot; 153 | - (NSDate *)date__YMd_Dot { 154 | if (!YYYYMMddDot) { 155 | YYYYMMddDot = [[NSDateFormatter alloc] init]; 156 | [YYYYMMddDot setDateFormat:@"YYYY.MM.dd"]; 157 | } 158 | return [YYYYMMddDot dateFromString:self]; 159 | } 160 | 161 | //转为 Data 162 | - (NSData *)data { 163 | return [self dataUsingEncoding:NSUTF8StringEncoding]; 164 | } 165 | //转为 base64string后的Data 166 | - (NSData *)base64Data { 167 | return [[NSData alloc] initWithBase64EncodedString:self options:0]; 168 | } 169 | // 转为 base64String 170 | - (NSString *)base64Str { 171 | return [[self dataUsingEncoding:NSUTF8StringEncoding] base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]; 172 | } 173 | //解 base64为Str 解不了就返回原始的数值 174 | - (NSString *)decodeBase64 { 175 | NSString *WillDecode = [[NSString alloc] initWithData:[[NSData alloc] initWithBase64EncodedString:self options:0] encoding:NSUTF8StringEncoding]; 176 | return (WillDecode.length != 0) ? WillDecode : self; 177 | } 178 | // 解 为字典 if 有 179 | - (NSDictionary *)jsonDic { 180 | return [NSJSONSerialization JSONObjectWithData:self.data options:NSJSONReadingMutableContainers error:nil]; 181 | } 182 | // 解 为数组 if 有 183 | - (NSArray *)jsonArr { 184 | return [NSJSONSerialization JSONObjectWithData:self.data options:NSJSONReadingMutableContainers error:nil]; 185 | } 186 | //按字符串的,逗号分割为数组 187 | - (NSArray *)combinArr { 188 | if ([self hasSuffix:@","]) { 189 | return [[self substringToIndex:self.length - 1] componentsSeparatedByString:@","]; 190 | } 191 | return [self componentsSeparatedByString:@","]; 192 | } 193 | 194 | #pragma mark - 195 | 196 | //是否包含对应字符 197 | - (BOOL)containStr:(NSString *)subString { 198 | return ([self rangeOfString:subString].location == NSNotFound) ? NO : YES; 199 | } 200 | //拼上字符串 201 | - (NSString *)addStr:(NSString *)string { 202 | if (!string || string.length == 0) { 203 | return self; 204 | } 205 | return [self stringByAppendingString:string]; 206 | } 207 | - (NSString *)addInt:(int)string { 208 | return [self stringByAppendingString:@(string).stringValue]; 209 | } 210 | //32位MD5加密 211 | - (NSString *)MD5 { 212 | const char *cStr = [self UTF8String]; 213 | unsigned char digest[CC_MD5_DIGEST_LENGTH]; 214 | CC_MD5(cStr, (CC_LONG) strlen(cStr), digest); 215 | NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2]; 216 | for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) { 217 | [result appendFormat:@"%02x", digest[i]]; 218 | } 219 | return [result copy]; 220 | } 221 | //SHA1加密 222 | - (NSString *)SHA1 { 223 | const char *cStr = [self UTF8String]; 224 | NSData *data = [NSData dataWithBytes:cStr length:self.length]; 225 | uint8_t digest[CC_SHA1_DIGEST_LENGTH]; 226 | CC_SHA1(data.bytes, (CC_LONG) data.length, digest); 227 | NSMutableString *result = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2]; 228 | for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) { 229 | [result appendFormat:@"%02x", digest[i]]; 230 | } 231 | return [result copy]; 232 | } 233 | 234 | 235 | 236 | -(NSString*)encodeString{ 237 | 238 | // CharactersToBeEscaped = @":/?&=;+!@#$()~',*"; 239 | // CharactersToLeaveUnescaped = @"[]."; 240 | 241 | NSString *encodedString = (NSString *) 242 | CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, 243 | (CFStringRef)self, 244 | NULL, 245 | (CFStringRef)@"!*'();:@&=+$,/?%#[]", 246 | kCFStringEncodingUTF8)); 247 | 248 | return encodedString; 249 | } 250 | 251 | //URLDEcode 252 | -(NSString *)decodeString 253 | 254 | { 255 | //NSString *decodedString = [encodedString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding ]; 256 | 257 | NSString *decodedString = (__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, 258 | (__bridge CFStringRef)self, 259 | CFSTR(""), 260 | CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding)); 261 | return decodedString; 262 | } 263 | 264 | 265 | 266 | 267 | - (UIImage *)qrCode { 268 | CIFilter *filter = [CIFilter filterWithName:@"CIQRCodeGenerator"]; 269 | 270 | // NSLog(@"filterAttributes:%@", filter.attributes); 271 | 272 | [filter setDefaults]; 273 | 274 | NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding]; 275 | [filter setValue:data forKey:@"inputMessage"]; 276 | 277 | CIImage *outputImage = [filter outputImage]; 278 | 279 | CIContext *context1 = [CIContext contextWithOptions:nil]; 280 | CGImageRef cgImage = [context1 createCGImage:outputImage 281 | fromRect:[outputImage extent]]; 282 | 283 | UIImage *image = [UIImage imageWithCGImage:cgImage 284 | scale:1 285 | orientation:UIImageOrientationUp]; 286 | 287 | // CGFloat width = image.size.width * resize; 288 | // CGFloat height = image.size.height * resize; 289 | // 290 | // UIGraphicsBeginImageContext(CGSizeMake(width, height)); 291 | // CGContextRef context2 = UIGraphicsGetCurrentContext(); 292 | // CGContextSetInterpolationQuality(context2, kCGInterpolationNone); 293 | // [image drawInRect:CGRectMake(0, 0, width, height)]; 294 | // image = UIGraphicsGetImageFromCurrentImageContext(); 295 | // UIGraphicsEndImageContext(); 296 | 297 | CGImageRelease(cgImage); 298 | return image; 299 | } 300 | 301 | #pragma mark - 302 | 303 | //是否中文 304 | - (BOOL)isChinese { 305 | NSString *match = @"(^[\u4e00-\u9fa5]+$)"; 306 | NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF matches %@", match]; 307 | return [predicate evaluateWithObject:self]; 308 | } 309 | //计算字符串长度 1中文2字符 310 | - (int)textLength { 311 | float number = 0.0; 312 | for (int index = 0; index < [self length]; index++) { 313 | NSString *character = [self substringWithRange:NSMakeRange(index, 1)]; 314 | if ([character lengthOfBytesUsingEncoding:NSUTF8StringEncoding] == 3) { 315 | number = number + 2; 316 | } else { 317 | number = number + 1; 318 | } 319 | } 320 | return ceil(number); 321 | } 322 | //限制最大显示长度 323 | - (NSString *)limitMaxTextShow:(NSInteger)limit { 324 | NSString *Orgin = [self copy]; 325 | for (NSInteger i = Orgin.length; i > 0; i--) { 326 | NSString *Get = [Orgin substringToIndex:i]; 327 | if (Get.textLength <= limit) { 328 | return Get; 329 | } 330 | } 331 | return self; 332 | } 333 | 334 | //邮箱格式验证 335 | - (BOOL)validateEmail { 336 | NSString *emailRegex = @"\\b([a-zA-Z0-9%_.+\\-]+)@([a-zA-Z0-9.\\-]+?\\.[a-zA-Z]{2,6})\\b"; 337 | NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex]; 338 | return [emailTest evaluateWithObject:self]; 339 | } 340 | 341 | //手机号格式验证 342 | - (BOOL)checkPhoneNumInput { 343 | NSString *Phoneend = [self stringByReplacingOccurrencesOfString:@" " withString:@""]; 344 | if ([Phoneend hasPrefix:@"1"] && Phoneend.textLength == 11) { 345 | return YES; 346 | } 347 | return NO; 348 | // NSString * MOBILE = @"^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$"; 349 | // NSString * CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$"; 350 | // NSString * CU = @"^1(3[0-2]|5[256]|8[56])\\d{8}$"; 351 | // NSString * CT = @"^1((33|53|8[09])[0-9]|349)\\d{7}$"; 352 | // // NSString * PHS = @"^0(10|2[0-5789]|\\d{3})\\d{7,8}$"; 353 | // 354 | // NSString *phoneRegex = @"^((13[0-9])|(15[0-9])|(18[0,0-9]))\\d{8}$"; 355 | // NSString *Phoneend = [self stringByReplacingOccurrencesOfString:@" " withString:@""]; 356 | // 357 | // NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE]; 358 | // NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM]; 359 | // NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU]; 360 | // NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT]; 361 | // NSPredicate *regextestphoneRegex = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", phoneRegex]; 362 | // BOOL res1 = [regextestmobile evaluateWithObject:Phoneend]; 363 | // BOOL res2 = [regextestcm evaluateWithObject:Phoneend]; 364 | // BOOL res3 = [regextestcu evaluateWithObject:Phoneend]; 365 | // BOOL res4 = [regextestct evaluateWithObject:Phoneend]; 366 | // 367 | // BOOL res5 = [regextestphoneRegex evaluateWithObject:Phoneend]; 368 | // 369 | // if (res1 || res2 || res3 || res4 || res5 ) 370 | // { 371 | // return YES; 372 | // } 373 | // else 374 | // { 375 | // return NO; 376 | // } 377 | } 378 | 379 | //验证是否ASCII码 380 | - (BOOL)isASCII { 381 | NSCharacterSet *cs; 382 | cs = [NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@/:;()¥「」!,.?<>£"、[]{}#%-*+=_\\|~<>$€^•'@#$%^&*()_+'\"/" 383 | ""]; 384 | NSRange specialrang = [self rangeOfCharacterFromSet:cs]; 385 | if (specialrang.location != NSNotFound) { 386 | return YES; 387 | } 388 | return NO; 389 | } 390 | 391 | //验证是含本方法定义的 “特殊字符” 392 | - (BOOL)isSpecialCharacter { 393 | NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"@/:;()¥「」!,.?<>£"、[]{}#%-*+=_\\|~<>$€^•'@#$%^&*()_+'\"/" 394 | ""]; 395 | NSRange specialrang = [self rangeOfCharacterFromSet:set]; 396 | if (specialrang.location != NSNotFound) { 397 | return YES; 398 | } 399 | return NO; 400 | } 401 | 402 | // 验证是否是数字 403 | - (BOOL)isNumber { 404 | NSCharacterSet *cs; 405 | cs = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"]; 406 | NSRange specialrang = [self rangeOfCharacterFromSet:cs]; 407 | if (specialrang.location != NSNotFound) { 408 | return YES; 409 | } 410 | return NO; 411 | } 412 | 413 | // 验证字符串里面是否都是数字 414 | - (BOOL)isPureNumber { 415 | NSUInteger length = [self length]; 416 | for (float i = 0; i < length; i++) { 417 | // NSString * c=[mytimestr characterAtIndex:i]; 418 | NSString *STR = [self substringWithRange:NSMakeRange(i, 1)]; 419 | NSLog(@"%@", STR); 420 | if ([STR isNumber]) { 421 | continue; 422 | } else { 423 | return NO; 424 | } 425 | } 426 | return YES; 427 | } 428 | 429 | //是否是纯数字 这里可以有小数点 430 | - (BOOL)isFloat { 431 | NSUInteger length = [self length]; 432 | for (float i = 0; i < length; i++) { 433 | // NSString * c=[mytimestr characterAtIndex:i]; 434 | NSString *STR = [self substringWithRange:NSMakeRange(i, 1)]; 435 | NSLog(@"%@", STR); 436 | if ([STR isNumber] || [STR isEqualToString:@"."]) { 437 | continue; 438 | } else { 439 | return NO; 440 | } 441 | } 442 | return YES; 443 | } 444 | 445 | //去掉 表情符号 446 | - (NSString *)disableEmoji { 447 | NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^\\u0020-\\u007E\\u00A0-\\u00BE\\u2E80-\\uA4CF\\uF900-\\uFAFF\\uFE30-\\uFE4F\\uFF00-\\uFFEF\\u0080-\\u009F\\u2000-\\u201f\r\n]" options:NSRegularExpressionCaseInsensitive error:nil]; 448 | NSString *modifiedString = [regex stringByReplacingMatchesInString:self 449 | options:0 450 | range:NSMakeRange(0, [self length]) 451 | withTemplate:@""]; 452 | return modifiedString; 453 | } 454 | 455 | + (NSString *)UUID { 456 | CFUUIDRef uuidRef = CFUUIDCreate(NULL); 457 | CFStringRef uuid = CFUUIDCreateString(NULL, uuidRef); 458 | 459 | CFRelease(uuidRef); 460 | 461 | return (__bridge_transfer NSString *) uuid; 462 | } 463 | 464 | @end 465 | 466 | @implementation NSDictionary (WT) 467 | 468 | //字典 转为 JsonStr 469 | - (NSString *)jsonStr { 470 | return [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:self options:0 error:NULL] encoding:NSUTF8StringEncoding]; 471 | } 472 | 473 | @end 474 | -------------------------------------------------------------------------------- /WTSDK/Category/NS/NSTimer+WT.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // NSTimer+WT.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSTimer (WT) 12 | //而scheduled的初始化方法将以默认mode直接添加到当前的runloop中. 13 | + (id)runTimer:(NSTimeInterval)inTimeInterval block:(void (^)())inBlock rep:(BOOL)inRepeats; 14 | //不用scheduled方式初始化的,需要手动addTimer:forMode: 将timer添加到一个runloop中。 [[NSRunLoop currentRunLoop]addTimer:he forMode:NSDefaultRunLoopMode]; 15 | + (id)timerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)())inBlock repeats:(BOOL)inRepeats; 16 | 17 | /** 18 | * 暂停 19 | */ 20 | - (void)pause; 21 | /** 22 | * 继续 23 | */ 24 | - (void)goOn; 25 | /** 26 | * X秒后继续 27 | */ 28 | - (void)goOn:(NSTimeInterval)interval; 29 | @end 30 | -------------------------------------------------------------------------------- /WTSDK/Category/NS/NSTimer+WT.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // NSTimer+WT.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "NSTimer+WT.h" 10 | 11 | @implementation NSTimer (WT) 12 | //而scheduled的初始化方法将以默认mode直接添加到当前的runloop中. 13 | + (id)runTimer:(NSTimeInterval)inTimeInterval block:(void (^)())inBlock rep:(BOOL)inRepeats { 14 | void (^block)() = [inBlock copy]; 15 | id ret = [self scheduledTimerWithTimeInterval:inTimeInterval target:self selector:@selector(jdExecuteSimpleBlock:) userInfo:block repeats:inRepeats]; 16 | return ret; 17 | } 18 | //不用scheduled方式初始化的,需要手动addTimer:forMode: 将timer添加到一个runloop中。 [[NSRunLoop currentRunLoop]addTimer:he forMode:NSDefaultRunLoopMode]; 19 | + (id)timerWithTimeInterval:(NSTimeInterval)inTimeInterval block:(void (^)())inBlock repeats:(BOOL)inRepeats { 20 | void (^block)() = [inBlock copy]; 21 | id ret = [self timerWithTimeInterval:inTimeInterval target:self selector:@selector(jdExecuteSimpleBlock:) userInfo:block repeats:inRepeats]; 22 | return ret; 23 | } 24 | 25 | + (void)jdExecuteSimpleBlock:(NSTimer *)inTimer; 26 | { 27 | if ([inTimer userInfo]) { 28 | void (^block)() = (void (^)())[inTimer userInfo]; 29 | block(); 30 | } 31 | } 32 | 33 | /** 34 | * 暂停 35 | */ 36 | - (void)pause { 37 | if (![self isValid]) { 38 | return; 39 | } 40 | [self setFireDate:[NSDate distantFuture]]; 41 | } 42 | /** 43 | * 继续 44 | */ 45 | - (void)goOn { 46 | if (![self isValid]) { 47 | return; 48 | } 49 | [self setFireDate:[NSDate date]]; 50 | } 51 | /** 52 | * X秒后继续 53 | */ 54 | - (void)goOn:(NSTimeInterval)interval { 55 | if (![self isValid]) { 56 | return; 57 | } 58 | [self setFireDate:[NSDate dateWithTimeIntervalSinceNow:interval]]; 59 | } 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /WTSDK/Category/UI/CALayer+WT.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // CALayer+WT.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | /** 12 | * 反转方向 13 | */ 14 | typedef NS_ENUM(NSInteger, AnimReverDirection) { 15 | //X 16 | AnimReverDirectionX = 0, 17 | 18 | //Y 19 | AnimReverDirectionY, 20 | 21 | //Z 22 | AnimReverDirectionZ, 23 | 24 | }; 25 | 26 | @interface CALayer (WT) 27 | 28 | /** 29 | * 颤抖效果 30 | */ 31 | - (CAAnimation *)shakeFunction; 32 | 33 | /** 34 | * 渐显效果 35 | */ 36 | - (CATransition *)fadeFunction; 37 | 38 | /** 39 | * 渐显效果 效果时间 40 | */ 41 | - (CATransition *)fadeFunction:(CGFloat)time; 42 | 43 | /** 44 | * 缩放效果 45 | */ 46 | - (CAKeyframeAnimation *)transformScaleFunction; 47 | 48 | /** 49 | * 简3D动画吧 50 | */ 51 | - (CAAnimation *)anim_revers:(AnimReverDirection)direction duration:(NSTimeInterval)duration isReverse:(BOOL)isReverse repeatCount:(NSUInteger)repeatCount; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /WTSDK/Category/UI/CALayer+WT.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // CALayer+WT.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "CALayer+WT.h" 10 | 11 | @implementation CALayer (WT) 12 | 13 | /** 14 | * 颤抖效果 15 | */ 16 | - (CAAnimation *)shakeFunction { 17 | CAKeyframeAnimation *shake = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; 18 | shake.values = @[ [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(-5.0f, 0.0f, 0.0f)], [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(5.0f, 0.0f, 0.0f)] ]; 19 | shake.autoreverses = YES; 20 | shake.repeatCount = 2.0f; 21 | shake.duration = 0.07f; 22 | [self addAnimation:shake forKey:nil]; 23 | return shake; 24 | } 25 | 26 | /** 27 | * 渐显效果 28 | */ 29 | - (CATransition *)fadeFunction { 30 | return [self fadeFunction:0.4]; 31 | } 32 | 33 | /** 34 | * 渐显效果 效果时间 35 | */ 36 | - (CATransition *)fadeFunction:(CGFloat)time { 37 | CATransition *animation = [CATransition animation]; 38 | [animation setDuration:time]; 39 | [animation setType:kCATransitionFade]; 40 | [animation setSubtype:kCATransitionFromRight]; 41 | [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]]; 42 | [self addAnimation:animation forKey:nil]; 43 | return animation; 44 | } 45 | 46 | /** 47 | * 缩放效果 48 | */ 49 | - (CAKeyframeAnimation *)transformScaleFunction { 50 | CAKeyframeAnimation *transformscale = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"]; 51 | transformscale.values = @[ @(0), @(0.5), @(1.08) ]; 52 | transformscale.keyTimes = @[ @(0.0), @(0.2), @(0.3) ]; 53 | transformscale.calculationMode = kCAAnimationLinear; 54 | [self addAnimation:transformscale forKey:nil]; 55 | return transformscale; 56 | } 57 | 58 | /** 59 | * 简3D动画吧 60 | */ 61 | - (CAAnimation *)anim_revers:(AnimReverDirection)direction duration:(NSTimeInterval)duration isReverse:(BOOL)isReverse repeatCount:(NSUInteger)repeatCount { 62 | NSString *key = @"reversAnim"; 63 | if ([self animationForKey:key] != nil) { 64 | [self removeAnimationForKey:key]; 65 | } 66 | NSString *directionStr = nil; 67 | if (AnimReverDirectionX == direction) directionStr = @"x"; 68 | if (AnimReverDirectionY == direction) directionStr = @"y"; 69 | if (AnimReverDirectionZ == direction) directionStr = @"z"; 70 | //创建普通动画 71 | CABasicAnimation *reversAnim = [CABasicAnimation animationWithKeyPath:[NSString stringWithFormat:@"transform.rotation.%@", directionStr]]; 72 | //起点值 73 | reversAnim.fromValue = @(0); 74 | //终点值 75 | reversAnim.toValue = @(M_PI_2); 76 | //时长 77 | reversAnim.duration = duration; 78 | //自动反转 79 | reversAnim.autoreverses = isReverse; 80 | //完成删除 81 | reversAnim.removedOnCompletion = YES; 82 | //重复次数 83 | reversAnim.repeatCount = repeatCount; 84 | //添加 85 | [self addAnimation:reversAnim forKey:key]; 86 | 87 | return reversAnim; 88 | } 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /WTSDK/Category/UI/Checkmark_failure_white@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tate-zwt/WTSDK/1ef388c75bd507894c3074e8d92b8567922ccb3b/WTSDK/Category/UI/Checkmark_failure_white@2x.png -------------------------------------------------------------------------------- /WTSDK/Category/UI/Checkmark_success_white@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Tate-zwt/WTSDK/1ef388c75bd507894c3074e8d92b8567922ccb3b/WTSDK/Category/UI/Checkmark_success_white@2x.png -------------------------------------------------------------------------------- /WTSDK/Category/UI/UIBarButtonItem+WT.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // UIBarButtonItem+WT.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIBarButtonItem (WT) 12 | /** 13 | * 创建一个item 14 | * 15 | * @param target 点击item后调用哪个对象的方法 16 | * @param action 点击item后调用target的哪个方法 17 | * @param image 图片 18 | * @param highImage 高亮的图片 19 | * 20 | * @return 创建完的item 21 | */ 22 | + (UIBarButtonItem *)itemWithTarget:(id)target action:(SEL)action image:(NSString *)image highImage:(NSString *)highImage; 23 | @end 24 | -------------------------------------------------------------------------------- /WTSDK/Category/UI/UIBarButtonItem+WT.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // UIBarButtonItem+WT.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "UIBarButtonItem+WT.h" 10 | #import "UIView+WT.h" 11 | 12 | @implementation UIBarButtonItem (WT) 13 | /** 14 | * 创建一个item 15 | * 16 | * @param target 点击item后调用哪个对象的方法 17 | * @param action 点击item后调用target的哪个方法 18 | * @param image 图片 19 | * @param highImage 高亮的图片 20 | * 21 | * @return 创建完的item 22 | */ 23 | + (UIBarButtonItem *)itemWithTarget:(id)target action:(SEL)action image:(NSString *)image highImage:(NSString *)highImage { 24 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 25 | [btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; 26 | // 设置图片 27 | [btn setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal]; 28 | [btn setBackgroundImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted]; 29 | // 设置尺寸 30 | btn.size = btn.currentBackgroundImage.size; 31 | return [[UIBarButtonItem alloc] initWithCustomView:btn]; 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /WTSDK/Category/UI/UIButton+WT.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // UIButton+WT.h 3 | // ShopApp 4 | // 5 | // Created by 张威庭 on 16/1/18. 6 | // Copyright © 2016年 cong. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIButton (WT) 12 | 13 | /** 创建一个Button */ 14 | + (UIButton *)frame:(CGRect)frame title:(NSString *)title font:(UIFont *)font color:(UIColor *)color addView:(UIView *)addView; 15 | 16 | /* 17 | * 倒计时按钮 18 | * @param timeLine 倒计时总时间 19 | * @param title 还没倒计时的title 20 | * @param subTitle 倒计时的子名字 如:时、分 21 | * @param mColor 还没倒计时的颜色 22 | * @param color 倒计时的颜色 23 | */ 24 | 25 | - (void)startWithTime:(NSInteger)timeLine title:(NSString *)title countDownTitle:(NSString *)subTitle mainColor:(UIColor *)mColor countColor:(UIColor *)color; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /WTSDK/Category/UI/UIButton+WT.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // UIButton+WT.m 3 | // ShopApp 4 | // 5 | // Created by 张威庭 on 16/1/18. 6 | // Copyright © 2016年 cong. All rights reserved. 7 | // 8 | 9 | #import "UIButton+WT.h" 10 | 11 | @implementation UIButton (WT) 12 | 13 | 14 | + (UIButton *)frame:(CGRect)frame title:(NSString *)title font:(UIFont *)font color:(UIColor *)color addView:(UIView *)addView{ 15 | UIButton *_ = [[UIButton alloc] initWithFrame:frame]; 16 | if (color) { 17 | [_ setTitleColor:color forState:UIControlStateNormal]; 18 | } 19 | [_ setTitle:title forState:UIControlStateNormal]; 20 | _.titleLabel.font = font; 21 | [addView addSubview:_]; 22 | return _; 23 | } 24 | 25 | - (void)startWithTime:(NSInteger)timeLine title:(NSString *)title countDownTitle:(NSString *)subTitle mainColor:(UIColor *)mColor countColor:(UIColor *)color { 26 | 27 | // 倒计时时间 28 | __block NSInteger timeOut = timeLine; 29 | dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 30 | dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); 31 | 32 | // 每秒执行一次 33 | dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 1.0 * NSEC_PER_SEC, 0); 34 | dispatch_source_set_event_handler(_timer, ^{ 35 | 36 | // 倒计时结束,关闭 37 | if (timeOut <= 0) { 38 | dispatch_source_cancel(_timer); 39 | 40 | dispatch_async(dispatch_get_main_queue(), ^{ 41 | 42 | self.backgroundColor = mColor; 43 | [self setTitle:title forState:UIControlStateNormal]; 44 | self.userInteractionEnabled = YES; 45 | }); 46 | 47 | } else { 48 | 49 | int seconds = timeOut % 60; 50 | NSString *timeStr = [NSString stringWithFormat:@"%0.2d", seconds]; 51 | 52 | dispatch_async(dispatch_get_main_queue(), ^{ 53 | self.backgroundColor = color; 54 | [self setTitle:[NSString stringWithFormat:@"%@%@", timeStr, subTitle] forState:UIControlStateNormal]; 55 | self.userInteractionEnabled = NO; 56 | }); 57 | 58 | timeOut--; 59 | } 60 | }); 61 | 62 | dispatch_resume(_timer); 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /WTSDK/Category/UI/UIImage+WT.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // UIImage+WT.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | static const void *completeBlockKey = &completeBlockKey; 12 | static const void *failBlockKey = &failBlockKey; 13 | 14 | @interface UIImage () 15 | 16 | @property (nonatomic, copy) void (^completeBlock)(); 17 | 18 | @property (nonatomic, copy) void (^failBlock)(); 19 | 20 | @end 21 | 22 | @interface UIImage (WT) 23 | 24 | /** 25 | * 截屏吧 截部分视图也行 26 | */ 27 | + (UIImage *)captureWithView:(UIView *)view; 28 | - (UIImage *)imageFromImage:(UIImage *)image inRect:(CGRect)rect; 29 | 30 | /** 31 | * 纯色图片 32 | */ 33 | + (UIImage *)coloreImage:(UIColor *)color; 34 | + (UIImage *)coloreImage:(UIColor *)color size:(CGSize)size; 35 | 36 | /** 37 | * 按固定的最大比例压缩图片 38 | */ 39 | - (UIImage *)allowMaxImg; 40 | - (UIImage *)allowMaxImg_thum:(BOOL)thumbnail; 41 | 42 | /** 43 | * 图片要求的最大长宽 44 | */ 45 | - (CGSize)reSetMaxWH:(CGFloat)WH; 46 | 47 | /** 48 | * 按比例 重设图片大小 49 | */ 50 | - (UIImage *)resize_Rate:(CGFloat)rate; 51 | /** 52 | * 按比例 质量 重设图片大小 53 | */ 54 | - (UIImage *)resize_Quality:(CGInterpolationQuality)quality rate:(CGFloat)rate; 55 | 56 | /** 57 | * 保存到指定相册名字 58 | */ 59 | - (void)savedToAlbum_AlbumName:(NSString *)albumName sucBlack:(void (^)())completeBlock failBlock:(void (^)())failBlock; 60 | 61 | /** 62 | * 保存到相册 63 | */ 64 | - (void)savedToAlbum:(void (^)())completeBlock failBlock:(void (^)())failBlock; 65 | 66 | /** 67 | * 水印方向 68 | */ 69 | typedef NS_ENUM(NSInteger, ImageWaterDirect) { 70 | //左上 71 | ImageWaterDirectTopLeft = 0, 72 | //右上 73 | ImageWaterDirectTopRight, 74 | //左下 75 | ImageWaterDirectBottomLeft, 76 | //右下 77 | ImageWaterDirectBottomRight, 78 | //正中 79 | ImageWaterDirectCenter 80 | 81 | }; 82 | 83 | /** 84 | * 加水印 85 | */ 86 | - (UIImage *)waterWithText:(NSString *)text direction:(ImageWaterDirect)direction fontColor:(UIColor *)fontColor fontPoint:(CGFloat)fontPoint marginXY:(CGPoint)marginXY; 87 | 88 | /** 89 | * 加水印 90 | */ 91 | - (UIImage *)waterWithWaterImage:(UIImage *)waterImage direction:(ImageWaterDirect)direction waterSize:(CGSize)waterSize marginXY:(CGPoint)marginXY; 92 | 93 | - (UIImage *)fixOrientation; 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /WTSDK/Category/UI/UIImage+WT.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // UIImage+WT.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "UIImage+WT.h" 10 | #import 11 | #import 12 | @implementation UIImage (WT) 13 | 14 | /** 15 | * 截屏吧 截部分视图也行 16 | */ 17 | + (UIImage *)captureWithView:(UIView *)view { 18 | UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, [UIScreen mainScreen].scale); 19 | 20 | // IOS7及其后续版本 21 | if ([self respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) { 22 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: 23 | [self methodSignatureForSelector: 24 | @selector(drawViewHierarchyInRect:afterScreenUpdates:)]]; 25 | [invocation setTarget:self]; 26 | [invocation setSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]; 27 | CGRect arg2 = view.bounds; 28 | BOOL arg3 = YES; 29 | [invocation setArgument:&arg2 atIndex:2]; 30 | [invocation setArgument:&arg3 atIndex:3]; 31 | [invocation invoke]; 32 | } else { // IOS7之前的版本 33 | [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 34 | } 35 | 36 | UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext(); 37 | UIGraphicsEndImageContext(); 38 | return screenshot; 39 | } 40 | 41 | - (UIImage *)imageFromImage:(UIImage *)image inRect:(CGRect)rect { 42 | CGImageRef sourceImageRef = [image CGImage]; 43 | CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect); 44 | UIImage *newImage = [UIImage imageWithCGImage:newImageRef]; 45 | // CGImageRelease(sourceImageRef); 46 | CGImageRelease(newImageRef); 47 | return newImage; 48 | } 49 | 50 | /** 51 | * 纯色图片 52 | */ 53 | + (UIImage *)coloreImage:(UIColor *)color size:(CGSize)size { 54 | CGRect rect = (CGRect){{0.0f, 0.0f}, size}; 55 | //开启一个图形上下文 56 | UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0f); 57 | //获取图形上下文 58 | CGContextRef context = UIGraphicsGetCurrentContext(); 59 | CGContextSetFillColorWithColor(context, color.CGColor); 60 | CGContextFillRect(context, rect); 61 | //获取图像 62 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 63 | //关闭上下文 64 | UIGraphicsEndImageContext(); 65 | return image; 66 | } 67 | 68 | + (UIImage *)coloreImage:(UIColor *)color { 69 | CGSize size = CGSizeMake(1.0f, 1.0f); 70 | return [self coloreImage:color size:size]; 71 | } 72 | 73 | /** 74 | * 按比例 重设图片大小 75 | */ 76 | - (UIImage *)resize_Rate:(CGFloat)rate { 77 | return [self resize_Quality:kCGInterpolationNone rate:rate]; 78 | } 79 | /** 80 | * 按比例 质量 重设图片大小 81 | */ 82 | - (UIImage *)resize_Quality:(CGInterpolationQuality)quality rate:(CGFloat)rate { 83 | UIImage *resized = nil; 84 | CGFloat width = self.size.width * rate; 85 | CGFloat height = self.size.height * rate; 86 | 87 | UIGraphicsBeginImageContext(CGSizeMake(width, height)); 88 | CGContextRef context = UIGraphicsGetCurrentContext(); 89 | CGContextSetInterpolationQuality(context, quality); 90 | [self drawInRect:CGRectMake(0, 0, width, height)]; 91 | resized = UIGraphicsGetImageFromCurrentImageContext(); 92 | UIGraphicsEndImageContext(); 93 | return resized; 94 | } 95 | 96 | - (UIImage *)allowMaxImg { 97 | return [self allowMaxImg_thum:NO]; 98 | } 99 | 100 | /** 101 | * 按最大比例压缩图片 102 | */ 103 | - (UIImage *)allowMaxImg_thum:(BOOL)thumbnail { 104 | if (self == nil) { 105 | return nil; 106 | } 107 | CGFloat height = self.size.height; 108 | CGFloat width = self.size.width; 109 | CGFloat Max_H_W = 800; //要显示的图片 我能容忍的 最大长或宽(800) 110 | if (thumbnail) { 111 | Max_H_W = 150; //thumbnail(缩略图时) 最大长或宽 112 | } 113 | if ((MAX(height, width)) < (Max_H_W)) { 114 | return self; //不需要再改了 115 | } 116 | if (MAX(height, width) > Max_H_W) { //超过了限制 按比例压缩长宽 117 | CGFloat Max = MAX(height, width); 118 | height = height * (Max_H_W / Max); 119 | width = width * (Max_H_W / Max); 120 | } 121 | UIImage *newimage; 122 | UIGraphicsBeginImageContext(CGSizeMake((int) width, (int) height)); 123 | [self drawInRect:CGRectMake(0, 0, (int) width, (int) height)]; 124 | newimage = UIGraphicsGetImageFromCurrentImageContext(); 125 | UIGraphicsEndImageContext(); 126 | return newimage; 127 | } 128 | 129 | //图片要求的最大长宽 130 | - (CGSize)reSetMaxWH:(CGFloat)WH { 131 | if (self == nil) { 132 | return CGSizeZero; 133 | } 134 | CGFloat height = self.size.height / self.scale; 135 | CGFloat width = self.size.width / self.scale; 136 | CGFloat Max_H_W = WH; //要显示的图片 我能容忍的 最大长或宽() 137 | if ((MAX(height, width)) < (Max_H_W)) { 138 | return self.size; //不需要再改了 139 | } 140 | if (MAX(height, width) > Max_H_W) { //超过了限制 按比例压缩长宽 141 | CGFloat Max = MAX(height, width); 142 | height = height * (Max_H_W / Max); 143 | width = width * (Max_H_W / Max); 144 | } 145 | return CGSizeMake(width, height); 146 | } 147 | 148 | #pragma mark - 149 | 150 | /** 151 | * 保存到指定相册名字 152 | */ 153 | - (void)savedToAlbum_AlbumName:(NSString *)albumName sucBlack:(void (^)())completeBlock failBlock:(void (^)())failBlock { 154 | ALAssetsLibrary *ass = [[ALAssetsLibrary alloc] init]; 155 | [ass writeImageToSavedPhotosAlbum:self.CGImage orientation:(ALAssetOrientation) self.imageOrientation completionBlock:^(NSURL *assetURL, NSError *error) { 156 | __block BOOL albumWasFound = NO; 157 | ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init]; 158 | //search all photo albums in the library 159 | [assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:^(ALAssetsGroup *group, BOOL *stop) { 160 | //判断相册是否存在 161 | if ([albumName compare:[group valueForProperty:ALAssetsGroupPropertyName]] == NSOrderedSame) { 162 | //存在 163 | albumWasFound = YES; 164 | [assetsLibrary assetForURL:assetURL resultBlock:^(ALAsset *asset) { 165 | if ([group addAsset:asset]) { 166 | completeBlock(); 167 | } 168 | } 169 | failureBlock:^(NSError *error) { 170 | failBlock(); 171 | }]; 172 | return; 173 | } 174 | //如果不存在该相册创建 175 | if (group == nil && albumWasFound == NO) { 176 | __weak ALAssetsLibrary *weakSelf = assetsLibrary; 177 | //创建相册 178 | [assetsLibrary addAssetsGroupAlbumWithName:albumName resultBlock:^(ALAssetsGroup *group) { 179 | [weakSelf assetForURL:assetURL 180 | resultBlock:^(ALAsset *asset) { 181 | if ([group addAsset:asset]) { 182 | completeBlock(); 183 | } 184 | } 185 | failureBlock:^(NSError *error) { 186 | failBlock(); 187 | }]; 188 | } 189 | failureBlock:^(NSError *error) { 190 | failBlock(); 191 | }]; 192 | return; 193 | } 194 | } 195 | failureBlock:^(NSError *error) { 196 | failBlock(); 197 | }]; 198 | }]; 199 | } 200 | 201 | /** 202 | * 保存相册 203 | * 204 | * @param completeBlock 成功回调 205 | * @param completeBlock 出错回调 206 | */ 207 | - (void)savedToAlbum:(void (^)())completeBlock failBlock:(void (^)())failBlock { 208 | UIImageWriteToSavedPhotosAlbum(self, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL); 209 | self.completeBlock = completeBlock; 210 | self.failBlock = failBlock; 211 | } 212 | 213 | - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo { 214 | if (error == nil) { 215 | if (self.completeBlock != nil) self.completeBlock(); 216 | } else { 217 | if (self.failBlock != nil) self.failBlock(); 218 | } 219 | } 220 | 221 | /* 222 | * 模拟成员变量 223 | */ 224 | - (void (^)())failBlock { 225 | return objc_getAssociatedObject(self, failBlockKey); 226 | } 227 | - (void)setfailBlock:(void (^)())failBlock { 228 | objc_setAssociatedObject(self, failBlockKey, failBlock, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 229 | } 230 | - (void (^)())completeBlock { 231 | return objc_getAssociatedObject(self, completeBlockKey); 232 | } 233 | 234 | - (void)setcompleteBlock:(void (^)())completeBlock { 235 | objc_setAssociatedObject(self, completeBlockKey, completeBlock, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 236 | } 237 | 238 | #pragma mark - function😇 239 | 240 | /** 241 | * 加水印 242 | */ 243 | - (UIImage *)waterWithText:(NSString *)text direction:(ImageWaterDirect)direction fontColor:(UIColor *)fontColor fontPoint:(CGFloat)fontPoint marginXY:(CGPoint)marginXY { 244 | CGSize size = self.size; 245 | CGRect rect = (CGRect){CGPointZero, size}; 246 | //新建图片图形上下文 247 | UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f); 248 | //绘制图片 249 | [self drawInRect:rect]; 250 | //绘制文本 251 | NSDictionary *attr = @{NSFontAttributeName : [UIFont systemFontOfSize:fontPoint], NSForegroundColorAttributeName : fontColor}; 252 | CGRect strRect = [self calWidth:text attr:attr direction:direction rect:rect marginXY:marginXY]; 253 | [text drawInRect:strRect withAttributes:attr]; 254 | //获取图片 255 | UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 256 | //结束图片图形上下文 257 | UIGraphicsEndImageContext(); 258 | return newImage; 259 | } 260 | 261 | - (CGRect)calWidth:(NSString *)str attr:(NSDictionary *)attr direction:(ImageWaterDirect)direction rect:(CGRect)rect marginXY:(CGPoint)marginXY { 262 | CGSize size = [str sizeWithAttributes:attr]; 263 | CGRect calRect = [self rectWithRect:rect size:size direction:direction marginXY:marginXY]; 264 | return calRect; 265 | } 266 | 267 | - (CGRect)rectWithRect:(CGRect)rect size:(CGSize)size direction:(ImageWaterDirect)direction marginXY:(CGPoint)marginXY { 268 | CGPoint point = CGPointZero; 269 | //右上 270 | if (ImageWaterDirectTopRight == direction) point = CGPointMake(rect.size.width - size.width, 0); 271 | //左下 272 | if (ImageWaterDirectBottomLeft == direction) point = CGPointMake(0, rect.size.height - size.height); 273 | //右下 274 | if (ImageWaterDirectBottomRight == direction) point = CGPointMake(rect.size.width - size.width, rect.size.height - size.height); 275 | //正中 276 | if (ImageWaterDirectCenter == direction) point = CGPointMake((rect.size.width - size.width) * .5f, (rect.size.height - size.height) * .5f); 277 | point.x += marginXY.x; 278 | point.y += marginXY.y; 279 | CGRect calRect = (CGRect){point, size}; 280 | return calRect; 281 | } 282 | 283 | /** 284 | * 加水印 285 | */ 286 | - (UIImage *)waterWithWaterImage:(UIImage *)waterImage direction:(ImageWaterDirect)direction waterSize:(CGSize)waterSize marginXY:(CGPoint)marginXY { 287 | CGSize size = self.size; 288 | CGRect rect = (CGRect){CGPointZero, size}; 289 | //新建图片图形上下文 290 | UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f); 291 | //绘制图片 292 | [self drawInRect:rect]; 293 | //计算水印的rect 294 | CGSize waterImageSize = CGSizeEqualToSize(waterSize, CGSizeZero) ? waterImage.size : waterSize; 295 | CGRect calRect = [self rectWithRect:rect size:waterImageSize direction:direction marginXY:marginXY]; 296 | //绘制水印图片 297 | [waterImage drawInRect:calRect]; 298 | //获取图片 299 | UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 300 | //结束图片图形上下文 301 | UIGraphicsEndImageContext(); 302 | 303 | return newImage; 304 | } 305 | 306 | - (UIImage *)fixOrientation { 307 | 308 | // No-op if the orientation is already correct 309 | if (self.imageOrientation == UIImageOrientationUp) return self; 310 | 311 | // We need to calculate the proper transformation to make the image upright. 312 | // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored. 313 | CGAffineTransform transform = CGAffineTransformIdentity; 314 | 315 | switch (self.imageOrientation) { 316 | case UIImageOrientationDown: 317 | case UIImageOrientationDownMirrored: 318 | transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height); 319 | transform = CGAffineTransformRotate(transform, M_PI); 320 | break; 321 | 322 | case UIImageOrientationLeft: 323 | case UIImageOrientationLeftMirrored: 324 | transform = CGAffineTransformTranslate(transform, self.size.width, 0); 325 | transform = CGAffineTransformRotate(transform, M_PI_2); 326 | break; 327 | 328 | case UIImageOrientationRight: 329 | case UIImageOrientationRightMirrored: 330 | transform = CGAffineTransformTranslate(transform, 0, self.size.height); 331 | transform = CGAffineTransformRotate(transform, -M_PI_2); 332 | break; 333 | case UIImageOrientationUp: 334 | case UIImageOrientationUpMirrored: 335 | break; 336 | } 337 | 338 | switch (self.imageOrientation) { 339 | case UIImageOrientationUpMirrored: 340 | case UIImageOrientationDownMirrored: 341 | transform = CGAffineTransformTranslate(transform, self.size.width, 0); 342 | transform = CGAffineTransformScale(transform, -1, 1); 343 | break; 344 | 345 | case UIImageOrientationLeftMirrored: 346 | case UIImageOrientationRightMirrored: 347 | transform = CGAffineTransformTranslate(transform, self.size.height, 0); 348 | transform = CGAffineTransformScale(transform, -1, 1); 349 | break; 350 | case UIImageOrientationUp: 351 | case UIImageOrientationDown: 352 | case UIImageOrientationLeft: 353 | case UIImageOrientationRight: 354 | break; 355 | } 356 | 357 | // Now we draw the underlying CGImage into a new context, applying the transform 358 | // calculated above. 359 | CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height, 360 | CGImageGetBitsPerComponent(self.CGImage), 0, 361 | CGImageGetColorSpace(self.CGImage), 362 | CGImageGetBitmapInfo(self.CGImage)); 363 | CGContextConcatCTM(ctx, transform); 364 | switch (self.imageOrientation) { 365 | case UIImageOrientationLeft: 366 | case UIImageOrientationLeftMirrored: 367 | case UIImageOrientationRight: 368 | case UIImageOrientationRightMirrored: 369 | // Grr... 370 | CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.height, self.size.width), self.CGImage); 371 | break; 372 | 373 | default: 374 | CGContextDrawImage(ctx, CGRectMake(0, 0, self.size.width, self.size.height), self.CGImage); 375 | break; 376 | } 377 | 378 | // And now we just create a new UIImage from the drawing context 379 | CGImageRef cgimg = CGBitmapContextCreateImage(ctx); 380 | UIImage *img = [UIImage imageWithCGImage:cgimg]; 381 | CGContextRelease(ctx); 382 | CGImageRelease(cgimg); 383 | return img; 384 | } 385 | 386 | @end 387 | -------------------------------------------------------------------------------- /WTSDK/Category/UI/UILabel+WT.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // UILabel+WT.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UILabel (WT) 12 | 13 | /** 创建一个 */ 14 | + (UILabel *)frame:(CGRect)frame title:(NSString *)title font:(UIFont *)font color:(UIColor *)color line:(NSInteger)line addView:(UIView *)addView; 15 | 16 | /** 有删除线的 */ 17 | - (void)delLineStr:(NSString *)string; 18 | 19 | /** 有下划线的 */ 20 | - (void)underlineStr:(NSString *)string; 21 | 22 | /** 设置label的行高默认为:10 */ 23 | - (void)settingLabelHeightofRowString:(NSString*)string; 24 | 25 | /** 设置label的行高*/ 26 | - (void)settingLabelRowOfHeight:(CGFloat)height string:(NSString*)string; 27 | 28 | /** 设置Html代码格式Str */ 29 | - (void)htmlString:(NSString *)htmlStr; 30 | 31 | /** 设置Html代码格式Str与行高 */ 32 | - (void)htmlString:(NSString *)htmlStr labelRowOfHeight:(CGFloat)height; 33 | 34 | 35 | /** 设置行距 */ 36 | - (void)setText:(NSString*)text lineSpacing:(CGFloat)lineSpacing; 37 | 38 | /** 计算label的行高 */ 39 | + (CGFloat)text:(NSString*)text heightWithFontSize:(CGFloat)fontSize width:(CGFloat)width lineSpacing:(CGFloat)lineSpacing; 40 | @end 41 | -------------------------------------------------------------------------------- /WTSDK/Category/UI/UILabel+WT.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // UILabel+WT.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "UILabel+WT.h" 10 | #import "WTConst.h" 11 | 12 | @implementation UILabel (WT) 13 | 14 | + (UILabel *)frame:(CGRect)frame title:(NSString *)title font:(UIFont *)font color:(UIColor *)color line:(NSInteger)line addView:(UIView *)addView{ 15 | UILabel *_ = [[UILabel alloc] initWithFrame:frame]; 16 | _.font = font; 17 | if (color) { 18 | _.textColor = color; 19 | } 20 | _.text = title; 21 | _.numberOfLines = line; 22 | [addView addSubview:_]; 23 | return _; 24 | } 25 | 26 | /** 有删除线的 */ 27 | - (void)delLineStr:(NSString *)string { 28 | if (WTStrIsEmpty(string)) return; 29 | NSMutableAttributedString *attri = [[NSMutableAttributedString alloc] initWithString:string]; 30 | [attri addAttribute:NSStrikethroughStyleAttributeName value:@(NSUnderlinePatternSolid | NSUnderlineStyleSingle) range:NSMakeRange(0, string.length)]; 31 | [self setAttributedText:attri]; 32 | } 33 | 34 | /** 有下划线的 */ 35 | - (void)underlineStr:(NSString *)string { 36 | if (WTStrIsEmpty(string)) return; 37 | NSMutableAttributedString *attri = [[NSMutableAttributedString alloc] initWithString:string]; 38 | [attri addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlinePatternSolid | NSUnderlineStyleSingle) range:NSMakeRange(0, string.length)]; 39 | [self setAttributedText:attri]; 40 | } 41 | 42 | - (void)settingLabelHeightofRowString:(NSString*)string{ 43 | [self settingLabelRowOfHeight:10 string:string]; 44 | } 45 | 46 | - (void)settingLabelRowOfHeight:(CGFloat)height string:(NSString*)string{ 47 | NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string]; 48 | NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 49 | [paragraphStyle setLineSpacing:height]; //调整行间距 50 | [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [string length])]; 51 | self.attributedText = attributedString; 52 | [self sizeToFit]; 53 | } 54 | 55 | 56 | - (void)htmlString:(NSString *)htmlStr{ 57 | NSAttributedString *attributedString = [[NSAttributedString alloc] initWithData:[htmlStr dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType } documentAttributes:nil error:nil]; 58 | self.attributedText = attributedString; 59 | } 60 | 61 | - (void)htmlString:(NSString *)htmlStr labelRowOfHeight:(CGFloat)height{ 62 | NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithData:[htmlStr dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType } documentAttributes:nil error:nil]; 63 | NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 64 | [paragraphStyle setLineSpacing:height]; //调整行间距 65 | [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [attributedString length])]; 66 | self.attributedText = attributedString; 67 | [self sizeToFit]; 68 | } 69 | 70 | - (void)setText:(NSString*)text lineSpacing:(CGFloat)lineSpacing { 71 | if (lineSpacing < 0.01 || !text) { 72 | self.text = text; 73 | return; 74 | } 75 | 76 | NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text]; 77 | [attributedString addAttribute:NSFontAttributeName value:self.font range:NSMakeRange(0, [text length])]; 78 | 79 | NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 80 | [paragraphStyle setLineSpacing:lineSpacing]; 81 | [paragraphStyle setLineBreakMode:self.lineBreakMode]; 82 | [paragraphStyle setAlignment:self.textAlignment]; 83 | [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [text length])]; 84 | 85 | self.attributedText = attributedString; 86 | } 87 | 88 | + (CGFloat)text:(NSString*)text heightWithFontSize:(CGFloat)fontSize width:(CGFloat)width lineSpacing:(CGFloat)lineSpacing { 89 | UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, MAXFLOAT)]; 90 | label.font = [UIFont systemFontOfSize:fontSize]; 91 | label.numberOfLines = 0; 92 | [label setText:text lineSpacing:lineSpacing]; 93 | [label sizeToFit]; 94 | return label.height; 95 | } 96 | 97 | @end 98 | -------------------------------------------------------------------------------- /WTSDK/Category/UI/UITextView+WT.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // UITextView+WT.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UIView+WT.h" 11 | @interface UITextView (WT) 12 | /** 插入NSAttributedString */ 13 | - (void)insertAttributedText:(NSAttributedString *)text; 14 | - (void)insertAttributedText:(NSAttributedString *)text settingBlock:(void (^)(NSMutableAttributedString *attributedText))settingBlock; 15 | 16 | /** 设置行距 */ 17 | - (void)setText:(NSString*)text lineSpacing:(CGFloat)lineSpacing; 18 | 19 | /** 计算TextView的行高 */ 20 | + (CGFloat)text:(NSString*)text heightWithFontSize:(CGFloat)fontSize width:(CGFloat)width lineSpacing:(CGFloat)lineSpacing; 21 | @end 22 | -------------------------------------------------------------------------------- /WTSDK/Category/UI/UITextView+WT.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // UITextView+WT.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "UITextView+WT.h" 10 | 11 | 12 | @implementation UITextView (WT) 13 | 14 | - (void)insertAttributedText:(NSAttributedString *)text { 15 | [self insertAttributedText:text settingBlock:nil]; 16 | } 17 | 18 | - (void)insertAttributedText:(NSAttributedString *)text settingBlock:(void (^)(NSMutableAttributedString *))settingBlock { 19 | NSMutableAttributedString *attributedText = [[NSMutableAttributedString alloc] init]; 20 | // 拼接之前的文字(图片和普通文字) 21 | [attributedText appendAttributedString:self.attributedText]; 22 | 23 | // 拼接其他文字 24 | NSUInteger loc = self.selectedRange.location; 25 | // [attributedText insertAttributedString:text atIndex:loc]; 26 | [attributedText replaceCharactersInRange:self.selectedRange withAttributedString:text]; //选中的内容替换 27 | 28 | // 调用外面传进来的代码 29 | if (settingBlock) { 30 | settingBlock(attributedText); 31 | } 32 | 33 | self.attributedText = attributedText; 34 | 35 | // 移除光标到表情的后面 36 | self.selectedRange = NSMakeRange(loc + 1, 0); 37 | } 38 | 39 | - (void)setText:(NSString*)text lineSpacing:(CGFloat)lineSpacing { 40 | if (lineSpacing < 0.01 || !text) { 41 | self.text = text; 42 | return; 43 | } 44 | 45 | NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text]; 46 | [attributedString addAttribute:NSFontAttributeName value:self.font range:NSMakeRange(0, [text length])]; 47 | 48 | NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 49 | [paragraphStyle setLineSpacing:lineSpacing]; 50 | [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [text length])]; 51 | 52 | self.attributedText = attributedString; 53 | } 54 | 55 | + (CGFloat)text:(NSString*)text heightWithFontSize:(CGFloat)fontSize width:(CGFloat)width lineSpacing:(CGFloat)lineSpacing { 56 | UITextView* textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, width, MAXFLOAT)]; 57 | textView.font = [UIFont systemFontOfSize:fontSize]; 58 | [textView setText:text lineSpacing:lineSpacing]; 59 | [textView sizeToFit]; 60 | return textView.height; 61 | } 62 | @end 63 | -------------------------------------------------------------------------------- /WTSDK/Category/UI/UIView+WT.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // UIView+WT.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | CGPoint CGRectGetCenter(CGRect rect); 11 | CGRect CGRectMoveToCenter(CGRect rect, CGPoint center); 12 | @interface UIView (WT) 13 | 14 | @property (nonatomic, assign) CGFloat x; 15 | @property (nonatomic, assign) CGFloat y; 16 | @property (nonatomic, assign) CGFloat centerX; 17 | @property (nonatomic, assign) CGFloat centerY; 18 | 19 | @property (nonatomic, assign) CGFloat width; 20 | @property (nonatomic, assign) CGFloat height; 21 | @property (nonatomic, assign) CGSize size; 22 | @property (nonatomic, assign) CGPoint origin; 23 | 24 | @property (nonatomic, assign) CGFloat top; 25 | @property (nonatomic, assign) CGFloat left; 26 | @property (nonatomic, assign) CGFloat bottom; 27 | @property (nonatomic, assign) CGFloat right; 28 | @property (nonatomic, assign) CGFloat radius; 29 | 30 | @property (nonatomic, readonly) CGPoint bottomLeft; 31 | @property (nonatomic, readonly) CGPoint bottomRight; 32 | @property (nonatomic, readonly) CGPoint topRight; 33 | 34 | - (void)moveBy:(CGPoint)delta; 35 | - (void)scaleBy:(CGFloat)scaleFactor; 36 | - (void)fitInSize:(CGSize)aSize; 37 | /** 获取View所在的控制器 */ 38 | - (UIViewController *)viewController; 39 | 40 | #pragma mark - 其它的效果😎 41 | 42 | /** 变圆 */ 43 | - (UIView *)roundV; 44 | /** 加阴影 self.layer.shadowOffset = CGSizeMake(0, 2)self.layer.shadowOpacity = 0.2; */ 45 | - (void)addShadow; 46 | 47 | typedef void (^GestureActionBlock)(UIGestureRecognizer *ges); 48 | /** 单点击手势 */ 49 | - (void)tapGesture:(GestureActionBlock)block; 50 | /** 有次数的单击手势 tapsCount:点击次数*/ 51 | - (void)tapGesture:(GestureActionBlock)block numberOfTapsRequired:(NSUInteger)tapsCount; 52 | /** 长按手势 */ 53 | - (void)longPressGestrue:(GestureActionBlock)block; 54 | 55 | /** 添加边框:四边 */ 56 | - (void)border:(UIColor *)color width:(CGFloat)width CornerRadius:(CGFloat)radius; 57 | /** 添加边框:四边 默认4*/ 58 | - (void)border:(UIColor *)color width:(CGFloat)width; 59 | /** 四边变圆 */ 60 | - (void)borderRoundCornerRadius:(CGFloat)radius; 61 | /** 四边变圆 默认4*/ 62 | - (void)borderRound; 63 | 64 | - (void)debug:(UIColor *)color width:(CGFloat)width; 65 | /** 移除对应的view */ 66 | - (void)removeClassView:(Class)classV; 67 | 68 | /** 画线 */ 69 | + (CAShapeLayer *)drawLine:(CGPoint)points to:(CGPoint)pointe color:(UIColor *)color; 70 | 71 | /** 画框框线 */ 72 | + (CAShapeLayer *)drawRect:(CGRect)rect radius:(CGFloat)redius color:(UIColor *)color; 73 | 74 | /** 画圆 */ 75 | + (CAShapeLayer *)drawArc:(CGPoint)points radius:(CGFloat)radius startD:(CGFloat)startd endD:(CGFloat)endD color:(UIColor *)color; 76 | 77 | @end 78 | -------------------------------------------------------------------------------- /WTSDK/Category/UI/UIView+WT.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // UIView+WT.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "UIView+WT.h" 10 | 11 | #import 12 | 13 | CGPoint CGRectGetCenter(CGRect rect) { 14 | CGPoint pt; 15 | pt.x = CGRectGetMidX(rect); 16 | pt.y = CGRectGetMidY(rect); 17 | return pt; 18 | } 19 | 20 | CGRect CGRectMoveToCenter(CGRect rect, CGPoint center) { 21 | CGRect newrect = CGRectZero; 22 | newrect.origin.x = center.x - CGRectGetMidX(rect); 23 | newrect.origin.y = center.y - CGRectGetMidY(rect); 24 | newrect.size = rect.size; 25 | return newrect; 26 | } 27 | 28 | @implementation UIView (WT) 29 | // Retrieve and set the origin 30 | - (CGPoint)origin { 31 | return self.frame.origin; 32 | } 33 | 34 | - (void)setOrigin:(CGPoint)aPoint { 35 | CGRect newframe = self.frame; 36 | newframe.origin = aPoint; 37 | self.frame = newframe; 38 | } 39 | 40 | // Retrieve and set the size 41 | - (CGSize)size { 42 | return self.frame.size; 43 | } 44 | 45 | - (void)setSize:(CGSize)aSize { 46 | CGRect newframe = self.frame; 47 | newframe.size = aSize; 48 | self.frame = newframe; 49 | } 50 | 51 | // Query other frame locations 52 | - (CGPoint)bottomRight { 53 | CGFloat x = self.frame.origin.x + self.frame.size.width; 54 | CGFloat y = self.frame.origin.y + self.frame.size.height; 55 | return CGPointMake(x, y); 56 | } 57 | 58 | - (CGPoint)bottomLeft { 59 | CGFloat x = self.frame.origin.x; 60 | CGFloat y = self.frame.origin.y + self.frame.size.height; 61 | return CGPointMake(x, y); 62 | } 63 | 64 | - (CGPoint)topRight { 65 | CGFloat x = self.frame.origin.x + self.frame.size.width; 66 | CGFloat y = self.frame.origin.y; 67 | return CGPointMake(x, y); 68 | } 69 | 70 | // Retrieve and set height, width, top, bottom, left, right 71 | - (CGFloat)height { 72 | return self.frame.size.height; 73 | } 74 | 75 | - (void)setHeight:(CGFloat)newheight { 76 | CGRect newframe = self.frame; 77 | newframe.size.height = newheight; 78 | self.frame = newframe; 79 | } 80 | 81 | - (CGFloat)width { 82 | return self.frame.size.width; 83 | } 84 | 85 | - (void)setWidth:(CGFloat)newwidth { 86 | CGRect newframe = self.frame; 87 | newframe.size.width = newwidth; 88 | self.frame = newframe; 89 | } 90 | 91 | - (CGFloat)top { 92 | return self.frame.origin.y; 93 | } 94 | 95 | - (void)setTop:(CGFloat)newtop { 96 | CGRect newframe = self.frame; 97 | newframe.origin.y = newtop; 98 | self.frame = newframe; 99 | } 100 | 101 | - (CGFloat)left { 102 | return self.frame.origin.x; 103 | } 104 | 105 | - (void)setLeft:(CGFloat)newleft { 106 | CGRect newframe = self.frame; 107 | newframe.origin.x = newleft; 108 | self.frame = newframe; 109 | } 110 | 111 | - (CGFloat)bottom { 112 | return self.frame.origin.y + self.frame.size.height; 113 | } 114 | 115 | - (void)setBottom:(CGFloat)newbottom { 116 | CGRect newframe = self.frame; 117 | newframe.origin.y = newbottom - self.frame.size.height; 118 | self.frame = newframe; 119 | } 120 | 121 | - (CGFloat)right { 122 | return self.frame.origin.x + self.frame.size.width; 123 | } 124 | 125 | - (void)setRight:(CGFloat)newright { 126 | CGFloat delta = newright - (self.frame.origin.x + self.frame.size.width); 127 | CGRect newframe = self.frame; 128 | newframe.origin.x += delta; 129 | self.frame = newframe; 130 | } 131 | 132 | // Move via offset 133 | - (void)moveBy:(CGPoint)delta { 134 | CGPoint newcenter = self.center; 135 | newcenter.x += delta.x; 136 | newcenter.y += delta.y; 137 | self.center = newcenter; 138 | } 139 | 140 | // Scaling 141 | - (void)scaleBy:(CGFloat)scaleFactor { 142 | CGRect newframe = self.frame; 143 | newframe.size.width *= scaleFactor; 144 | newframe.size.height *= scaleFactor; 145 | self.frame = newframe; 146 | } 147 | 148 | // Ensure that both dimensions fit within the given size by scaling down 149 | - (void)fitInSize:(CGSize)aSize { 150 | CGFloat scale; 151 | CGRect newframe = self.frame; 152 | 153 | if (newframe.size.height && (newframe.size.height > aSize.height)) { 154 | scale = aSize.height / newframe.size.height; 155 | newframe.size.width *= scale; 156 | newframe.size.height *= scale; 157 | } 158 | 159 | if (newframe.size.width && (newframe.size.width >= aSize.width)) { 160 | scale = aSize.width / newframe.size.width; 161 | newframe.size.width *= scale; 162 | newframe.size.height *= scale; 163 | } 164 | 165 | self.frame = newframe; 166 | } 167 | 168 | - (void)setX:(CGFloat)x { 169 | CGRect frame = self.frame; 170 | frame.origin.x = x; 171 | self.frame = frame; 172 | } 173 | 174 | - (void)setY:(CGFloat)y { 175 | 176 | CGRect frame = self.frame; 177 | frame.origin.y = y; 178 | self.frame = frame; 179 | } 180 | 181 | - (CGFloat)x { 182 | 183 | return self.frame.origin.x; 184 | } 185 | 186 | - (CGFloat)y { 187 | return self.frame.origin.y; 188 | } 189 | - (void)setCenterX:(CGFloat)centerX { 190 | CGPoint center = self.center; 191 | center.x = centerX; 192 | self.center = center; 193 | } 194 | 195 | - (void)setCenterY:(CGFloat)centerY { 196 | 197 | CGPoint center = self.center; 198 | center.y = centerY; 199 | self.center = center; 200 | } 201 | 202 | - (CGFloat)centerX { 203 | 204 | return self.center.x; 205 | } 206 | 207 | - (CGFloat)centerY { 208 | return self.center.y; 209 | } 210 | 211 | - (CGFloat)radius { 212 | return self.layer.cornerRadius; 213 | } 214 | 215 | - (void)setRadius:(CGFloat)radius { 216 | if (radius <= 0) { 217 | radius = self.width * 0.5f; 218 | } 219 | self.layer.cornerRadius = radius; 220 | self.layer.masksToBounds = YES; 221 | } 222 | 223 | - (UIViewController *)viewController { 224 | UIResponder *next = self.nextResponder; 225 | while (next != nil) { 226 | if ([next isKindOfClass:[UIViewController class]]) { 227 | 228 | return (UIViewController *) next; 229 | } 230 | 231 | next = next.nextResponder; 232 | } 233 | 234 | return nil; 235 | } 236 | 237 | //变圆 238 | - (UIView *)roundV { 239 | self.layer.masksToBounds = YES; 240 | self.layer.cornerRadius = self.width / 2; 241 | return self; 242 | } 243 | 244 | //加阴影 245 | - (void)addShadow { 246 | self.layer.shadowOffset = CGSizeMake(0, 2); 247 | self.layer.shadowOpacity = 0.24; 248 | self.layer.shadowPath = [UIBezierPath bezierPathWithRect:CGRectMake(0, self.height - 2, self.width == 320 ? [UIScreen mainScreen].bounds.size.width : self.width, 2)].CGPath; 249 | } 250 | 251 | 252 | /** 添加边框:四边 */ 253 | - (void)border:(UIColor *)color width:(CGFloat)width CornerRadius:(CGFloat)radius { 254 | if (radius == 0) { 255 | [self border:color width:width]; 256 | } else { 257 | CALayer *layer = self.layer; 258 | if (color != nil) { 259 | layer.borderColor = color.CGColor; 260 | } 261 | layer.cornerRadius = radius; 262 | layer.masksToBounds = YES; 263 | layer.borderWidth = width; 264 | } 265 | } 266 | /** 四边变圆 */ 267 | - (void)borderRoundCornerRadius:(CGFloat)radius { 268 | CALayer *layer = self.layer; 269 | 270 | layer.cornerRadius = radius; 271 | layer.masksToBounds = YES; 272 | } 273 | //添加边框 274 | - (void)border:(UIColor *)color width:(CGFloat)width; 275 | { 276 | CALayer *layer = self.layer; 277 | if (color != nil) { 278 | layer.borderColor = color.CGColor; 279 | } 280 | layer.cornerRadius = 4; 281 | layer.masksToBounds = YES; 282 | layer.borderWidth = width; 283 | } 284 | 285 | - (void)borderRound { 286 | CALayer *layer = self.layer; 287 | layer.cornerRadius = 4; 288 | layer.masksToBounds = YES; 289 | } 290 | 291 | /** 移除对应的view */ 292 | - (void)removeClassView:(Class)classV { 293 | for (UIView *view in self.subviews) { 294 | if ([view isKindOfClass:classV]) { 295 | [view removeFromSuperview]; 296 | } 297 | } 298 | } 299 | 300 | //调试 301 | - (void)debug:(UIColor *)color width:(CGFloat)width { 302 | #ifdef DEBUG 303 | if (color == nil) { 304 | [self border:[UIColor colorWithRed:(arc4random() % 255) / 255.0f green:(arc4random() % 255) / 255.0f blue:(arc4random() % 255) / 255.0f alpha:1] width:width]; 305 | return; 306 | } 307 | [self border:color width:width]; 308 | #endif 309 | } 310 | 311 | static char kActionHandlerTapBlockKey; 312 | static char kActionHandlerTapGestureKey; 313 | static char kActionHandlerLongPressBlockKey; 314 | static char kActionHandlerLongPressGestureKey; 315 | 316 | //单点击手势 317 | - (void)tapGesture:(GestureActionBlock)block { 318 | self.userInteractionEnabled = YES; 319 | UITapGestureRecognizer *gesture = objc_getAssociatedObject(self, &kActionHandlerTapGestureKey); 320 | if (!gesture) { 321 | gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleActionForTapGesture:)]; 322 | [self addGestureRecognizer:gesture]; 323 | objc_setAssociatedObject(self, &kActionHandlerTapGestureKey, gesture, OBJC_ASSOCIATION_RETAIN); 324 | } 325 | objc_setAssociatedObject(self, &kActionHandlerTapBlockKey, block, OBJC_ASSOCIATION_COPY); 326 | } 327 | //有次数的单击手势 328 | - (void)tapGesture:(GestureActionBlock)block numberOfTapsRequired:(NSUInteger)tapsCount { 329 | self.userInteractionEnabled = YES; 330 | UITapGestureRecognizer *gesture = objc_getAssociatedObject(self, &kActionHandlerTapGestureKey); 331 | if (!gesture) { 332 | gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleActionForTapGesture:)]; 333 | gesture.numberOfTapsRequired = tapsCount; 334 | [self addGestureRecognizer:gesture]; 335 | objc_setAssociatedObject(self, &kActionHandlerTapGestureKey, gesture, OBJC_ASSOCIATION_RETAIN); 336 | } 337 | objc_setAssociatedObject(self, &kActionHandlerTapBlockKey, block, OBJC_ASSOCIATION_COPY); 338 | } 339 | 340 | 341 | - (void)handleActionForTapGesture:(UITapGestureRecognizer *)gesture { 342 | if (gesture.state == UIGestureRecognizerStateRecognized) { 343 | GestureActionBlock block = objc_getAssociatedObject(self, &kActionHandlerTapBlockKey); 344 | if (block) { 345 | block(gesture); 346 | } 347 | } 348 | } 349 | 350 | //长按手势 351 | - (void)longPressGestrue:(GestureActionBlock)block { 352 | self.userInteractionEnabled = YES; 353 | UILongPressGestureRecognizer *gesture = objc_getAssociatedObject(self, &kActionHandlerLongPressGestureKey); 354 | if (!gesture) { 355 | gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleActionForLongPressGesture:)]; 356 | [self addGestureRecognizer:gesture]; 357 | objc_setAssociatedObject(self, &kActionHandlerLongPressGestureKey, gesture, OBJC_ASSOCIATION_RETAIN); 358 | } 359 | objc_setAssociatedObject(self, &kActionHandlerLongPressBlockKey, block, OBJC_ASSOCIATION_COPY); 360 | } 361 | 362 | - (void)handleActionForLongPressGesture:(UITapGestureRecognizer *)gesture { 363 | if (gesture.state == UIGestureRecognizerStateBegan) { 364 | GestureActionBlock block = objc_getAssociatedObject(self, &kActionHandlerLongPressBlockKey); 365 | if (block) { 366 | block(gesture); 367 | } 368 | } 369 | } 370 | 371 | //画线 372 | + (CAShapeLayer *)drawLine:(CGPoint)points to:(CGPoint)pointe color:(UIColor *)color { 373 | CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 374 | UIBezierPath *path = [UIBezierPath bezierPath]; 375 | [path moveToPoint:points]; 376 | [path addLineToPoint:pointe]; 377 | [path closePath]; 378 | shapeLayer.path = path.CGPath; 379 | shapeLayer.strokeColor = [color CGColor]; 380 | shapeLayer.fillColor = [[UIColor whiteColor] CGColor]; 381 | shapeLayer.lineWidth = 1; 382 | return shapeLayer; 383 | } 384 | 385 | //画框框线 386 | + (CAShapeLayer *)drawRect:(CGRect)rect radius:(CGFloat)redius color:(UIColor *)color { 387 | CAShapeLayer *solidLine = [CAShapeLayer layer]; 388 | UIBezierPath *solidPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:redius]; 389 | solidLine.lineWidth = 1.0f; 390 | solidLine.strokeColor = color.CGColor; 391 | solidLine.fillColor = [UIColor clearColor].CGColor; 392 | solidLine.path = solidPath.CGPath; 393 | return solidLine; 394 | } 395 | 396 | //画圆 397 | + (CAShapeLayer *)drawArc:(CGPoint)points radius:(CGFloat)radius startD:(CGFloat)startd endD:(CGFloat)endD color:(UIColor *)color { 398 | CAShapeLayer *solidLine = [CAShapeLayer layer]; 399 | UIBezierPath *solidPath = [UIBezierPath bezierPathWithArcCenter:points radius:radius startAngle:startd endAngle:endD clockwise:YES]; 400 | solidLine.lineWidth = 1.0f; 401 | solidLine.strokeColor = color.CGColor; 402 | solidLine.fillColor = [UIColor clearColor].CGColor; 403 | solidLine.path = solidPath.CGPath; 404 | return solidLine; 405 | } 406 | 407 | @end 408 | -------------------------------------------------------------------------------- /WTSDK/Tool/Singleton.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // .h 3 | #define singleton_interface(class) +(instancetype) shared##class; 4 | 5 | // .m 6 | #define singleton_implementation(class) \ 7 | static class *_instance; \ 8 | \ 9 | +(id) allocWithZone : (struct _NSZone *) zone { \ 10 | static dispatch_once_t onceToken; \ 11 | dispatch_once(&onceToken, ^{ \ 12 | _instance = [super allocWithZone:zone]; \ 13 | }); \ 14 | \ 15 | return _instance; \ 16 | } \ 17 | \ 18 | +(instancetype) shared##class \ 19 | { \ 20 | if (_instance == nil) { \ 21 | _instance = [[class alloc] init]; \ 22 | } \ 23 | \ 24 | return _instance; \ 25 | } 26 | -------------------------------------------------------------------------------- /WTSDK/Tool/WTConst.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | #ifdef DEBUG //处于开发阶段 3 | #define NSLog(...) NSLog(@"%s %d\n %@\n\n", __func__, __LINE__, [NSString stringWithFormat:__VA_ARGS__]) 4 | #else //处于发布阶段 5 | #define NSLog(...) 6 | #endif 7 | 8 | //我要导入的东西哈哈哈哈哈😊😊😊😊😊😊😊😊😊😊😊😊😊 9 | #ifdef __OBJC__ 10 | //basic frame 😅 11 | #import 12 | #import 13 | 14 | //category 15 | #import "CALayer+WT.h" 16 | #import "NSArray+WT.h" 17 | #import "NSDate+WT.h" 18 | #import "NSString+WT.h" 19 | #import "NSTimer+WT.h" 20 | #import "UIBarButtonItem+WT.h" 21 | #import "UIImage+WT.h" 22 | #import "UILabel+WT.h" 23 | #import "UITextView+WT.h" 24 | #import "UIView+WT.h" 25 | 26 | //tool 27 | #import "WTUtility.h" 28 | #import "Singleton.h" 29 | 30 | //View 😙😙😙😙😙😙😙😙😙😙 31 | #import "UIButton+WT.h" 32 | #import "WTTextField.h" 33 | 34 | #endif 35 | //导入的东西 END😊😊😊😊😊😊😊😊😊😊😊😊😊😊 36 | 37 | #define USDF [NSUserDefaults standardUserDefaults] 38 | 39 | //获取最上层的window 40 | #define WTTopWindow [[UIApplication sharedApplication].windows lastObject] 41 | //弱引用申明 42 | #define WSELF __weak __typeof(self) weakSelf = self; 43 | 44 | #define SFM(x) ([NSString stringWithFormat:@"%@", (x)]) 45 | 46 | #define WTAppDelegate ((AppDelegate *) [[UIApplication sharedApplication] delegate]) 47 | #define WTUserDefaults [NSUserDefaults standardUserDefaults] 48 | 49 | #define KStatusBarHeight [[UIApplication sharedApplication] statusBarFrame].size.height 50 | #define KNavBarHeight 44.0 51 | #define KTabBarHeight ([[UIApplication sharedApplication] statusBarFrame].size.height>20?83:49) 52 | #define KTopHeight (KStatusBarHeight + KNavBarHeight) 53 | 54 | //状态栏高度 55 | #define WTStatus_Bar_Height [[UIApplication sharedApplication] statusBarFrame].size.height 56 | //NavBar高度 57 | #define WTNavigation_Bar_Height 44 58 | //状态栏 + 导航栏 高度 59 | #define WTStatus_And_Navigation_Height ((WTStatus_Bar_Height) + (WTNavigation_Bar_Height)) 60 | //底部tab高度 61 | #define WTTab_Bar_Height ([[UIApplication sharedApplication] statusBarFrame].size.height>20?83:49) 62 | 63 | 64 | //通知中心 65 | #define WTNotificationCenter [NSNotificationCenter defaultCenter] 66 | #define WTScreenHeight [UIScreen mainScreen].bounds.size.height 67 | #define WTScreenWidth [UIScreen mainScreen].bounds.size.width 68 | #define WTDeviceHeight [UIScreen mainScreen].bounds.size.height 69 | #define WTDeviceWidth [UIScreen mainScreen].bounds.size.width 70 | #define PI 3.14159265358979323846 71 | 72 | #define WTStrIsEmpty(str) ([str isKindOfClass:[NSNull class]] || [str length] < 1 ? YES : NO || [str isEqualToString:@"(null)"] || [str isEqualToString:@"null"]) 73 | //随机色 74 | #define WTRandomColor [UIColor colorWithRed:arc4random_uniform(256) / 255.0 green:arc4random_uniform(256) / 255.0 blue:arc4random_uniform(256) / 255.0 alpha:1.0] 75 | 76 | // RGB颜色 77 | #define WTColor(r, g, b) [UIColor colorWithRed:(r) / 255.0 green:(g) / 255.0 blue:(b) / 255.0 alpha:1.0] 78 | 79 | #define WTAlphaColor(r, g, b, a) [UIColor colorWithRed:r / 255.0 green:g / 255.0 blue:b / 255.0 alpha:a] 80 | #define WTHexColor(X) [UIColor colorWithRed:((float) ((X & 0xFF0000) >> 16)) / 255.0 green:((float) ((X & 0xFF00) >> 8)) / 255.0 blue:((float) (X & 0xFF)) / 255.0 alpha:1.0] 81 | #define WTHexColorA(X, A) [UIColor colorWithRed:((float) ((X & 0xFF0000) >> 16)) / 255.0 green:((float) ((X & 0xFF00) >> 8)) / 255.0 blue:((float) (X & 0xFF)) / 255.0 alpha:A] 82 | 83 | // 是否为iOS9,获得系统版本 84 | #define WTIOS9 ([[UIDevice currentDevice].systemVersion doubleValue] >= 9.0) 85 | 86 | // 是否为iOS7,获得系统版本 87 | #define WTIOS7 ([[UIDevice currentDevice].systemVersion doubleValue] >= 7.0) 88 | 89 | // 是否为iOS8,获得系统版本 90 | #define WTIOS8 ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) 91 | // 是否为iOS6,获得系统版本 92 | #define WTIOS6 ([[UIDevice currentDevice].systemVersion doubleValue] <= 6.1) 93 | 94 | #define iPhone5_Screen ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO) 95 | #define iPhone6_Screen ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(750, 1334), [[UIScreen mainScreen] currentMode].size) : NO) 96 | #define iPhone6Plus_Screen ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1242, 2208), [[UIScreen mainScreen] currentMode].size) : NO) 97 | #define IPHONEX_SCREEN ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO) // 375 * 812 98 | 99 | -------------------------------------------------------------------------------- /WTSDK/Tool/WTUtility.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // WTUtility.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/9/27. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "WTConst.h" 10 | #import 11 | #import 12 | @interface WTUtility : NSObject 13 | 14 | /** 计算两个经纬的距离 */ 15 | + (double)calculateDistanceWithLatitude:(NSString *)latitudeOne andLongitude:(NSString *)longitudeOne twoDistanceWithLatitude:(NSString *)latitudeTwo andLongitude:(NSString *)longitudeTwo; 16 | 17 | + (void)saveUserInfoDic:(NSMutableDictionary *)dic; 18 | 19 | + (void)saveLastUserName:(NSString *)userName password:(NSString *)password; 20 | 21 | + (NSDictionary *)getUserNameAndPasswordInfoDic; 22 | 23 | + (void)removeUserInfoDic; 24 | 25 | + (void)removeUserNameAndPasswordInfoDic; 26 | 27 | + (NSMutableDictionary *)getUserInfoDic; 28 | 29 | + (BOOL)isASCII:(NSString *)character; 30 | 31 | + (BOOL)isSpecialCharacter:(NSString *)character; 32 | 33 | // 验证是否是数字 34 | + (BOOL)isNumber:(NSString *)character; 35 | 36 | /** 37 | * 震动效果 38 | */ 39 | + (CAKeyframeAnimation *)shakeAnimation; 40 | 41 | //纯颜色图片 42 | + (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size; 43 | 44 | /** 45 | * 代码执行时间0为很多次 46 | */ 47 | void code_RunTime(int times, void (^block)(void)); 48 | 49 | /** 50 | * 延迟执行 51 | */ 52 | void after_Run(float time, void (^block)(void)); 53 | 54 | /** 55 | * 是否连接到网络 56 | */ 57 | + (BOOL)connectedToNetwork; 58 | 59 | /** 60 | * 分割 钱字符串 61 | */ 62 | + (NSMutableString *)sepearteMoneyByString:(NSMutableString *)money; 63 | 64 | /** 65 | * 按钮点击事件 66 | */ 67 | + (void)btnSuddenlyTouch:(UIButton *)senderBtn; 68 | 69 | 70 | 71 | /** 72 | * 随机 73 | */ 74 | + (NSString *)randomStr; 75 | 76 | /** 77 | * 能否使用相机 不能用就alertview提示下 78 | */ 79 | + (BOOL)canUseCamera; 80 | 81 | /** 根据UIImage压缩后的NSDate第一个字节返回对应的图片类型 */ 82 | + (NSString *)typeForImageData:(NSData *)data; 83 | 84 | /** 返回文件大小 */ 85 | + (float)calculateFileSizeInUnit:(unsigned long long)contentLength; 86 | 87 | /** 返回文件大小的单位 */ 88 | + (NSString *)calculateUnit:(unsigned long long)contentLength; 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /WTSDK/Tool/WTUtility.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // WTUtility.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/9/27. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "SystemConfiguration/SystemConfiguration.h" 10 | #import "UIImage+WT.h" 11 | #import "WTUtility.h" 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | #include 18 | 19 | #define ORIGINAL_MAX_WIDTH 640.0f 20 | @implementation WTUtility 21 | 22 | /** 计算两个经纬的距离 */ 23 | + (double)calculateDistanceWithLatitude:(NSString *)latitudeOne andLongitude:(NSString *)longitudeOne twoDistanceWithLatitude:(NSString *)latitudeTwo andLongitude:(NSString *)longitudeTwo { 24 | CLLocation *orig = [[CLLocation alloc] initWithLatitude:latitudeOne.doubleValue longitude:longitudeOne.doubleValue]; 25 | CLLocation *dist = [[CLLocation alloc] initWithLatitude:latitudeTwo.doubleValue longitude:longitudeTwo.doubleValue]; 26 | 27 | CLLocationDistance kilometers = [orig distanceFromLocation:dist] / 1000; 28 | NSLog(@"距离:%f", kilometers); 29 | 30 | return kilometers; 31 | } 32 | 33 | + (void)saveLastUserName:(NSString *)userName password:(NSString *)password { 34 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 35 | NSDictionary *dic = @{ @"userName" : userName, 36 | @"password" : password }; 37 | [userDefaults setObject:dic forKey:@"UserNameAndPasswordDic"]; 38 | } 39 | 40 | + (NSDictionary *)getUserNameAndPasswordInfoDic { 41 | return [NSDictionary dictionaryWithDictionary:[[NSUserDefaults standardUserDefaults] objectForKey:@"UserNameAndPasswordDic"]]; 42 | } 43 | + (void)saveUserInfoDic:(NSMutableDictionary *)dic { 44 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 45 | [userDefaults setObject:dic forKey:@"UserModelDic"]; 46 | [userDefaults synchronize]; 47 | } 48 | 49 | + (void)removeUserInfoDic { 50 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 51 | [userDefaults removeObjectForKey:@"UserModelDic"]; 52 | } 53 | 54 | + (void)removeUserNameAndPasswordInfoDic { 55 | NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; 56 | [userDefaults removeObjectForKey:@"UserNameAndPasswordDic"]; 57 | } 58 | + (NSMutableDictionary *)getUserInfoDic { 59 | return [NSMutableDictionary dictionaryWithDictionary:[[NSUserDefaults standardUserDefaults] objectForKey:@"UserModelDic"]]; 60 | } 61 | 62 | // 纯颜色图片 63 | + (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size { 64 | CGRect rect = CGRectMake(0, 0, size.width, size.height); 65 | UIGraphicsBeginImageContext(rect.size); 66 | CGContextRef context = UIGraphicsGetCurrentContext(); 67 | CGContextSetFillColorWithColor(context, [color CGColor]); 68 | CGContextFillRect(context, rect); 69 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 70 | UIGraphicsEndImageContext(); 71 | return image; 72 | } 73 | 74 | //验证是否ASCII码 75 | + (BOOL)isASCII:(NSString *)Character { 76 | NSCharacterSet *cs; 77 | cs = [NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@/:;()¥「」!,.?<>£"、[]{}#%-*+=_\\|~<>$€^•'@#$%^&*()_+'\"/" 78 | ""]; 79 | NSRange specialrang = [Character rangeOfCharacterFromSet:cs]; 80 | if (specialrang.location != NSNotFound) { 81 | return YES; 82 | } 83 | return NO; 84 | } 85 | //验证是含本方法定义的 “特殊字符” 86 | + (BOOL)isSpecialCharacter:(NSString *)Character { 87 | NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"@/:;()¥「」!,.?<>£"、[]{}#%-*+=_\\|~<>$€^•'@#$%^&*()_+'\"/" 88 | ""]; 89 | NSRange specialrang = [Character rangeOfCharacterFromSet:set]; 90 | if (specialrang.location != NSNotFound) { 91 | return YES; 92 | } 93 | return NO; 94 | } 95 | 96 | // 验证是否是数字 97 | + (BOOL)isNumber:(NSString *)Character { 98 | NSCharacterSet *cs; 99 | cs = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"]; 100 | NSRange specialrang = [Character rangeOfCharacterFromSet:cs]; 101 | if (specialrang.location != NSNotFound) { 102 | return YES; 103 | } 104 | return NO; 105 | } 106 | //震动效果 107 | + (CAKeyframeAnimation *)shakeAnimation { 108 | CAKeyframeAnimation *shake = [CAKeyframeAnimation animationWithKeyPath:@"transform"]; 109 | shake.values = @[ [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(-5.0f, 0.0f, 0.0f)], [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(5.0f, 0.0f, 0.0f)] ]; 110 | shake.autoreverses = YES; 111 | shake.repeatCount = 2.0f; 112 | shake.duration = 0.07f; 113 | return shake; 114 | //[Btn.layer addAnimation:shake forKey:nil]; 115 | } 116 | 117 | /** 118 | * 代码执行时间 119 | */ 120 | void WTUseTime(void (^block)(void)) { 121 | mach_timebase_info_data_t info; 122 | if (mach_timebase_info(&info) != KERN_SUCCESS) return; 123 | uint64_t start = mach_absolute_time(); 124 | block(); 125 | uint64_t end = mach_absolute_time(); 126 | uint64_t elapsed = end - start; 127 | uint64_t nanos = elapsed * info.numer / info.denom; 128 | NSLog(@"⏰ %f", (CGFloat) nanos / NSEC_PER_SEC); 129 | } 130 | /** 131 | * 代码执行时间(循环XXXXX次) 132 | */ 133 | void code_RunTime(int times, void (^block)(void)) { 134 | int TureTime = times ? times : 10000; 135 | WTUseTime(^{ 136 | for (int i = 0; i < TureTime; i++) { 137 | block(); 138 | } 139 | }); 140 | } 141 | 142 | /** 143 | * 延迟执行 144 | */ 145 | void after_Run(float time, void (^block)(void)) { 146 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(time * NSEC_PER_SEC)), dispatch_get_main_queue(), block); 147 | } 148 | 149 | + (BOOL)connectedToNetwork { 150 | // 创建零地址,0.0.0.0的地址表示查询本机的网络连接状态 151 | struct sockaddr_in zeroAddress; //sockaddr_in是与sockaddr等价的数据结构 152 | bzero(&zeroAddress, sizeof(zeroAddress)); 153 | zeroAddress.sin_len = sizeof(zeroAddress); 154 | zeroAddress.sin_family = AF_INET; //sin_family是地址家族,一般都是“AF_xxx”的形式。通常大多用的是都是AF_INET,代表TCP/IP协议族 155 | 156 | SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *) &zeroAddress); //创建测试连接的引用: 157 | SCNetworkReachabilityFlags flags; 158 | 159 | BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags); 160 | CFRelease(defaultRouteReachability); 161 | 162 | if (!didRetrieveFlags) { 163 | printf("Error. Could not recover network reachability flagsn"); 164 | return NO; 165 | } 166 | 167 | /** 168 | * kSCNetworkReachabilityFlagsReachable: 能够连接网络 169 | * kSCNetworkReachabilityFlagsConnectionRequired: 能够连接网络,但是首先得建立连接过程 170 | * kSCNetworkReachabilityFlagsIsWWAN: 判断是否通过蜂窝网覆盖的连接, 171 | * 比如EDGE,GPRS或者目前的3G.主要是区别通过WiFi的连接. 172 | * 173 | */ 174 | BOOL isReachable = ((flags & kSCNetworkFlagsReachable) != 0); 175 | BOOL needsConnection = ((flags & kSCNetworkFlagsConnectionRequired) != 0); 176 | 177 | // NSLog(@"------%d",isReachable); 178 | // NSLog(@"------%d",needsConnection); 179 | //return (isReachable && !needsConnection) ? NO : YES;//反向测试 180 | return (isReachable && !needsConnection) ? YES : NO; 181 | } 182 | 183 | + (NSMutableString *)sepearteMoneyByString:(NSMutableString *)money { 184 | NSInteger three = 0; 185 | NSInteger slong = money.length; 186 | while (slong--) { 187 | three++; 188 | if (three == 3) { 189 | three = 0; 190 | [money insertString:@" " atIndex:slong]; 191 | } 192 | } 193 | return money; 194 | } 195 | 196 | //保证在scrollview上的Btn也有点击效果 197 | + (void)btnSuddenlyTouch:(UIButton *)senderBtn { 198 | senderBtn.selected = !senderBtn.isSelected; 199 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 200 | senderBtn.selected = !senderBtn.isSelected; 201 | }); 202 | } 203 | 204 | 205 | //随机 206 | + (NSString *)randomStr { 207 | const int N = 5; 208 | NSString *sourceString = @"ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 209 | NSMutableString *result = [[NSMutableString alloc] init]; 210 | // srand((int)time(0)); 211 | for (int i = 0; i < N; i++) { 212 | [result appendString:[sourceString substringWithRange:NSMakeRange(rand() % [sourceString length], 1)]]; 213 | } 214 | return result; 215 | } 216 | 217 | /** 218 | * 能否使用相机 219 | */ 220 | + (BOOL)canUseCamera { 221 | NSString *mediaType = AVMediaTypeVideo; 222 | AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType]; 223 | if (authStatus == AVAuthorizationStatusRestricted) { 224 | NSLog(@"Restricted"); 225 | } else if (authStatus == AVAuthorizationStatusDenied) { 226 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" 227 | message:@"请在设备的设置-隐私-相机 中允许访问相机。" 228 | delegate:self 229 | cancelButtonTitle:@"确定" 230 | otherButtonTitles:nil]; 231 | [alert show]; 232 | return NO; 233 | } else if (authStatus == AVAuthorizationStatusAuthorized) { //允许访问 234 | return YES; 235 | } else if (authStatus == AVAuthorizationStatusNotDetermined) { 236 | [AVCaptureDevice requestAccessForMediaType:mediaType 237 | completionHandler:^(BOOL granted) { 238 | if (granted) { //点击允许访问时调用 239 | //用户明确许可与否,媒体需要捕获,但用户尚未授予或拒绝许可。 240 | NSLog(@"Granted access to %@", mediaType); 241 | } else { 242 | NSLog(@"Not granted access to %@", mediaType); 243 | } 244 | }]; 245 | } else { 246 | NSLog(@"Unknown authorization status"); 247 | } 248 | 249 | return YES; 250 | } 251 | 252 | /** 根据UIImage压缩后的NSDate第一个字节返回对应的图片类型 */ 253 | + (NSString *)typeForImageData:(NSData *)data { 254 | uint8_t c; 255 | [data getBytes:&c length:1]; 256 | switch (c) { 257 | 258 | case 0xFF: 259 | return @"image/jpeg"; 260 | 261 | case 0x89: 262 | return @"image/png"; 263 | 264 | case 0x47: 265 | return @"image/gif"; 266 | 267 | case 0x49: 268 | case 0x4D: 269 | return @"image/tiff"; 270 | } 271 | 272 | return nil; 273 | } 274 | + (float)calculateFileSizeInUnit:(unsigned long long)contentLength 275 | { 276 | if(contentLength >= pow(1024, 3)) 277 | return (float) (contentLength / (float)pow(1024, 3)); 278 | else if(contentLength >= pow(1024, 2)) 279 | return (float) (contentLength / (float)pow(1024, 2)); 280 | else if(contentLength >= 1024) 281 | return (float) (contentLength / (float)1024); 282 | else 283 | return (float) (contentLength); 284 | } 285 | + (NSString *)calculateUnit:(unsigned long long)contentLength 286 | { 287 | if(contentLength >= pow(1024, 3)) 288 | return @"GB"; 289 | else if(contentLength >= pow(1024, 2)) 290 | return @"MB"; 291 | else if(contentLength >= 1024) 292 | return @"KB"; 293 | else 294 | return @"Bytes"; 295 | } 296 | 297 | 298 | @end 299 | -------------------------------------------------------------------------------- /WTSDK/View/WTLabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // WTLabel.h 3 | // PicMovie 4 | // 5 | // Created by 张威庭 on 2017/6/27. 6 | // Copyright © 2017年 PicMovie. All rights reserved. 7 | // 8 | 9 | #import 10 | typedef NS_ENUM (NSInteger, WTTextAlignmentType) { 11 | 12 | WTTextAlignmentTypeLeftTop = 0, 13 | 14 | WTTextAlignmentTypeRightTop = 1, 15 | 16 | WTTextAlignmentTypeLeftBottom = 2, 17 | 18 | WTTextAlignmentTypeRightBottom = 3, 19 | 20 | WTTextAlignmentTypeTopCenter = 4, 21 | 22 | WTTextAlignmentTypeBottomCenter = 5, 23 | 24 | WTTextAlignmentTypeLeft = 6, 25 | 26 | WTTextAlignmentTypeRight = 7, 27 | 28 | WTTextAlignmentTypeCenter = 8, 29 | 30 | }; 31 | @interface WTLabel : UILabel 32 | @property (nonatomic,assign) WTTextAlignmentType textAlignmentType; 33 | @end 34 | -------------------------------------------------------------------------------- /WTSDK/View/WTLabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // WTLabel.m 3 | // PicMovie 4 | // 5 | // Created by 张威庭 on 2017/6/27. 6 | // Copyright © 2017年 PicMovie. All rights reserved. 7 | // 8 | 9 | #import "WTLabel.h" 10 | 11 | @implementation WTLabel 12 | 13 | //自定义UILabel 14 | // 重写label的textRectForBounds方法 15 | - (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines { 16 | CGRect rect = [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines]; 17 | switch (self.textAlignmentType) { 18 | case WTTextAlignmentTypeLeftTop: { 19 | rect.origin = bounds.origin; 20 | } 21 | break; 22 | case WTTextAlignmentTypeRightTop: { 23 | rect.origin = CGPointMake(CGRectGetMaxX(bounds) - rect.size.width, bounds.origin.y); 24 | } 25 | break; 26 | case WTTextAlignmentTypeLeftBottom: { 27 | rect.origin = CGPointMake(bounds.origin.x, CGRectGetMaxY(bounds) - rect.size.height); 28 | } 29 | break; 30 | case WTTextAlignmentTypeRightBottom: { 31 | rect.origin = CGPointMake(CGRectGetMaxX(bounds) - rect.size.width, CGRectGetMaxY(bounds) - rect.size.height); 32 | } 33 | break; 34 | case WTTextAlignmentTypeTopCenter: { 35 | rect.origin = CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(rect)) / 2, CGRectGetMaxY(bounds) - rect.origin.y); 36 | } 37 | break; 38 | case WTTextAlignmentTypeBottomCenter: { 39 | rect.origin = CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(rect)) / 2, CGRectGetMaxY(bounds) - CGRectGetMaxY(bounds) - rect.size.height); 40 | } 41 | break; 42 | case WTTextAlignmentTypeLeft: { 43 | rect.origin = CGPointMake(0, rect.origin.y); 44 | } 45 | break; 46 | case WTTextAlignmentTypeRight: { 47 | rect.origin = CGPointMake(rect.origin.x, 0); 48 | } 49 | break; 50 | case WTTextAlignmentTypeCenter: { 51 | rect.origin = CGPointMake((CGRectGetWidth(bounds) - CGRectGetWidth(rect)) / 2, (CGRectGetHeight(bounds) - CGRectGetHeight(rect)) / 2); 52 | } 53 | break; 54 | 55 | default: 56 | break; 57 | } 58 | return rect; 59 | } 60 | - (void)drawTextInRect:(CGRect)rect { 61 | CGRect textRect = [self textRectForBounds:rect limitedToNumberOfLines:self.numberOfLines]; 62 | [super drawTextInRect:textRect]; 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /WTSDK/View/WTTextField.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // WTTextField.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WTTextField : UITextField 12 | 13 | /** 右边也加placeHolder */ 14 | - (void)addRightPlaceHolder:(NSString *)placeHolder; 15 | 16 | /** 认为是电话号码 按电话号码的限制输入 */ 17 | @property (nonatomic, assign, getter=isTelePhone) BOOL telePhone; 18 | 19 | /** 认为是身份证 加个button X */ 20 | @property (nonatomic, assign, getter=isIdentityInput) BOOL identityInput; 21 | 22 | /** 纯数字形式的输入 */ 23 | @property (nonatomic, assign, getter=isNumber) BOOL number; 24 | 25 | /** 数字形式的输入 可以有小数点 点后最多两位数 */ 26 | @property (nonatomic, assign, getter=isNumber_dot) BOOL number_dot; 27 | 28 | /** 限制特殊字符的输入 */ 29 | @property (nonatomic, assign, getter=isDisableSpecialChat) BOOL disableSpecialChat; 30 | 31 | /** 必须是 ASCII字符 */ 32 | @property (nonatomic, assign, getter=isMust_ASCII) BOOL must_ASCII; 33 | 34 | /** 强制按字符长度计算限制文本的最大长度 (一个中文算两个字符!) */ 35 | @property (nonatomic, assign) NSUInteger maxCharactersLength; 36 | 37 | /** 强制按text.length长度计算限制文本的最大长度 */ 38 | @property (nonatomic, assign) NSUInteger maxTextLength; 39 | 40 | - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; 41 | - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField; 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /WTSDK/View/WTTextField.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // WTTextField.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "NSString+WT.h" 10 | #import "WTTextField.h" 11 | #import 12 | static const char *PlaceLabel = "PlaceLabel"; 13 | @implementation WTTextField 14 | 15 | //重载方法,控制弹出选项 16 | - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { 17 | if (action == @selector(paste:)) //过滤粘贴操作 18 | { 19 | return NO; 20 | } else if (action == @selector(copy:)) //过滤赋值操作 21 | { 22 | return NO; 23 | } else if (action == @selector(select:)) //过滤选择操作 24 | { 25 | return NO; 26 | } else if (action == @selector(selectAll:)) //过滤选择全部操作 27 | { 28 | return NO; 29 | } 30 | //其它的操作不过滤 31 | return [super canPerformAction:action withSender:sender]; 32 | } 33 | 34 | - (void)dealloc { 35 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 36 | } 37 | 38 | - (instancetype)initWithFrame:(CGRect)frame { 39 | self = [super initWithFrame:frame]; 40 | if (self) { 41 | if (([[[UIDevice currentDevice] systemVersion] floatValue] > 8.0)) { 42 | self.delegate = (id) self; 43 | } else { 44 | } 45 | } 46 | return self; 47 | } 48 | 49 | - (void)awakeFromNib { 50 | if (([[[UIDevice currentDevice] systemVersion] floatValue] > 8.0)) { 51 | self.delegate = (id) self; 52 | } else { 53 | } 54 | } 55 | #pragma mark - 这里可以控制里面文字的间距 56 | //- (CGRect)editingRectForBounds:(CGRect)bounds { 57 | // return CGRectInset(bounds, 8, 0); 58 | //} 59 | // 60 | //- (CGRect)textRectForBounds:(CGRect)bounds { 61 | // return CGRectInset(bounds, 8, 0); 62 | //} 63 | 64 | - (UILabel *)placeHolderLabel { 65 | return objc_getAssociatedObject(self, PlaceLabel); 66 | } 67 | - (void)setPlaceHolderLabel:(UILabel *)placeHolderLabel { 68 | objc_setAssociatedObject(self, PlaceLabel, placeHolderLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 69 | } 70 | 71 | - (void)addRightPlaceHolder:(NSString *)placeHolder { 72 | CGFloat W = [placeHolder widthWithFont:12 h:20]; 73 | UILabel *La = [[UILabel alloc] initWithFrame:CGRectMake(self.frame.size.width - W - 8, 0, W, self.frame.size.height)]; 74 | La.text = placeHolder; 75 | La.textColor = [UIColor lightGrayColor]; 76 | La.font = [UIFont systemFontOfSize:12]; 77 | [self addSubview:La]; 78 | [self setPlaceHolderLabel:La]; 79 | // [[NSNotificationCenter defaultCenter] removeObserver:self]; 80 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChange) name:UITextFieldTextDidChangeNotification object:self]; 81 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldChange) name:UITextFieldTextDidEndEditingNotification object:self]; 82 | } 83 | 84 | - (void)textFieldChange { 85 | [self placeHolderLabel].hidden = self.text.length; 86 | } 87 | 88 | //认为是电话号码 按电话号码的限制输入 89 | - (void)setTelePhone:(BOOL)telePhone { 90 | _telePhone = telePhone; 91 | self.keyboardType = UIKeyboardTypeNumberPad; 92 | } 93 | 94 | - (void)setIdentityInput:(BOOL)identityInput { 95 | _identityInput = identityInput; 96 | self.keyboardType = UIKeyboardTypeNumberPad; 97 | _maxTextLength = 24; 98 | } 99 | 100 | //纯数字形式的输入 101 | - (void)setNumber:(BOOL)number { 102 | _number = number; 103 | self.keyboardType = UIKeyboardTypeNumberPad; 104 | } 105 | 106 | //数字形式的输入 可以有小数点 点后最多两位数 107 | - (void)setNumber_dot:(BOOL)number_dot { 108 | _number_dot = number_dot; 109 | self.keyboardType = UIKeyboardTypeDecimalPad; 110 | } 111 | 112 | //限制特殊字符的输入 113 | - (void)setDisableSpecialChat:(BOOL)disableSpecialChat { 114 | _disableSpecialChat = disableSpecialChat; 115 | } 116 | 117 | //必须是 ASCII字符 118 | - (void)setMust_ASCII:(BOOL)must_ASCII { 119 | _must_ASCII = must_ASCII; 120 | self.keyboardType = UIKeyboardTypeASCIICapable; 121 | } 122 | 123 | //强制按字符长度计算限制文本的最大长度 (一个中文算两个字符!) 加强判断 设另个为0 124 | - (void)setMaxCharactersLength:(NSUInteger)maxCharactersLength { 125 | _maxCharactersLength = maxCharactersLength; 126 | _maxTextLength = 0; 127 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil]; 128 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldDidChange) name:UITextFieldTextDidChangeNotification object:self]; 129 | } 130 | 131 | //强制按text.length长度计算限制文本的最大长度 加强判断 设另个为0 132 | - (void)setMaxTextLength:(NSUInteger)maxTextLength { 133 | _maxTextLength = maxTextLength; 134 | _maxCharactersLength = 0; 135 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextFieldTextDidChangeNotification object:nil]; 136 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldDidChange) name:UITextFieldTextDidChangeNotification object:nil]; 137 | } 138 | 139 | //NSNotification 140 | - (void)textFieldDidChange { 141 | if (_maxCharactersLength) { 142 | if (self.markedTextRange == nil && [self.text textLength] > _maxCharactersLength) { 143 | self.text = [self.text limitMaxTextShow:_maxCharactersLength]; 144 | } 145 | } 146 | if (_maxTextLength) { 147 | if (self.markedTextRange == nil && self.text.length > _maxTextLength) { 148 | self.text = [self.text substringToIndex:_maxTextLength]; 149 | } 150 | } 151 | } 152 | 153 | #pragma mark - textField Delegate 154 | 155 | - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 156 | if (range.length >= 1) { 157 | return YES; 158 | } 159 | //电话号码 160 | if (_telePhone) { 161 | NSString *Mix = [textField.text addStr:string]; 162 | if (Mix.delSpace.length > 11 || ![string isNumber]) { 163 | return NO; 164 | } 165 | if (Mix.length == 3 || Mix.length == 8) { 166 | textField.text = [Mix addStr:@" "]; 167 | return NO; 168 | } 169 | return YES; 170 | } 171 | //数字 172 | if (_number) { 173 | if (![string isNumber]) { 174 | return NO; 175 | } 176 | } 177 | //可以有小数点的 数字 小数点有判断 178 | if (_number_dot) { 179 | if (![string isNumber] && ![string isEqualToString:@"."]) { 180 | return NO; 181 | } 182 | if ([string isEqualToString:@"."]) { 183 | if (textField.text.length == 0 || [textField.text rangeOfString:@"."].location != NSNotFound) { 184 | return NO; 185 | } 186 | } else { //输入数字 187 | NSUInteger at = [textField.text rangeOfString:@"."].location; 188 | if (at != NSNotFound) { 189 | if (textField.text.length - at > 2) { //点后最多两位数 190 | return NO; 191 | } 192 | } 193 | } 194 | } 195 | 196 | if (_maxTextLength && textField.text.length >= _maxTextLength) { 197 | return NO; 198 | } 199 | 200 | if (_maxCharactersLength && textField.text.textLength >= _maxCharactersLength) { 201 | return NO; 202 | } 203 | 204 | if (_disableSpecialChat && [string isSpecialCharacter]) { 205 | return NO; 206 | } 207 | 208 | if (_must_ASCII && ![string isASCII]) { 209 | return NO; 210 | } 211 | 212 | return YES; 213 | } 214 | 215 | - (BOOL)textFieldShouldReturn:(UITextField *)textField { 216 | [textField resignFirstResponder]; 217 | return YES; 218 | } 219 | 220 | - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField { 221 | // 身份证 加个button X 222 | if (_identityInput) { 223 | textField.inputAccessoryView = [self createActionBar]; 224 | } else { 225 | textField.inputAccessoryView = nil; 226 | } 227 | return YES; 228 | } 229 | 230 | - (UIToolbar *)createActionBar { 231 | UIToolbar *actionBar = [[UIToolbar alloc] init]; 232 | [actionBar sizeToFit]; 233 | UIBarButtonItem *L = [[UIBarButtonItem alloc] initWithTitle:@" O " style:UIBarButtonItemStylePlain target:self action:@selector(add_O_Char)]; 234 | UIBarButtonItem *R = [[UIBarButtonItem alloc] initWithTitle:@" X " style:UIBarButtonItemStylePlain target:self action:@selector(add_X_Char)]; 235 | UIBarButtonItem *flexible = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; 236 | [actionBar setItems:[NSArray arrayWithObjects:L, flexible, R, nil]]; 237 | return actionBar; 238 | } 239 | 240 | - (void)add_O_Char { 241 | if (self.text.length < 24) { 242 | self.text = [self.text stringByAppendingString:@"O"]; 243 | } 244 | } 245 | - (void)add_X_Char { 246 | if (self.text.length < 24) { 247 | self.text = [self.text stringByAppendingString:@"X"]; 248 | } 249 | } 250 | 251 | @end 252 | -------------------------------------------------------------------------------- /WTSDK/View/WTTextView.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // WTTextView.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WTTextView : UITextView 12 | 13 | /** 14 | * 提示用户输入的标语 15 | */ 16 | @property (nonatomic, copy) NSString *placeHolder; 17 | 18 | /** 19 | * 标语文本的颜色 20 | */ 21 | @property (nonatomic, strong) UIColor *placeHolderTextColor; 22 | 23 | /** 24 | * 获取自身文本占据有多少行 25 | */ 26 | - (NSUInteger)numberOfLinesOfText; 27 | 28 | /** 29 | * 获取每行的高度 30 | */ 31 | + (NSUInteger)maxCharactersPerLine; 32 | 33 | /** 34 | * 获取某个文本占据自身适应宽带的行数 35 | */ 36 | + (NSUInteger)numberOfLinesForMessage:(NSString *)text; 37 | 38 | /** 39 | * 边框啊 传空默认颜色或hex 宽默认1 40 | */ 41 | @property (nonatomic, copy) NSString *bor_c; 42 | 43 | /** 44 | * 强制按字符长度计算限制文本的最大长度 (一个中文算两个字符!) 45 | */ 46 | @property (nonatomic, assign) NSUInteger maxCharactersLength; 47 | /** 48 | * 强制按text.length长度计算限制文本的最大长度 49 | */ 50 | @property (nonatomic, assign) NSUInteger maxTextLength; 51 | /** 显示ToolBar */ 52 | @property (nonatomic, assign, getter=isShowToolBar) BOOL showToolBar; 53 | /** 点换行是取消响应 */ 54 | @property (nonatomic, assign, getter=isReturnToresign) BOOL returnToresign; 55 | @property (nonatomic, strong) UIToolbar *toolbar; 56 | /** 禁止使用表情字符 */ 57 | @property (nonatomic, assign, getter=isDisabelEmoji) BOOL disabelEmoji; 58 | 59 | - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text; 60 | - (BOOL)textViewShouldBeginEditing:(UITextView *)textView; 61 | - (void)textViewDidChange:(UITextView *)textView; 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /WTSDK/View/WTTextView.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // WTTextView.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "WTConst.h" 10 | #import "WTTextView.h" 11 | @implementation WTTextView 12 | 13 | - (void)setPlaceHolder:(NSString *)placeHolder { 14 | if ([placeHolder isEqualToString:_placeHolder]) { 15 | // return; 16 | } 17 | 18 | NSUInteger maxChars = [WTTextView maxCharactersPerLine]; 19 | if ([placeHolder length] > maxChars) { 20 | placeHolder = [placeHolder substringToIndex:maxChars - 8]; 21 | placeHolder = [[placeHolder stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] stringByAppendingFormat:@"..."]; 22 | } 23 | 24 | _placeHolder = placeHolder; 25 | // [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:self]; 26 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveTextDidChangeNotification:) name:UITextViewTextDidChangeNotification object:self]; 27 | [self setNeedsDisplay]; 28 | } 29 | 30 | - (void)setPlaceHolderTextColor:(UIColor *)placeHolderTextColor { 31 | if ([placeHolderTextColor isEqual:_placeHolderTextColor]) { 32 | return; 33 | } 34 | 35 | _placeHolderTextColor = placeHolderTextColor; 36 | [self setNeedsDisplay]; 37 | } 38 | 39 | #pragma mark - Message text view 40 | 41 | - (NSUInteger)numberOfLinesOfText { 42 | return [WTTextView numberOfLinesForMessage:self.text]; 43 | } 44 | 45 | + (NSUInteger)maxCharactersPerLine { 46 | return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) ? 33 : 109; 47 | } 48 | 49 | + (NSUInteger)numberOfLinesForMessage:(NSString *)text { 50 | return (text.length / [WTTextView maxCharactersPerLine]) + 1; 51 | } 52 | 53 | #pragma mark - Text view overrides 54 | 55 | - (void)setText:(NSString *)text { 56 | [super setText:text]; 57 | [self setNeedsDisplay]; 58 | } 59 | 60 | - (void)setAttributedText:(NSAttributedString *)attributedText { 61 | [super setAttributedText:attributedText]; 62 | [self setNeedsDisplay]; 63 | } 64 | 65 | - (void)setContentInset:(UIEdgeInsets)contentInset { 66 | [super setContentInset:contentInset]; 67 | [self setNeedsDisplay]; 68 | } 69 | 70 | - (void)setFont:(UIFont *)font { 71 | [super setFont:font]; 72 | [self setNeedsDisplay]; 73 | } 74 | 75 | - (void)setTextAlignment:(NSTextAlignment)textAlignment { 76 | [super setTextAlignment:textAlignment]; 77 | [self setNeedsDisplay]; 78 | } 79 | 80 | #pragma mark - Notifications 81 | 82 | - (void)didReceiveTextDidChangeNotification:(NSNotification *)notification { 83 | [self setNeedsDisplay]; 84 | } 85 | 86 | #pragma mark - Life cycle 87 | 88 | - (void)setup { 89 | _placeHolderTextColor = [UIColor lightGrayColor]; 90 | self.autoresizingMask = UIViewAutoresizingFlexibleWidth; 91 | self.scrollIndicatorInsets = UIEdgeInsetsMake(10.0f, 0.0f, 10.0f, 8.0f); 92 | self.contentInset = UIEdgeInsetsZero; 93 | self.scrollEnabled = YES; 94 | self.scrollsToTop = YES; 95 | self.userInteractionEnabled = YES; 96 | self.font = [UIFont systemFontOfSize:16.0f]; 97 | self.textColor = [UIColor blackColor]; 98 | self.backgroundColor = [UIColor whiteColor]; 99 | self.keyboardAppearance = UIKeyboardAppearanceDefault; 100 | self.keyboardType = UIKeyboardTypeDefault; 101 | self.returnKeyType = UIReturnKeySend; 102 | ; 103 | self.textAlignment = NSTextAlignmentJustified; 104 | 105 | self.autocorrectionType = UITextAutocorrectionTypeNo; 106 | self.autocapitalizationType = UITextAutocapitalizationTypeNone; 107 | self.enablesReturnKeyAutomatically = YES; 108 | } 109 | 110 | /** 111 | * 当控件是从xib storyboard中创建时,就会先调用这个方法initWithCoder:之后awakeFromNib:方法 112 | * 113 | */ 114 | - (id)initWithCoder:(NSCoder *)decoder { 115 | 116 | if (self = [super initWithCoder:decoder]) { 117 | 118 | [self setup]; 119 | } 120 | return self; 121 | } 122 | 123 | - (id)initWithFrame:(CGRect)frame { 124 | self = [super initWithFrame:frame]; 125 | if (self) { 126 | [self setup]; 127 | } 128 | return self; 129 | } 130 | 131 | - (void)dealloc { 132 | _placeHolder = nil; 133 | _placeHolderTextColor = nil; 134 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:self]; 135 | } 136 | 137 | #pragma mark - Drawing 138 | 139 | - (void)drawRect:(CGRect)rect { 140 | [super drawRect:rect]; 141 | if ([self.text length] == 0 && self.placeHolder) { 142 | CGRect placeHolderRect = CGRectMake(13.0f, 7.0f, rect.size.width, rect.size.height); 143 | [self.placeHolderTextColor set]; 144 | NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 145 | paragraphStyle.lineBreakMode = NSLineBreakByTruncatingTail; 146 | paragraphStyle.alignment = self.textAlignment; 147 | [self.placeHolder drawInRect:placeHolderRect withAttributes:@{ 148 | NSFontAttributeName : self.font ? self.font : [UIFont systemFontOfSize:13], 149 | NSForegroundColorAttributeName : self.placeHolderTextColor ? self.placeHolderTextColor : [UIColor lightGrayColor], 150 | NSParagraphStyleAttributeName : paragraphStyle 151 | }]; 152 | } 153 | } 154 | 155 | - (UIToolbar *)toolbar { 156 | if (_toolbar == nil) { 157 | UIToolbar *actionBar = [[UIToolbar alloc] init]; 158 | [actionBar sizeToFit]; 159 | UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle:@"完成" style:UIBarButtonItemStyleDone target:self action:@selector(wancheng)]; 160 | UIBarButtonItem *flexible = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; 161 | [actionBar setItems:[NSArray arrayWithObjects:flexible, doneButton, nil]]; 162 | _toolbar = actionBar; 163 | _toolbar.barStyle = UIBarStyleDefault; 164 | _toolbar.translucent = YES; 165 | } 166 | return _toolbar; 167 | } 168 | 169 | - (void)wancheng { 170 | [self endEditing:YES]; 171 | } 172 | 173 | /** 174 | * 边框啊 颜色 宽默认1 175 | */ 176 | - (void)setBor_c:(NSString *)bor_c { 177 | if ([bor_c isEqualToString:@"EVGO_Color"] || bor_c.length == 0) { 178 | [self border:[UIColor lightGrayColor] width:1]; 179 | return; 180 | } 181 | if (![bor_c hasPrefix:@"0x"]) { 182 | bor_c = [NSString stringWithFormat:@"0x%@", bor_c]; 183 | } 184 | // unsigned long red = strtoul([bor_c UTF8String],0,16); 185 | [self border:[UIColor lightGrayColor] width:1]; 186 | } 187 | 188 | //强制按字符长度计算限制文本的最大长度 (一个中文算两个字符!) 加强判断 设另个为0 189 | - (void)setMaxCharactersLength:(NSUInteger)maxCharactersLength { 190 | _maxCharactersLength = maxCharactersLength; 191 | _maxTextLength = 0; 192 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textViewDidChange) name:UITextViewTextDidChangeNotification object:self]; 193 | } 194 | 195 | //强制按text.length长度计算限制文本的最大长度 加强判断 设另个为0 196 | - (void)setMaxTextLength:(NSUInteger)maxTextLength { 197 | _maxTextLength = maxTextLength; 198 | self.delegate = (id) self; 199 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textViewDidChange) name:UITextViewTextDidChangeNotification object:self]; 200 | } 201 | 202 | - (void)setShowToolBar:(BOOL)showToolBar { 203 | _showToolBar = showToolBar; 204 | self.delegate = (id) self; 205 | } 206 | 207 | - (void)setDisabelEmoji:(BOOL)disabelEmoji { 208 | _disabelEmoji = disabelEmoji; 209 | self.delegate = (id) self; 210 | } 211 | 212 | //NSNotification 213 | - (void)textViewDidChange { 214 | if (_maxCharactersLength) { 215 | if (self.markedTextRange == nil && [self.text textLength] > _maxCharactersLength) { 216 | self.text = [self.text limitMaxTextShow:_maxCharactersLength]; 217 | } 218 | } 219 | if (_maxTextLength) { 220 | if (self.markedTextRange == nil && self.text.length > _maxTextLength) { 221 | self.text = [self.text substringToIndex:_maxTextLength]; 222 | } 223 | } 224 | [self setNeedsDisplay]; 225 | } 226 | 227 | - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { 228 | if ([text isEqualToString:@"\n"]) { 229 | [textView resignFirstResponder]; 230 | return NO; 231 | } 232 | if (range.length == 1) { 233 | return YES; 234 | } 235 | if (_maxTextLength && self.text.length > _maxTextLength) { 236 | return NO; 237 | } 238 | return YES; 239 | } 240 | 241 | - (BOOL)textViewShouldBeginEditing:(UITextView *)textView { 242 | if (self.showToolBar) { 243 | textView.inputAccessoryView = self.toolbar; 244 | } 245 | return YES; 246 | } 247 | 248 | - (void)textViewDidChange:(UITextView *)textView { 249 | [textView scrollRangeToVisible:NSMakeRange([textView.text length] - 1, 0)]; 250 | NSRange textRange = [textView selectedRange]; 251 | if (self.disabelEmoji && self.markedTextRange == nil) { 252 | [textView setText:textView.text.disableEmoji]; 253 | } 254 | [textView setSelectedRange:textRange]; 255 | } 256 | 257 | - (void)textViewDidEndEditing:(UITextView *)textView { 258 | } 259 | 260 | @end 261 | -------------------------------------------------------------------------------- /WTSDKExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // AppDelegate.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WTSDKExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // AppDelegate.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 18 | // Override point for customization after application launch. 19 | return YES; 20 | } 21 | 22 | - (void)applicationWillResignActive:(UIApplication *)application { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | - (void)applicationDidEnterBackground:(UIApplication *)application { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | - (void)applicationWillEnterForeground:(UIApplication *)application { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | - (void)applicationWillTerminate:(UIApplication *)application { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /WTSDKExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /WTSDKExample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /WTSDKExample/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 29 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 81 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /WTSDKExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /WTSDKExample/TestViewController.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // TestViewController.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 16/9/8. 6 | // Copyright © 2016年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TestViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WTSDKExample/TestViewController.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // TestViewController.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 16/9/8. 6 | // Copyright © 2016年 zwt. All rights reserved. 7 | // 8 | 9 | #import "TestViewController.h" 10 | #import "WTConst.h" 11 | @interface TestViewController () 12 | @property (weak, nonatomic) IBOutlet UILabel *htmlLabel; 13 | @property (weak, nonatomic) IBOutlet UILabel *htmlHeightLabel; 14 | 15 | @end 16 | 17 | @implementation TestViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | NSString *htmlStr = @"
Tate《WTSDK》 Tate_zwt star 源码在WTSDK文件夹里,如果你觉得不错的话,麻烦在GitHub上面点个Star,thank you all!"; 22 | [_htmlLabel htmlString:htmlStr]; 23 | [_htmlLabel tapGesture:^(UIGestureRecognizer *ges) { 24 | NSLog(@"我被触发了"); 25 | } numberOfTapsRequired:3]; 26 | 27 | [_htmlHeightLabel htmlString:htmlStr labelRowOfHeight:12]; 28 | } 29 | 30 | - (void)didReceiveMemoryWarning { 31 | [super didReceiveMemoryWarning]; 32 | // Dispose of any resources that can be recreated. 33 | } 34 | 35 | /* 36 | #pragma mark - Navigation 37 | 38 | // In a storyboard-based application, you will often want to do a little preparation before navigation 39 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 40 | // Get the new view controller using [segue destinationViewController]. 41 | // Pass the selected object to the new view controller. 42 | } 43 | */ 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /WTSDKExample/ViewController.h: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // ViewController.h 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WTSDKExample/ViewController.m: -------------------------------------------------------------------------------- 1 | // GitHub: https://github.com/Tate-zwt/WTSDK 2 | // ViewController.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "WTConst.h" 11 | @interface ViewController () 12 | @property (weak, nonatomic) IBOutlet UILabel *introducingLabel; 13 | 14 | @end 15 | 16 | @implementation ViewController 17 | 18 | - (void)viewDidLoad { 19 | [super viewDidLoad]; 20 | [_introducingLabel settingLabelHeightofRowString:@"源码在WTSDK文件夹里,如果你觉得不错的话,麻烦在GitHub上面点个Star,thank you all!"]; 21 | } 22 | 23 | - (void)didReceiveMemoryWarning { 24 | [super didReceiveMemoryWarning]; 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /WTSDKExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WTSDK 4 | // 5 | // Created by 张威庭 on 15/12/16. 6 | // Copyright © 2015年 zwt. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | --------------------------------------------------------------------------------