├── README.md
└── iOS-Category
├── iOS-Category.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ └── ZBB.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ └── ZBB.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── iOS-Category.xcscheme
│ └── xcschememanagement.plist
└── iOS-Category
├── NSArray+Safe.h
├── NSArray+Safe.m
├── NSAttributedString+Category.h
├── NSAttributedString+Category.m
├── NSData+CommonCryptor.h
├── NSData+CommonCryptor.m
├── NSDate+Category.h
├── NSDate+Category.m
├── NSDictionary+Category.h
├── NSDictionary+Category.m
├── NSDictionary+Safe.h
├── NSDictionary+Safe.m
├── NSMutableArray+Safe.h
├── NSMutableArray+Safe.m
├── NSMutableDictionary+Safe.h
├── NSMutableDictionary+Safe.m
├── NSMutableString+Safe.h
├── NSMutableString+Safe.m
├── NSObject+Category.h
├── NSObject+Category.m
├── NSObject+PerformBlock.h
├── NSObject+PerformBlock.m
├── NSObject+Swizzle.h
├── NSObject+Swizzle.m
├── NSString+Category.h
├── NSString+Category.m
├── NSString+DisplayTime.h
├── NSString+DisplayTime.m
├── NSString+MD5.h
├── NSString+MD5.m
├── NSString+Predicate.h
├── NSString+Predicate.m
├── NSString+Safe.h
├── NSString+Safe.m
├── UIButton+Category.h
├── UIButton+Category.m
├── UIColor+Category.h
├── UIColor+Category.m
├── UIImage+Category.h
├── UIImage+Category.m
├── UIMenuItem+Category.h
├── UIMenuItem+Category.m
├── UITableView+CellAnimation.h
├── UITableView+CellAnimation.m
├── UIView+Category.h
├── UIView+Category.m
├── UIView+Frame.h
└── UIView+Frame.m
/README.md:
--------------------------------------------------------------------------------
1 | # iOS 常用Category类别分享(持续更新)
2 | 以后会持续更新,可以继续关注哦!
3 | [简书地址](http://www.jianshu.com/p/68ba104b9061)
4 | # 前言
5 | 没有其他巴拉巴拉的一堆,直接上干货,分享自己从事iOS开发以来积累的Category工具类别,提高大家的开发效率!
6 | **PS:我会不定期进行更新,加入一些新的方法;**
7 |
8 | ------
9 | ##20.5.30更新
10 | 1.增加NSDate类一些常用的转换方法;
11 | 2.增加快速创建富文本字符串的方法;
12 | 3.优化了字典转字符串方法, 处理了转出来的字符串带/n和空格的情况;
13 | 4.NSString+Safe增加了stringWithFormat避免显示null的方法;
14 |
15 |
16 | ------
17 | ##18.5.22更新
18 | 1.优化了千分符方法;
19 | 2.将各个健壮性方法单独提取出来;
20 | 3.优化了覆盖及拦截method;
21 |
22 |
23 | ------
24 | ##17.8.25更新
25 | 1.进行了局部的重新排版;
26 | 2.添加了NSObject的一些分类方法(具体见下面内容);
27 | 3.合并了一些类目方法;
28 | 4.整理了整个项目文件夹,条目更加清晰;
29 | 5.添加了更多的注释;
30 |
31 |
32 | ------
33 | 这边我给大家分享的基本都是常用类,其中包括**NSObject**、 **NSString**、 **NSArray**、**NSDictionary**、**UIView**、**UIImage**、**UIButton**、**UIView**、**UIView**、**NSData**、**UIMenuItem**、**NSDate**。
34 | 这边把一些常用的工具类分享给了大家,基本每个方法都是我在实际项目因为某些需求写的、还有部分是网上找的。如果不会使用可以来询问我,发现错误请及时联系我,不喜勿喷,谢谢~
35 | 以后我还会持续更新的!如果各位下载的同学喜欢,请给点个星 ,谢谢啦!
36 |
37 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 3D5E53F62482358300637812 /* NSDate+Category.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D5E53F52482358300637812 /* NSDate+Category.m */; };
11 | 3D8217E11D3F45A20077850F /* NSAttributedString+Category.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D8217A61D3F45A20077850F /* NSAttributedString+Category.m */; };
12 | 3D8217E31D3F45A20077850F /* NSData+CommonCryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D8217AA1D3F45A20077850F /* NSData+CommonCryptor.m */; };
13 | 3D8217E41D3F45A20077850F /* NSDictionary+Category.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D8217AC1D3F45A20077850F /* NSDictionary+Category.m */; };
14 | 3D8217E81D3F45A20077850F /* NSString+Category.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D8217B41D3F45A20077850F /* NSString+Category.m */; };
15 | 3D8217EA1D3F45A20077850F /* NSString+MD5.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D8217B81D3F45A20077850F /* NSString+MD5.m */; };
16 | 3D8217EF1D3F45A20077850F /* UIButton+Category.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D8217C21D3F45A20077850F /* UIButton+Category.m */; };
17 | 3D8217F51D3F45A20077850F /* UIImage+Category.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D8217CE1D3F45A20077850F /* UIImage+Category.m */; };
18 | 3D8217F71D3F45A20077850F /* UIMenuItem+Category.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D8217D21D3F45A20077850F /* UIMenuItem+Category.m */; };
19 | 3D8217FB1D3F45A20077850F /* UIView+Category.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D8217DA1D3F45A20077850F /* UIView+Category.m */; };
20 | 3D8218091D3F5ECB0077850F /* NSString+Predicate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D8218081D3F5ECB0077850F /* NSString+Predicate.m */; };
21 | 3D82180F1D3F6A930077850F /* NSString+DisplayTime.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D82180E1D3F6A930077850F /* NSString+DisplayTime.m */; };
22 | 3DC904131F4D748700E56004 /* NSObject+Category.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DC904121F4D748700E56004 /* NSObject+Category.m */; };
23 | 3DC904161F4D790F00E56004 /* NSObject+PerformBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DC904151F4D790F00E56004 /* NSObject+PerformBlock.m */; };
24 | 3DC9041C1F4D7E6E00E56004 /* UIView+Frame.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DC9041B1F4D7E6E00E56004 /* UIView+Frame.m */; };
25 | 3DC9041F1F4D87E200E56004 /* UIColor+Category.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DC9041E1F4D87E200E56004 /* UIColor+Category.m */; };
26 | 3DC904221F4EAE2F00E56004 /* NSString+Safe.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DC904211F4EAE2F00E56004 /* NSString+Safe.m */; };
27 | 3DC904251F4EB8CD00E56004 /* NSMutableString+Safe.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DC904241F4EB8CD00E56004 /* NSMutableString+Safe.m */; };
28 | 3DD78BCD1F669053003B8E9F /* UITableView+CellAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD78BCC1F669053003B8E9F /* UITableView+CellAnimation.m */; };
29 | 3DFAD8EC20AEA1400067ACDE /* NSDictionary+Safe.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DFAD8EB20AEA1400067ACDE /* NSDictionary+Safe.m */; };
30 | 3DFAD8EF20AEA1870067ACDE /* NSMutableDictionary+Safe.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DFAD8EE20AEA1870067ACDE /* NSMutableDictionary+Safe.m */; };
31 | 3DFAD8F220AEA7F80067ACDE /* NSArray+Safe.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DFAD8F120AEA7F80067ACDE /* NSArray+Safe.m */; };
32 | 3DFAD8F520AEB58C0067ACDE /* NSMutableArray+Safe.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DFAD8F420AEB58C0067ACDE /* NSMutableArray+Safe.m */; };
33 | 3DFAD93820B2E0960067ACDE /* NSObject+Swizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DFAD93720B2E0950067ACDE /* NSObject+Swizzle.m */; };
34 | /* End PBXBuildFile section */
35 |
36 | /* Begin PBXCopyFilesBuildPhase section */
37 | 3D8217931D3F44C90077850F /* CopyFiles */ = {
38 | isa = PBXCopyFilesBuildPhase;
39 | buildActionMask = 2147483647;
40 | dstPath = "include/$(PRODUCT_NAME)";
41 | dstSubfolderSpec = 16;
42 | files = (
43 | );
44 | runOnlyForDeploymentPostprocessing = 0;
45 | };
46 | /* End PBXCopyFilesBuildPhase section */
47 |
48 | /* Begin PBXFileReference section */
49 | 3D5E53F42482358300637812 /* NSDate+Category.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDate+Category.h"; sourceTree = ""; };
50 | 3D5E53F52482358300637812 /* NSDate+Category.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSDate+Category.m"; sourceTree = ""; };
51 | 3D8217951D3F44C90077850F /* libiOS-Category.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libiOS-Category.a"; sourceTree = BUILT_PRODUCTS_DIR; };
52 | 3D8217A51D3F45A20077850F /* NSAttributedString+Category.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributedString+Category.h"; sourceTree = ""; };
53 | 3D8217A61D3F45A20077850F /* NSAttributedString+Category.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributedString+Category.m"; sourceTree = ""; };
54 | 3D8217A91D3F45A20077850F /* NSData+CommonCryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+CommonCryptor.h"; sourceTree = ""; };
55 | 3D8217AA1D3F45A20077850F /* NSData+CommonCryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+CommonCryptor.m"; sourceTree = ""; };
56 | 3D8217AB1D3F45A20077850F /* NSDictionary+Category.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Category.h"; sourceTree = ""; };
57 | 3D8217AC1D3F45A20077850F /* NSDictionary+Category.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+Category.m"; sourceTree = ""; };
58 | 3D8217B31D3F45A20077850F /* NSString+Category.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+Category.h"; sourceTree = ""; };
59 | 3D8217B41D3F45A20077850F /* NSString+Category.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+Category.m"; sourceTree = ""; };
60 | 3D8217B71D3F45A20077850F /* NSString+MD5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+MD5.h"; sourceTree = ""; };
61 | 3D8217B81D3F45A20077850F /* NSString+MD5.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+MD5.m"; sourceTree = ""; };
62 | 3D8217C11D3F45A20077850F /* UIButton+Category.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIButton+Category.h"; sourceTree = ""; };
63 | 3D8217C21D3F45A20077850F /* UIButton+Category.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIButton+Category.m"; sourceTree = ""; };
64 | 3D8217CD1D3F45A20077850F /* UIImage+Category.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Category.h"; sourceTree = ""; };
65 | 3D8217CE1D3F45A20077850F /* UIImage+Category.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Category.m"; sourceTree = ""; };
66 | 3D8217D11D3F45A20077850F /* UIMenuItem+Category.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIMenuItem+Category.h"; sourceTree = ""; };
67 | 3D8217D21D3F45A20077850F /* UIMenuItem+Category.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIMenuItem+Category.m"; sourceTree = ""; };
68 | 3D8217D91D3F45A20077850F /* UIView+Category.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Category.h"; sourceTree = ""; };
69 | 3D8217DA1D3F45A20077850F /* UIView+Category.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Category.m"; sourceTree = ""; };
70 | 3D8218071D3F5ECB0077850F /* NSString+Predicate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+Predicate.h"; sourceTree = ""; };
71 | 3D8218081D3F5ECB0077850F /* NSString+Predicate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+Predicate.m"; sourceTree = ""; };
72 | 3D82180D1D3F6A930077850F /* NSString+DisplayTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+DisplayTime.h"; sourceTree = ""; };
73 | 3D82180E1D3F6A930077850F /* NSString+DisplayTime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+DisplayTime.m"; sourceTree = ""; };
74 | 3DC904111F4D748700E56004 /* NSObject+Category.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+Category.h"; sourceTree = ""; };
75 | 3DC904121F4D748700E56004 /* NSObject+Category.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+Category.m"; sourceTree = ""; };
76 | 3DC904141F4D790F00E56004 /* NSObject+PerformBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+PerformBlock.h"; sourceTree = ""; };
77 | 3DC904151F4D790F00E56004 /* NSObject+PerformBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+PerformBlock.m"; sourceTree = ""; };
78 | 3DC9041A1F4D7E6E00E56004 /* UIView+Frame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+Frame.h"; sourceTree = ""; };
79 | 3DC9041B1F4D7E6E00E56004 /* UIView+Frame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Frame.m"; sourceTree = ""; };
80 | 3DC9041D1F4D87E200E56004 /* UIColor+Category.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+Category.h"; sourceTree = ""; };
81 | 3DC9041E1F4D87E200E56004 /* UIColor+Category.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+Category.m"; sourceTree = ""; };
82 | 3DC904201F4EAE2F00E56004 /* NSString+Safe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+Safe.h"; sourceTree = ""; };
83 | 3DC904211F4EAE2F00E56004 /* NSString+Safe.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+Safe.m"; sourceTree = ""; };
84 | 3DC904231F4EB8CD00E56004 /* NSMutableString+Safe.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMutableString+Safe.h"; sourceTree = ""; };
85 | 3DC904241F4EB8CD00E56004 /* NSMutableString+Safe.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableString+Safe.m"; sourceTree = ""; };
86 | 3DD78BCB1F669053003B8E9F /* UITableView+CellAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITableView+CellAnimation.h"; sourceTree = ""; };
87 | 3DD78BCC1F669053003B8E9F /* UITableView+CellAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITableView+CellAnimation.m"; sourceTree = ""; };
88 | 3DFAD8EA20AEA1400067ACDE /* NSDictionary+Safe.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Safe.h"; sourceTree = ""; };
89 | 3DFAD8EB20AEA1400067ACDE /* NSDictionary+Safe.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+Safe.m"; sourceTree = ""; };
90 | 3DFAD8ED20AEA1870067ACDE /* NSMutableDictionary+Safe.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSMutableDictionary+Safe.h"; sourceTree = ""; };
91 | 3DFAD8EE20AEA1870067ACDE /* NSMutableDictionary+Safe.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSMutableDictionary+Safe.m"; sourceTree = ""; };
92 | 3DFAD8F020AEA7F80067ACDE /* NSArray+Safe.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSArray+Safe.h"; sourceTree = ""; };
93 | 3DFAD8F120AEA7F80067ACDE /* NSArray+Safe.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Safe.m"; sourceTree = ""; };
94 | 3DFAD8F320AEB58C0067ACDE /* NSMutableArray+Safe.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSMutableArray+Safe.h"; sourceTree = ""; };
95 | 3DFAD8F420AEB58C0067ACDE /* NSMutableArray+Safe.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSMutableArray+Safe.m"; sourceTree = ""; };
96 | 3DFAD93620B2E0950067ACDE /* NSObject+Swizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+Swizzle.h"; sourceTree = ""; };
97 | 3DFAD93720B2E0950067ACDE /* NSObject+Swizzle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+Swizzle.m"; sourceTree = ""; };
98 | /* End PBXFileReference section */
99 |
100 | /* Begin PBXFrameworksBuildPhase section */
101 | 3D8217921D3F44C90077850F /* Frameworks */ = {
102 | isa = PBXFrameworksBuildPhase;
103 | buildActionMask = 2147483647;
104 | files = (
105 | );
106 | runOnlyForDeploymentPostprocessing = 0;
107 | };
108 | /* End PBXFrameworksBuildPhase section */
109 |
110 | /* Begin PBXGroup section */
111 | 3D5E53F32482356100637812 /* NSdate */ = {
112 | isa = PBXGroup;
113 | children = (
114 | 3D5E53F42482358300637812 /* NSDate+Category.h */,
115 | 3D5E53F52482358300637812 /* NSDate+Category.m */,
116 | );
117 | name = NSdate;
118 | sourceTree = "";
119 | };
120 | 3D82178C1D3F44C90077850F = {
121 | isa = PBXGroup;
122 | children = (
123 | 3D8217971D3F44C90077850F /* iOS-Category */,
124 | 3D8217961D3F44C90077850F /* Products */,
125 | );
126 | sourceTree = "";
127 | };
128 | 3D8217961D3F44C90077850F /* Products */ = {
129 | isa = PBXGroup;
130 | children = (
131 | 3D8217951D3F44C90077850F /* libiOS-Category.a */,
132 | );
133 | name = Products;
134 | sourceTree = "";
135 | };
136 | 3D8217971D3F44C90077850F /* iOS-Category */ = {
137 | isa = PBXGroup;
138 | children = (
139 | 3D5E53F32482356100637812 /* NSdate */,
140 | 3DD78BCA1F669025003B8E9F /* TableView */,
141 | 3DC904061F4D5DC700E56004 /* NSString */,
142 | 3DC904091F4D5EF200E56004 /* NSDictionary */,
143 | 3DC904081F4D5EE300E56004 /* NSArray */,
144 | 3DC904101F4D746C00E56004 /* NSObject */,
145 | 3DC9040F1F4D6D2500E56004 /* UIMenuItem */,
146 | 3DC9040E1F4D683D00E56004 /* NSData */,
147 | 3DC9040D1F4D66A100E56004 /* UIColor */,
148 | 3DC9040C1F4D669900E56004 /* UIImage */,
149 | 3DC9040B1F4D663200E56004 /* UIView */,
150 | 3DC9040A1F4D651200E56004 /* UIButton */,
151 | 3DC904071F4D5E2200E56004 /* NSAttributedString */,
152 | );
153 | path = "iOS-Category";
154 | sourceTree = "";
155 | };
156 | 3DC904061F4D5DC700E56004 /* NSString */ = {
157 | isa = PBXGroup;
158 | children = (
159 | 3D8217B31D3F45A20077850F /* NSString+Category.h */,
160 | 3D8217B41D3F45A20077850F /* NSString+Category.m */,
161 | 3D8218071D3F5ECB0077850F /* NSString+Predicate.h */,
162 | 3D8218081D3F5ECB0077850F /* NSString+Predicate.m */,
163 | 3D82180D1D3F6A930077850F /* NSString+DisplayTime.h */,
164 | 3D82180E1D3F6A930077850F /* NSString+DisplayTime.m */,
165 | 3D8217B71D3F45A20077850F /* NSString+MD5.h */,
166 | 3D8217B81D3F45A20077850F /* NSString+MD5.m */,
167 | 3DC904201F4EAE2F00E56004 /* NSString+Safe.h */,
168 | 3DC904211F4EAE2F00E56004 /* NSString+Safe.m */,
169 | 3DC904231F4EB8CD00E56004 /* NSMutableString+Safe.h */,
170 | 3DC904241F4EB8CD00E56004 /* NSMutableString+Safe.m */,
171 | );
172 | name = NSString;
173 | sourceTree = "";
174 | };
175 | 3DC904071F4D5E2200E56004 /* NSAttributedString */ = {
176 | isa = PBXGroup;
177 | children = (
178 | 3D8217A51D3F45A20077850F /* NSAttributedString+Category.h */,
179 | 3D8217A61D3F45A20077850F /* NSAttributedString+Category.m */,
180 | );
181 | name = NSAttributedString;
182 | sourceTree = "";
183 | };
184 | 3DC904081F4D5EE300E56004 /* NSArray */ = {
185 | isa = PBXGroup;
186 | children = (
187 | 3DFAD8F020AEA7F80067ACDE /* NSArray+Safe.h */,
188 | 3DFAD8F120AEA7F80067ACDE /* NSArray+Safe.m */,
189 | 3DFAD8F320AEB58C0067ACDE /* NSMutableArray+Safe.h */,
190 | 3DFAD8F420AEB58C0067ACDE /* NSMutableArray+Safe.m */,
191 | );
192 | name = NSArray;
193 | sourceTree = "";
194 | };
195 | 3DC904091F4D5EF200E56004 /* NSDictionary */ = {
196 | isa = PBXGroup;
197 | children = (
198 | 3D8217AB1D3F45A20077850F /* NSDictionary+Category.h */,
199 | 3D8217AC1D3F45A20077850F /* NSDictionary+Category.m */,
200 | 3DFAD8EA20AEA1400067ACDE /* NSDictionary+Safe.h */,
201 | 3DFAD8EB20AEA1400067ACDE /* NSDictionary+Safe.m */,
202 | 3DFAD8ED20AEA1870067ACDE /* NSMutableDictionary+Safe.h */,
203 | 3DFAD8EE20AEA1870067ACDE /* NSMutableDictionary+Safe.m */,
204 | );
205 | name = NSDictionary;
206 | sourceTree = "";
207 | };
208 | 3DC9040A1F4D651200E56004 /* UIButton */ = {
209 | isa = PBXGroup;
210 | children = (
211 | 3D8217C11D3F45A20077850F /* UIButton+Category.h */,
212 | 3D8217C21D3F45A20077850F /* UIButton+Category.m */,
213 | );
214 | name = UIButton;
215 | sourceTree = "";
216 | };
217 | 3DC9040B1F4D663200E56004 /* UIView */ = {
218 | isa = PBXGroup;
219 | children = (
220 | 3D8217D91D3F45A20077850F /* UIView+Category.h */,
221 | 3D8217DA1D3F45A20077850F /* UIView+Category.m */,
222 | 3DC9041A1F4D7E6E00E56004 /* UIView+Frame.h */,
223 | 3DC9041B1F4D7E6E00E56004 /* UIView+Frame.m */,
224 | );
225 | name = UIView;
226 | sourceTree = "";
227 | };
228 | 3DC9040C1F4D669900E56004 /* UIImage */ = {
229 | isa = PBXGroup;
230 | children = (
231 | 3D8217CD1D3F45A20077850F /* UIImage+Category.h */,
232 | 3D8217CE1D3F45A20077850F /* UIImage+Category.m */,
233 | );
234 | name = UIImage;
235 | sourceTree = "";
236 | };
237 | 3DC9040D1F4D66A100E56004 /* UIColor */ = {
238 | isa = PBXGroup;
239 | children = (
240 | 3DC9041D1F4D87E200E56004 /* UIColor+Category.h */,
241 | 3DC9041E1F4D87E200E56004 /* UIColor+Category.m */,
242 | );
243 | name = UIColor;
244 | sourceTree = "";
245 | };
246 | 3DC9040E1F4D683D00E56004 /* NSData */ = {
247 | isa = PBXGroup;
248 | children = (
249 | 3D8217A91D3F45A20077850F /* NSData+CommonCryptor.h */,
250 | 3D8217AA1D3F45A20077850F /* NSData+CommonCryptor.m */,
251 | );
252 | name = NSData;
253 | sourceTree = "";
254 | };
255 | 3DC9040F1F4D6D2500E56004 /* UIMenuItem */ = {
256 | isa = PBXGroup;
257 | children = (
258 | 3D8217D11D3F45A20077850F /* UIMenuItem+Category.h */,
259 | 3D8217D21D3F45A20077850F /* UIMenuItem+Category.m */,
260 | );
261 | name = UIMenuItem;
262 | sourceTree = "";
263 | };
264 | 3DC904101F4D746C00E56004 /* NSObject */ = {
265 | isa = PBXGroup;
266 | children = (
267 | 3DFAD93620B2E0950067ACDE /* NSObject+Swizzle.h */,
268 | 3DFAD93720B2E0950067ACDE /* NSObject+Swizzle.m */,
269 | 3DC904111F4D748700E56004 /* NSObject+Category.h */,
270 | 3DC904121F4D748700E56004 /* NSObject+Category.m */,
271 | 3DC904141F4D790F00E56004 /* NSObject+PerformBlock.h */,
272 | 3DC904151F4D790F00E56004 /* NSObject+PerformBlock.m */,
273 | );
274 | name = NSObject;
275 | sourceTree = "";
276 | };
277 | 3DD78BCA1F669025003B8E9F /* TableView */ = {
278 | isa = PBXGroup;
279 | children = (
280 | 3DD78BCB1F669053003B8E9F /* UITableView+CellAnimation.h */,
281 | 3DD78BCC1F669053003B8E9F /* UITableView+CellAnimation.m */,
282 | );
283 | name = TableView;
284 | sourceTree = "";
285 | };
286 | /* End PBXGroup section */
287 |
288 | /* Begin PBXNativeTarget section */
289 | 3D8217941D3F44C90077850F /* iOS-Category */ = {
290 | isa = PBXNativeTarget;
291 | buildConfigurationList = 3D82179E1D3F44C90077850F /* Build configuration list for PBXNativeTarget "iOS-Category" */;
292 | buildPhases = (
293 | 3D8217911D3F44C90077850F /* Sources */,
294 | 3D8217921D3F44C90077850F /* Frameworks */,
295 | 3D8217931D3F44C90077850F /* CopyFiles */,
296 | );
297 | buildRules = (
298 | );
299 | dependencies = (
300 | );
301 | name = "iOS-Category";
302 | productName = "iOS-Category";
303 | productReference = 3D8217951D3F44C90077850F /* libiOS-Category.a */;
304 | productType = "com.apple.product-type.library.static";
305 | };
306 | /* End PBXNativeTarget section */
307 |
308 | /* Begin PBXProject section */
309 | 3D82178D1D3F44C90077850F /* Project object */ = {
310 | isa = PBXProject;
311 | attributes = {
312 | LastUpgradeCheck = 0730;
313 | ORGANIZATIONNAME = BBFC;
314 | TargetAttributes = {
315 | 3D8217941D3F44C90077850F = {
316 | CreatedOnToolsVersion = 7.3.1;
317 | };
318 | };
319 | };
320 | buildConfigurationList = 3D8217901D3F44C90077850F /* Build configuration list for PBXProject "iOS-Category" */;
321 | compatibilityVersion = "Xcode 3.2";
322 | developmentRegion = English;
323 | hasScannedForEncodings = 0;
324 | knownRegions = (
325 | English,
326 | en,
327 | );
328 | mainGroup = 3D82178C1D3F44C90077850F;
329 | productRefGroup = 3D8217961D3F44C90077850F /* Products */;
330 | projectDirPath = "";
331 | projectRoot = "";
332 | targets = (
333 | 3D8217941D3F44C90077850F /* iOS-Category */,
334 | );
335 | };
336 | /* End PBXProject section */
337 |
338 | /* Begin PBXSourcesBuildPhase section */
339 | 3D8217911D3F44C90077850F /* Sources */ = {
340 | isa = PBXSourcesBuildPhase;
341 | buildActionMask = 2147483647;
342 | files = (
343 | 3DFAD93820B2E0960067ACDE /* NSObject+Swizzle.m in Sources */,
344 | 3DFAD8EF20AEA1870067ACDE /* NSMutableDictionary+Safe.m in Sources */,
345 | 3D5E53F62482358300637812 /* NSDate+Category.m in Sources */,
346 | 3D82180F1D3F6A930077850F /* NSString+DisplayTime.m in Sources */,
347 | 3D8217E31D3F45A20077850F /* NSData+CommonCryptor.m in Sources */,
348 | 3DFAD8F520AEB58C0067ACDE /* NSMutableArray+Safe.m in Sources */,
349 | 3DC9041C1F4D7E6E00E56004 /* UIView+Frame.m in Sources */,
350 | 3D8217E81D3F45A20077850F /* NSString+Category.m in Sources */,
351 | 3DD78BCD1F669053003B8E9F /* UITableView+CellAnimation.m in Sources */,
352 | 3DC904131F4D748700E56004 /* NSObject+Category.m in Sources */,
353 | 3D8217EA1D3F45A20077850F /* NSString+MD5.m in Sources */,
354 | 3D8217E11D3F45A20077850F /* NSAttributedString+Category.m in Sources */,
355 | 3D8217EF1D3F45A20077850F /* UIButton+Category.m in Sources */,
356 | 3DFAD8F220AEA7F80067ACDE /* NSArray+Safe.m in Sources */,
357 | 3D8217E41D3F45A20077850F /* NSDictionary+Category.m in Sources */,
358 | 3DC904161F4D790F00E56004 /* NSObject+PerformBlock.m in Sources */,
359 | 3DC904221F4EAE2F00E56004 /* NSString+Safe.m in Sources */,
360 | 3D8217F71D3F45A20077850F /* UIMenuItem+Category.m in Sources */,
361 | 3D8217FB1D3F45A20077850F /* UIView+Category.m in Sources */,
362 | 3DFAD8EC20AEA1400067ACDE /* NSDictionary+Safe.m in Sources */,
363 | 3D8217F51D3F45A20077850F /* UIImage+Category.m in Sources */,
364 | 3DC904251F4EB8CD00E56004 /* NSMutableString+Safe.m in Sources */,
365 | 3D8218091D3F5ECB0077850F /* NSString+Predicate.m in Sources */,
366 | 3DC9041F1F4D87E200E56004 /* UIColor+Category.m in Sources */,
367 | );
368 | runOnlyForDeploymentPostprocessing = 0;
369 | };
370 | /* End PBXSourcesBuildPhase section */
371 |
372 | /* Begin XCBuildConfiguration section */
373 | 3D82179C1D3F44C90077850F /* Debug */ = {
374 | isa = XCBuildConfiguration;
375 | buildSettings = {
376 | ALWAYS_SEARCH_USER_PATHS = NO;
377 | CLANG_ANALYZER_NONNULL = YES;
378 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
379 | CLANG_CXX_LIBRARY = "libc++";
380 | CLANG_ENABLE_MODULES = YES;
381 | CLANG_ENABLE_OBJC_ARC = YES;
382 | CLANG_WARN_BOOL_CONVERSION = YES;
383 | CLANG_WARN_CONSTANT_CONVERSION = YES;
384 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
385 | CLANG_WARN_EMPTY_BODY = YES;
386 | CLANG_WARN_ENUM_CONVERSION = YES;
387 | CLANG_WARN_INT_CONVERSION = YES;
388 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
389 | CLANG_WARN_UNREACHABLE_CODE = YES;
390 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
391 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
392 | COPY_PHASE_STRIP = NO;
393 | DEBUG_INFORMATION_FORMAT = dwarf;
394 | ENABLE_STRICT_OBJC_MSGSEND = YES;
395 | ENABLE_TESTABILITY = YES;
396 | GCC_C_LANGUAGE_STANDARD = gnu99;
397 | GCC_DYNAMIC_NO_PIC = NO;
398 | GCC_NO_COMMON_BLOCKS = YES;
399 | GCC_OPTIMIZATION_LEVEL = 0;
400 | GCC_PREPROCESSOR_DEFINITIONS = (
401 | "DEBUG=1",
402 | "$(inherited)",
403 | );
404 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
405 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
406 | GCC_WARN_UNDECLARED_SELECTOR = YES;
407 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
408 | GCC_WARN_UNUSED_FUNCTION = YES;
409 | GCC_WARN_UNUSED_VARIABLE = YES;
410 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
411 | MTL_ENABLE_DEBUG_INFO = YES;
412 | ONLY_ACTIVE_ARCH = YES;
413 | SDKROOT = iphoneos;
414 | };
415 | name = Debug;
416 | };
417 | 3D82179D1D3F44C90077850F /* Release */ = {
418 | isa = XCBuildConfiguration;
419 | buildSettings = {
420 | ALWAYS_SEARCH_USER_PATHS = NO;
421 | CLANG_ANALYZER_NONNULL = YES;
422 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
423 | CLANG_CXX_LIBRARY = "libc++";
424 | CLANG_ENABLE_MODULES = YES;
425 | CLANG_ENABLE_OBJC_ARC = YES;
426 | CLANG_WARN_BOOL_CONVERSION = YES;
427 | CLANG_WARN_CONSTANT_CONVERSION = YES;
428 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
429 | CLANG_WARN_EMPTY_BODY = YES;
430 | CLANG_WARN_ENUM_CONVERSION = YES;
431 | CLANG_WARN_INT_CONVERSION = YES;
432 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
433 | CLANG_WARN_UNREACHABLE_CODE = YES;
434 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
435 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
436 | COPY_PHASE_STRIP = NO;
437 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
438 | ENABLE_NS_ASSERTIONS = NO;
439 | ENABLE_STRICT_OBJC_MSGSEND = YES;
440 | GCC_C_LANGUAGE_STANDARD = gnu99;
441 | GCC_NO_COMMON_BLOCKS = YES;
442 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
443 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
444 | GCC_WARN_UNDECLARED_SELECTOR = YES;
445 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
446 | GCC_WARN_UNUSED_FUNCTION = YES;
447 | GCC_WARN_UNUSED_VARIABLE = YES;
448 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
449 | MTL_ENABLE_DEBUG_INFO = NO;
450 | SDKROOT = iphoneos;
451 | VALIDATE_PRODUCT = YES;
452 | };
453 | name = Release;
454 | };
455 | 3D82179F1D3F44C90077850F /* Debug */ = {
456 | isa = XCBuildConfiguration;
457 | buildSettings = {
458 | OTHER_LDFLAGS = "-ObjC";
459 | PRODUCT_NAME = "$(TARGET_NAME)";
460 | SKIP_INSTALL = YES;
461 | };
462 | name = Debug;
463 | };
464 | 3D8217A01D3F44C90077850F /* Release */ = {
465 | isa = XCBuildConfiguration;
466 | buildSettings = {
467 | OTHER_LDFLAGS = "-ObjC";
468 | PRODUCT_NAME = "$(TARGET_NAME)";
469 | SKIP_INSTALL = YES;
470 | };
471 | name = Release;
472 | };
473 | /* End XCBuildConfiguration section */
474 |
475 | /* Begin XCConfigurationList section */
476 | 3D8217901D3F44C90077850F /* Build configuration list for PBXProject "iOS-Category" */ = {
477 | isa = XCConfigurationList;
478 | buildConfigurations = (
479 | 3D82179C1D3F44C90077850F /* Debug */,
480 | 3D82179D1D3F44C90077850F /* Release */,
481 | );
482 | defaultConfigurationIsVisible = 0;
483 | defaultConfigurationName = Release;
484 | };
485 | 3D82179E1D3F44C90077850F /* Build configuration list for PBXNativeTarget "iOS-Category" */ = {
486 | isa = XCConfigurationList;
487 | buildConfigurations = (
488 | 3D82179F1D3F44C90077850F /* Debug */,
489 | 3D8217A01D3F44C90077850F /* Release */,
490 | );
491 | defaultConfigurationIsVisible = 0;
492 | defaultConfigurationName = Release;
493 | };
494 | /* End XCConfigurationList section */
495 | };
496 | rootObject = 3D82178D1D3F44C90077850F /* Project object */;
497 | }
498 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category.xcodeproj/project.xcworkspace/xcuserdata/ZBB.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kazamihayato/iOS-Category/e863413653591e1752d23dc72b9e5305e48cda8a/iOS-Category/iOS-Category.xcodeproj/project.xcworkspace/xcuserdata/ZBB.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category.xcodeproj/xcuserdata/ZBB.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category.xcodeproj/xcuserdata/ZBB.xcuserdatad/xcschemes/iOS-Category.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category.xcodeproj/xcuserdata/ZBB.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | iOS-Category.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 3D8217941D3F44C90077850F
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSArray+Safe.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSArray+Safe.h
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2018/5/18.
6 | // Copyright © 2018年 BBFC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSArray (Safe)
12 |
13 | + (instancetype)safeArrayWithObject:(id)object;
14 |
15 | - (id)safeObjectAtIndex:(NSUInteger)index;
16 |
17 | - (NSArray *)safeSubarrayWithRange:(NSRange)range;
18 |
19 | - (NSUInteger)safeIndexOfObject:(id)anObject;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSArray+Safe.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSArray+Safe.m
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2018/5/18.
6 | // Copyright © 2018年 BBFC. All rights reserved.
7 | //
8 |
9 | #import "NSArray+Safe.h"
10 |
11 |
12 | @implementation NSArray (Safe)
13 |
14 | + (instancetype)safeArrayWithObject:(id)object
15 | {
16 | if (object == nil) {
17 | return [self array];
18 | } else {
19 | return [self arrayWithObject:object];
20 | }
21 | }
22 |
23 |
24 | - (id)safeObjectAtIndex:(NSUInteger)index
25 | {
26 | if (index >= self.count) {
27 | return nil;
28 | } else {
29 | return [self objectAtIndex:index];
30 | }
31 | }
32 |
33 | - (NSUInteger)safeIndexOfObject:(id)anObject
34 | {
35 | if (anObject == nil) {
36 | return NSNotFound;
37 | } else {
38 | return [self indexOfObject:anObject];
39 | }
40 | }
41 |
42 | - (NSArray *)safeSubarrayWithRange:(NSRange)range
43 | {
44 | NSUInteger location = range.location;
45 | NSUInteger length = range.length;
46 | if (location + length > self.count) {
47 | //超过了边界,就获取从loction开始所有的item
48 | if ((location + length) > self.count) {
49 | length = (self.count - location);
50 | return [self safeSubarrayWithRange:NSMakeRange(location, length)];
51 | }
52 |
53 | return nil;
54 | }
55 | else {
56 | return [self subarrayWithRange:range];
57 | }
58 | }
59 |
60 |
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSAttributedString+Category.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSAttributedString+Category.h
3 | // PKWSevers
4 | //
5 | // Created by chenguangjiang on 16/5/23.
6 | // Copyright © 2016年 peikua. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | @interface NSAttributedString (Category)
12 | // 快速创建富文本字符串,包含了Str 颜色 字体 字体间距 行间距 range
13 | + (NSAttributedString *)attributedWithString:(NSString *)string
14 | font:(UIFont*)font
15 | color:(UIColor *)color;
16 |
17 | + (NSAttributedString *)attributedWithString:(NSString *)string
18 | font:(UIFont*)font
19 | color:(UIColor *)color
20 | wordSpacing:(CGFloat)wordSpacing
21 | lineSpacing:(CGFloat)lineSpacing;
22 |
23 | + (NSAttributedString *)attributedWithString:(NSString *)string
24 | font:(UIFont*)font
25 | color:(UIColor *)color
26 | wordSpacing:(CGFloat)wordSpacing
27 | lineSpacing:(CGFloat)lineSpacing
28 | range:(NSRange)range;
29 |
30 | //html片段转为富文本放在Label、Button上显示,这样HTML标签才会生效
31 | + (NSAttributedString*)htmlToAttString:(NSString*)string;
32 |
33 |
34 | //由于系统计算富文本的高度不正确,自己写了方法
35 | - (CGFloat)heightWithContainWidth:(CGFloat)width;
36 | @end
37 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSAttributedString+Category.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSAttributedString+Category.m
3 | // PKWSevers
4 | //
5 | // Created by chenguangjiang on 16/5/23.
6 | // Copyright © 2016年 peikua. All rights reserved.
7 | //
8 |
9 | #import "NSAttributedString+Category.h"
10 | #import
11 | @implementation NSAttributedString (Category)
12 | + (NSAttributedString *)attributedWithString:(NSString *)string
13 | font:(UIFont*)font
14 | color:(UIColor *)color{
15 | return [self attributedWithString:string font:font color:color wordSpacing:0 lineSpacing:0 range:NSMakeRange(0, string.length)];
16 | }
17 |
18 | + (NSAttributedString *)attributedWithString:(NSString *)string
19 | font:(UIFont*)font
20 | color:(UIColor *)color
21 | wordSpacing:(CGFloat)wordSpacing
22 | lineSpacing:(CGFloat)lineSpacing{
23 | return [self attributedWithString:string font:font color:color wordSpacing:wordSpacing lineSpacing:lineSpacing range:NSMakeRange(0, string.length)];
24 | }
25 |
26 |
27 | + (NSAttributedString *)attributedWithString:(NSString *)string
28 | font:(UIFont*)font
29 | color:(UIColor *)color
30 | wordSpacing:(CGFloat)wordSpacing
31 | lineSpacing:(CGFloat)lineSpacing
32 | range:(NSRange)range{
33 | if (string==NULL || string.length==0) {
34 | return [[NSAttributedString alloc] initWithString:@""];
35 | }
36 | NSRange getRange = NSIntersectionRange(NSMakeRange(0, string.length), range);
37 | NSMutableDictionary* muAttbutes = [NSMutableDictionary dictionary];
38 | if(color){
39 | [muAttbutes setObject:color forKey:NSForegroundColorAttributeName];
40 | }
41 |
42 | if(font){
43 | [muAttbutes setObject:font forKey:NSFontAttributeName];
44 | }
45 |
46 | NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
47 |
48 | if (wordSpacing > 0) {
49 | [muAttbutes setObject:@(wordSpacing) forKey:NSKernAttributeName];
50 |
51 | }
52 |
53 | if (lineSpacing > 0) {
54 | [paragraphStyle setLineSpacing:lineSpacing];
55 | [muAttbutes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
56 |
57 | }
58 |
59 |
60 | NSDictionary * attributes = [NSDictionary dictionaryWithDictionary:muAttbutes];
61 | NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string];
62 | [attributedString addAttributes:attributes range:getRange];
63 |
64 | return attributedString;
65 |
66 | }
67 |
68 |
69 | + (NSAttributedString*)htmlToAttString:(NSString*)string{
70 | NSData* data = [string dataUsingEncoding:NSUnicodeStringEncoding];
71 | NSDictionary* options = @{
72 | NSDocumentTypeDocumentOption: NSHTMLTextDocumentType
73 | };
74 | return [[NSAttributedString alloc]initWithData:data options:options documentAttributes:nil error:nil];
75 | }
76 |
77 |
78 | - (CGFloat)heightWithContainWidth:(CGFloat)width{
79 | int total_height = 0;
80 | CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)self);
81 | CGRect drawingRect = CGRectMake(0, 0, width, 100000);
82 | CGMutablePathRef path = CGPathCreateMutable();
83 | CGPathAddRect(path, NULL, drawingRect);
84 | CTFrameRef textFrame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0), path, NULL);
85 | CGPathRelease(path);
86 | CFRelease(framesetter);
87 |
88 | NSArray *linesArray = (NSArray *) CTFrameGetLines(textFrame);
89 | if(linesArray.count == 0)return 0;
90 | CGPoint origins[[linesArray count]];
91 | CTFrameGetLineOrigins(textFrame, CFRangeMake(0, 0), origins);
92 | int line_y = (int) origins[[linesArray count] -1].y;
93 | CGFloat ascent;
94 | CGFloat descent;
95 | CGFloat leading;
96 | CTLineRef line = (__bridge CTLineRef) [linesArray objectAtIndex:[linesArray count]-1];
97 | CTLineGetTypographicBounds(line, &ascent, &descent, &leading);
98 |
99 | total_height = 100000 - line_y + (int) descent +1;
100 | CFRelease(textFrame);
101 | return total_height;
102 | }
103 | @end
104 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSData+CommonCryptor.h:
--------------------------------------------------------------------------------
1 | //
2 | // PK-ios
3 | //
4 | // Created by peikua on 15/9/15.
5 | // Copyright (c) 2015年 peikua. All rights reserved.
6 | //
7 |
8 | #import
9 | #import
10 | #import
11 | #import
12 |
13 |
14 | extern NSString * const kCommonCryptoErrorDomain;
15 |
16 | @interface NSError (CommonCryptoErrorDomain)
17 | + (NSError *) errorWithCCCryptorStatus: (CCCryptorStatus) status;
18 | @end
19 |
20 | @interface NSData (CommonDigest)
21 |
22 | - (NSData *) MD2Sum;
23 | - (NSData *) MD4Sum;
24 | - (NSData *) MD5Sum;
25 |
26 | - (NSData *) SHA1Hash;
27 | - (NSData *) SHA224Hash;
28 | - (NSData *) SHA256Hash;
29 | - (NSData *) SHA384Hash;
30 | - (NSData *) SHA512Hash;
31 |
32 | @end
33 |
34 | @interface NSData (CommonCryptor)
35 |
36 | - (NSData *) AES256EncryptedDataUsingKey: (id) key error: (NSError **) error;
37 | - (NSData *) decryptedAES256DataUsingKey: (id) key error: (NSError **) error;
38 |
39 | - (NSData *) DESEncryptedDataUsingKey: (id) key error: (NSError **) error;
40 | - (NSData *) decryptedDESDataUsingKey: (id) key error: (NSError **) error;
41 |
42 | - (NSData *) CASTEncryptedDataUsingKey: (id) key error: (NSError **) error;
43 | - (NSData *) decryptedCASTDataUsingKey: (id) key error: (NSError **) error;
44 |
45 | @end
46 |
47 | @interface NSData (LowLevelCommonCryptor)
48 |
49 | - (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
50 | key: (id) key // data or string
51 | error: (CCCryptorStatus *) error;
52 | - (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
53 | key: (id) key // data or string
54 | options: (CCOptions) options
55 | error: (CCCryptorStatus *) error;
56 | - (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
57 | key: (id) key // data or string
58 | initializationVector: (id) iv // data or string
59 | options: (CCOptions) options
60 | error: (CCCryptorStatus *) error;
61 |
62 | - (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
63 | key: (id) key // data or string
64 | error: (CCCryptorStatus *) error;
65 | - (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
66 | key: (id) key // data or string
67 | options: (CCOptions) options
68 | error: (CCCryptorStatus *) error;
69 | - (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
70 | key: (id) key // data or string
71 | initializationVector: (id) iv // data or string
72 | options: (CCOptions) options
73 | error: (CCCryptorStatus *) error;
74 |
75 | @end
76 |
77 | @interface NSData (CommonHMAC)
78 |
79 | - (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm;
80 | - (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm key: (id) key;
81 |
82 | @end
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSData+CommonCryptor.m:
--------------------------------------------------------------------------------
1 | //
2 | // PK-ios
3 | //
4 | // Created by peikua on 15/9/15.
5 | // Copyright (c) 2015年 peikua. All rights reserved.
6 | //
7 |
8 | #import "NSData+CommonCryptor.h"
9 | #import
10 | #import
11 | #import
12 | #import
13 |
14 |
15 | NSString * const kCommonCryptoErrorDomain = @"CommonCryptoErrorDomain";
16 |
17 | @implementation NSError (CommonCryptoErrorDomain)
18 |
19 | + (NSError *) errorWithCCCryptorStatus: (CCCryptorStatus) status
20 | {
21 | NSString * description = nil, * reason = nil;
22 |
23 | switch ( status )
24 | {
25 | case kCCSuccess:
26 | description = NSLocalizedString(@"Success", @"Error description");
27 | break;
28 |
29 | case kCCParamError:
30 | description = NSLocalizedString(@"Parameter Error", @"Error description");
31 | reason = NSLocalizedString(@"Illegal parameter supplied to encryption/decryption algorithm", @"Error reason");
32 | break;
33 |
34 | case kCCBufferTooSmall:
35 | description = NSLocalizedString(@"Buffer Too Small", @"Error description");
36 | reason = NSLocalizedString(@"Insufficient buffer provided for specified operation", @"Error reason");
37 | break;
38 |
39 | case kCCMemoryFailure:
40 | description = NSLocalizedString(@"Memory Failure", @"Error description");
41 | reason = NSLocalizedString(@"Failed to allocate memory", @"Error reason");
42 | break;
43 |
44 | case kCCAlignmentError:
45 | description = NSLocalizedString(@"Alignment Error", @"Error description");
46 | reason = NSLocalizedString(@"Input size to encryption algorithm was not aligned correctly", @"Error reason");
47 | break;
48 |
49 | case kCCDecodeError:
50 | description = NSLocalizedString(@"Decode Error", @"Error description");
51 | reason = NSLocalizedString(@"Input data did not decode or decrypt correctly", @"Error reason");
52 | break;
53 |
54 | case kCCUnimplemented:
55 | description = NSLocalizedString(@"Unimplemented Function", @"Error description");
56 | reason = NSLocalizedString(@"Function not implemented for the current algorithm", @"Error reason");
57 | break;
58 |
59 | default:
60 | description = NSLocalizedString(@"Unknown Error", @"Error description");
61 | break;
62 | }
63 |
64 | NSMutableDictionary * userInfo = [[NSMutableDictionary alloc] init];
65 | [userInfo setObject: description forKey: NSLocalizedDescriptionKey];
66 |
67 | if ( reason != nil )
68 | [userInfo setObject: reason forKey: NSLocalizedFailureReasonErrorKey];
69 |
70 | NSError * result = [NSError errorWithDomain: kCommonCryptoErrorDomain code: status userInfo: userInfo];
71 | #if !__has_feature(objc_arc)
72 | [userInfo release];
73 | #endif
74 |
75 | return ( result );
76 | }
77 |
78 | @end
79 |
80 | #pragma mark -
81 |
82 | @implementation NSData (CommonDigest)
83 |
84 | - (NSData *) MD2Sum
85 | {
86 | unsigned char hash[CC_MD2_DIGEST_LENGTH];
87 | (void) CC_MD2( [self bytes], (CC_LONG)[self length], hash );
88 | return ( [NSData dataWithBytes: hash length: CC_MD2_DIGEST_LENGTH] );
89 | }
90 |
91 | - (NSData *) MD4Sum
92 | {
93 | unsigned char hash[CC_MD4_DIGEST_LENGTH];
94 | (void) CC_MD4( [self bytes], (CC_LONG)[self length], hash );
95 | return ( [NSData dataWithBytes: hash length: CC_MD4_DIGEST_LENGTH] );
96 | }
97 |
98 | - (NSData *) MD5Sum
99 | {
100 | unsigned char hash[CC_MD5_DIGEST_LENGTH];
101 | (void) CC_MD5( [self bytes], (CC_LONG)[self length], hash );
102 | return ( [NSData dataWithBytes: hash length: CC_MD5_DIGEST_LENGTH] );
103 | }
104 |
105 | - (NSData *) SHA1Hash
106 | {
107 | unsigned char hash[CC_SHA1_DIGEST_LENGTH];
108 | (void) CC_SHA1( [self bytes], (CC_LONG)[self length], hash );
109 | return ( [NSData dataWithBytes: hash length: CC_SHA1_DIGEST_LENGTH] );
110 | }
111 |
112 | - (NSData *) SHA224Hash
113 | {
114 | unsigned char hash[CC_SHA224_DIGEST_LENGTH];
115 | (void) CC_SHA224( [self bytes], (CC_LONG)[self length], hash );
116 | return ( [NSData dataWithBytes: hash length: CC_SHA224_DIGEST_LENGTH] );
117 | }
118 |
119 | - (NSData *) SHA256Hash
120 | {
121 | unsigned char hash[CC_SHA256_DIGEST_LENGTH];
122 | (void) CC_SHA256( [self bytes], (CC_LONG)[self length], hash );
123 | return ( [NSData dataWithBytes: hash length: CC_SHA256_DIGEST_LENGTH] );
124 | }
125 |
126 | - (NSData *) SHA384Hash
127 | {
128 | unsigned char hash[CC_SHA384_DIGEST_LENGTH];
129 | (void) CC_SHA384( [self bytes], (CC_LONG)[self length], hash );
130 | return ( [NSData dataWithBytes: hash length: CC_SHA384_DIGEST_LENGTH] );
131 | }
132 |
133 | - (NSData *) SHA512Hash
134 | {
135 | unsigned char hash[CC_SHA512_DIGEST_LENGTH];
136 | (void) CC_SHA512( [self bytes], (CC_LONG)[self length], hash );
137 | return ( [NSData dataWithBytes: hash length: CC_SHA512_DIGEST_LENGTH] );
138 | }
139 |
140 | @end
141 |
142 | @implementation NSData (CommonCryptor)
143 |
144 | - (NSData *) AES256EncryptedDataUsingKey: (id) key error: (NSError **) error
145 | {
146 | CCCryptorStatus status = kCCSuccess;
147 | NSData * result = [self dataEncryptedUsingAlgorithm: kCCAlgorithmAES128
148 | key: key
149 | options: kCCOptionPKCS7Padding
150 | error: &status];
151 |
152 | if ( result != nil )
153 | return ( result );
154 |
155 | if ( error != NULL )
156 | *error = [NSError errorWithCCCryptorStatus: status];
157 |
158 | return ( nil );
159 | }
160 |
161 | - (NSData *) decryptedAES256DataUsingKey: (id) key error: (NSError **) error
162 | {
163 | CCCryptorStatus status = kCCSuccess;
164 | NSData * result = [self decryptedDataUsingAlgorithm: kCCAlgorithmAES128
165 | key: key
166 | options: kCCOptionPKCS7Padding
167 | error: &status];
168 |
169 | if ( result != nil )
170 | return ( result );
171 |
172 | if ( error != NULL )
173 | *error = [NSError errorWithCCCryptorStatus: status];
174 |
175 | return ( nil );
176 | }
177 |
178 | - (NSData *) DESEncryptedDataUsingKey: (id) key error: (NSError **) error
179 | {
180 | CCCryptorStatus status = kCCSuccess;
181 | NSData * result = [self dataEncryptedUsingAlgorithm: kCCAlgorithmDES
182 | key: key
183 | options: kCCOptionPKCS7Padding
184 | error: &status];
185 |
186 | if ( result != nil )
187 | return ( result );
188 |
189 | if ( error != NULL )
190 | *error = [NSError errorWithCCCryptorStatus: status];
191 |
192 | return ( nil );
193 | }
194 |
195 | - (NSData *) decryptedDESDataUsingKey: (id) key error: (NSError **) error
196 | {
197 | CCCryptorStatus status = kCCSuccess;
198 | NSData * result = [self decryptedDataUsingAlgorithm: kCCAlgorithmDES
199 | key: key
200 | options: kCCOptionPKCS7Padding
201 | error: &status];
202 |
203 | if ( result != nil )
204 | return ( result );
205 |
206 | if ( error != NULL )
207 | *error = [NSError errorWithCCCryptorStatus: status];
208 |
209 | return ( nil );
210 | }
211 |
212 | - (NSData *) CASTEncryptedDataUsingKey: (id) key error: (NSError **) error
213 | {
214 | CCCryptorStatus status = kCCSuccess;
215 | NSData * result = [self dataEncryptedUsingAlgorithm: kCCAlgorithmCAST
216 | key: key
217 | options: kCCOptionPKCS7Padding
218 | error: &status];
219 |
220 | if ( result != nil )
221 | return ( result );
222 |
223 | if ( error != NULL )
224 | *error = [NSError errorWithCCCryptorStatus: status];
225 |
226 | return ( nil );
227 | }
228 |
229 | - (NSData *) decryptedCASTDataUsingKey: (id) key error: (NSError **) error
230 | {
231 | CCCryptorStatus status = kCCSuccess;
232 | NSData * result = [self decryptedDataUsingAlgorithm: kCCAlgorithmCAST
233 | key: key
234 | options: kCCOptionPKCS7Padding
235 | error: &status];
236 |
237 | if ( result != nil )
238 | return ( result );
239 |
240 | if ( error != NULL )
241 | *error = [NSError errorWithCCCryptorStatus: status];
242 |
243 | return ( nil );
244 | }
245 |
246 | @end
247 |
248 | static void FixKeyLengths( CCAlgorithm algorithm, NSMutableData * keyData, NSMutableData * ivData )
249 | {
250 | NSUInteger keyLength = [keyData length];
251 | switch ( algorithm )
252 | {
253 | case kCCAlgorithmAES128:
254 | {
255 | if ( keyLength < 16 )
256 | {
257 | [keyData setLength: 16];
258 | }
259 | else if ( keyLength < 24 )
260 | {
261 | [keyData setLength: 24];
262 | }
263 | else
264 | {
265 | [keyData setLength: 32];
266 | }
267 |
268 | break;
269 | }
270 |
271 | case kCCAlgorithmDES:
272 | {
273 | [keyData setLength: 8];
274 | break;
275 | }
276 |
277 | case kCCAlgorithm3DES:
278 | {
279 | [keyData setLength: 24];
280 | break;
281 | }
282 |
283 | case kCCAlgorithmCAST:
284 | {
285 | if ( keyLength < 5 )
286 | {
287 | [keyData setLength: 5];
288 | }
289 | else if ( keyLength > 16 )
290 | {
291 | [keyData setLength: 16];
292 | }
293 |
294 | break;
295 | }
296 |
297 | case kCCAlgorithmRC4:
298 | {
299 | if ( keyLength > 512 )
300 | [keyData setLength: 512];
301 | break;
302 | }
303 |
304 | default:
305 | break;
306 | }
307 |
308 | [ivData setLength: [keyData length]];
309 | }
310 |
311 | @implementation NSData (LowLevelCommonCryptor)
312 |
313 | - (NSData *) _runCryptor: (CCCryptorRef) cryptor result: (CCCryptorStatus *) status
314 | {
315 | size_t bufsize = CCCryptorGetOutputLength( cryptor, (size_t)[self length], true );
316 | void * buf = malloc( bufsize );
317 | size_t bufused = 0;
318 | size_t bytesTotal = 0;
319 | *status = CCCryptorUpdate( cryptor, [self bytes], (size_t)[self length],
320 | buf, bufsize, &bufused );
321 | if ( *status != kCCSuccess )
322 | {
323 | free( buf );
324 | return ( nil );
325 | }
326 |
327 | bytesTotal += bufused;
328 |
329 | // From Brent Royal-Gordon (Twitter: architechies):
330 | // Need to update buf ptr past used bytes when calling CCCryptorFinal()
331 | *status = CCCryptorFinal( cryptor, buf + bufused, bufsize - bufused, &bufused );
332 | if ( *status != kCCSuccess )
333 | {
334 | free( buf );
335 | return ( nil );
336 | }
337 |
338 | bytesTotal += bufused;
339 |
340 | return ( [NSData dataWithBytesNoCopy: buf length: bytesTotal] );
341 | }
342 |
343 | - (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
344 | key: (id) key
345 | error: (CCCryptorStatus *) error
346 | {
347 | return ( [self dataEncryptedUsingAlgorithm: algorithm
348 | key: key
349 | initializationVector: nil
350 | options: 0
351 | error: error] );
352 | }
353 |
354 | - (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
355 | key: (id) key
356 | options: (CCOptions) options
357 | error: (CCCryptorStatus *) error
358 | {
359 | return ( [self dataEncryptedUsingAlgorithm: algorithm
360 | key: key
361 | initializationVector: nil
362 | options: options
363 | error: error] );
364 | }
365 |
366 | - (NSData *) dataEncryptedUsingAlgorithm: (CCAlgorithm) algorithm
367 | key: (id) key
368 | initializationVector: (id) iv
369 | options: (CCOptions) options
370 | error: (CCCryptorStatus *) error
371 | {
372 | CCCryptorRef cryptor = NULL;
373 | CCCryptorStatus status = kCCSuccess;
374 |
375 | NSParameterAssert([key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
376 | NSParameterAssert(iv == nil || [iv isKindOfClass: [NSData class]] || [iv isKindOfClass: [NSString class]]);
377 |
378 | NSMutableData * keyData, * ivData;
379 | if ( [key isKindOfClass: [NSData class]] )
380 | keyData = (NSMutableData *) [key mutableCopy];
381 | else
382 | keyData = [[key dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
383 |
384 | if ( [iv isKindOfClass: [NSString class]] )
385 | ivData = [[iv dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
386 | else
387 | ivData = (NSMutableData *) [iv mutableCopy]; // data or nil
388 |
389 | #if !__has_feature(objc_arc)
390 | [keyData autorelease];
391 | [ivData autorelease];
392 | #endif
393 | // ensure correct lengths for key and iv data, based on algorithms
394 | FixKeyLengths( algorithm, keyData, ivData );
395 |
396 | status = CCCryptorCreate( kCCEncrypt, algorithm, options,
397 | [keyData bytes], [keyData length], [ivData bytes],
398 | &cryptor );
399 |
400 | if ( status != kCCSuccess )
401 | {
402 | if ( error != NULL )
403 | *error = status;
404 | return ( nil );
405 | }
406 |
407 | NSData * result = [self _runCryptor: cryptor result: &status];
408 | if ( (result == nil) && (error != NULL) )
409 | *error = status;
410 |
411 | CCCryptorRelease( cryptor );
412 |
413 | return ( result );
414 | }
415 |
416 | - (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
417 | key: (id) key // data or string
418 | error: (CCCryptorStatus *) error
419 | {
420 | return ( [self decryptedDataUsingAlgorithm: algorithm
421 | key: key
422 | initializationVector: nil
423 | options: 0
424 | error: error] );
425 | }
426 |
427 | - (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
428 | key: (id) key // data or string
429 | options: (CCOptions) options
430 | error: (CCCryptorStatus *) error
431 | {
432 | return ( [self decryptedDataUsingAlgorithm: algorithm
433 | key: key
434 | initializationVector: nil
435 | options: options
436 | error: error] );
437 | }
438 |
439 | - (NSData *) decryptedDataUsingAlgorithm: (CCAlgorithm) algorithm
440 | key: (id) key // data or string
441 | initializationVector: (id) iv // data or string
442 | options: (CCOptions) options
443 | error: (CCCryptorStatus *) error
444 | {
445 | CCCryptorRef cryptor = NULL;
446 | CCCryptorStatus status = kCCSuccess;
447 |
448 | NSParameterAssert([key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
449 | NSParameterAssert(iv == nil || [iv isKindOfClass: [NSData class]] || [iv isKindOfClass: [NSString class]]);
450 |
451 | NSMutableData * keyData, * ivData;
452 | if ( [key isKindOfClass: [NSData class]] )
453 | keyData = (NSMutableData *) [key mutableCopy];
454 | else
455 | keyData = [[key dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
456 |
457 | if ( [iv isKindOfClass: [NSString class]] )
458 | ivData = [[iv dataUsingEncoding: NSUTF8StringEncoding] mutableCopy];
459 | else
460 | ivData = (NSMutableData *) [iv mutableCopy]; // data or nil
461 |
462 | #if !__has_feature(objc_arc)
463 | [keyData autorelease];
464 | [ivData autorelease];
465 | #endif
466 |
467 | // ensure correct lengths for key and iv data, based on algorithms
468 | FixKeyLengths( algorithm, keyData, ivData );
469 |
470 | status = CCCryptorCreate( kCCDecrypt, algorithm, options,
471 | [keyData bytes], [keyData length], [ivData bytes],
472 | &cryptor );
473 |
474 | if ( status != kCCSuccess )
475 | {
476 | if ( error != NULL )
477 | *error = status;
478 | return ( nil );
479 | }
480 |
481 | NSData * result = [self _runCryptor: cryptor result: &status];
482 | if ( (result == nil) && (error != NULL) )
483 | *error = status;
484 |
485 | CCCryptorRelease( cryptor );
486 |
487 | return ( result );
488 | }
489 |
490 | @end
491 |
492 | @implementation NSData (CommonHMAC)
493 |
494 | - (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm
495 | {
496 | return ( [self HMACWithAlgorithm: algorithm key: nil] );
497 | }
498 |
499 | - (NSData *) HMACWithAlgorithm: (CCHmacAlgorithm) algorithm key: (id) key
500 | {
501 | NSParameterAssert(key == nil || [key isKindOfClass: [NSData class]] || [key isKindOfClass: [NSString class]]);
502 |
503 | NSData * keyData = nil;
504 | if ( [key isKindOfClass: [NSString class]] )
505 | keyData = [key dataUsingEncoding: NSUTF8StringEncoding];
506 | else
507 | keyData = (NSData *) key;
508 |
509 | // this could be either CC_SHA1_DIGEST_LENGTH or CC_MD5_DIGEST_LENGTH. SHA1 is larger.
510 | unsigned char buf[CC_SHA1_DIGEST_LENGTH];
511 | CCHmac( algorithm, [keyData bytes], [keyData length], [self bytes], [self length], buf );
512 |
513 | return ( [NSData dataWithBytes: buf length: (algorithm == kCCHmacAlgMD5 ? CC_MD5_DIGEST_LENGTH : CC_SHA1_DIGEST_LENGTH)] );
514 | }
515 |
516 | @end
517 |
518 |
519 |
520 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSDate+Category.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSDate+Category.h
3 | // iOS-Category
4 | //
5 | // Created by zhuangbb on 2020/5/30.
6 | // Copyright © 2020 BBFC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | @interface NSDate (Category)
14 | #pragma mark - 返回NSString部分
15 |
16 | /// NSDate转格式显示
17 | /// @param date 例如:[NSDate date]
18 | /// @param formatter @"yyyy-MM-dd"
19 | + (NSString *)dateToString:(NSDate *)date dateFormatter:(NSString *)formatter;
20 |
21 | /// 时间戳转格式显示
22 | /// @param timeInterval
23 | /// @param formatter @"yyyy-MM-dd"
24 | + (NSString *)timeIntervalToString:(NSTimeInterval)timeInterval dateFormatter:(NSString *)formatter;
25 |
26 | #pragma mark - 返回NSDate部分
27 |
28 | /// 根据显示时间的字符串返回NSDate
29 | /// @param timeString 例如:1980-01-01
30 | /// @param format @"yyyy-MM-dd"
31 | + (NSDate *)dateWithDateString:(NSString *)timeString formatString:(NSString *)format;
32 |
33 | /// 在已有NSDate的情况下,加减具体数字的年月日,获取未来或者过去的NSDate
34 | /// @param presentDate
35 | /// @param year 小于0为过去,大于0则为未来
36 | /// @param month
37 | /// @param day
38 | + (NSDate *)dateWithPresentDate:(NSDate*)presentDate year:(NSInteger)year month:(NSInteger)month day:(NSInteger)day;
39 |
40 | /// 根据具体的年月日获取NSDate
41 | /// @param year
42 | /// @param month
43 | /// @param day
44 | + (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day;
45 |
46 | #pragma mark - 返回整型部分
47 | /// 根据前后NSDate,获取中间差了多少天
48 | /// @param startDate 开始时间
49 | /// @param endDate 结束时间
50 | + (NSInteger)daysBetweenStartDate:(NSDate *)startDate endDate:(NSDate *)endDate;
51 |
52 | /// 获取传入Date对应的月份有多少天
53 | /// @param date
54 | + (NSInteger)totaldaysInMonth:(NSDate *)date;
55 |
56 | // 是否和当前同一天
57 | + (BOOL)isCurrentDay:(NSDate *)date;
58 | @end
59 |
60 | NS_ASSUME_NONNULL_END
61 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSDate+Category.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSDate+Category.m
3 | // iOS-Category
4 | //
5 | // Created by zhuangbb on 2020/5/30.
6 | // Copyright © 2020 BBFC. All rights reserved.
7 | //
8 |
9 | #import "NSDate+Category.h"
10 |
11 | @implementation NSDate (Category)
12 | //内部方法、也可以自己暴露
13 | + (NSDateFormatter *)setDateFormatter:(NSString *)formatter {
14 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
15 | [dateFormatter setDateFormat:formatter];
16 | //这条很重要,不加的话。手机设置选择外国可能就会返回中文
17 | [dateFormatter setLocale:[NSLocale currentLocale]];
18 | return dateFormatter;
19 | }
20 |
21 | + (NSDateComponents *)components:(NSDate *)date {
22 | NSDateFormatter *dateFormatter = [[self class] setDateFormatter:@"yyyy-MM-dd"];
23 | NSString *dateString = [NSDate timeIntervalToString:date.timeIntervalSince1970 dateFormatter:dateFormatter.dateFormat];
24 | NSDate *startDate = [dateFormatter dateFromString:dateString];
25 | NSDateComponents *components = [[NSCalendar currentCalendar] components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | kCFCalendarUnitWeekday | kCFCalendarUnitWeekdayOrdinal) fromDate:startDate];
26 |
27 | return components;
28 | }
29 | #pragma mark - 返回NSString部分
30 | + (NSString *)dateToString:(NSDate *)date dateFormatter:(NSString *)formatter {
31 | NSDateFormatter *dateFormatter = [[self class] setDateFormatter:formatter];
32 | NSString *dateString = [dateFormatter stringFromDate:date];
33 | return dateString;
34 | }
35 |
36 | + (NSString *)timeIntervalToString:(NSTimeInterval)timeInterval dateFormatter:(NSString *)formatter {
37 | NSDateFormatter *dateFormatter = [[self class] setDateFormatter:formatter];
38 | NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeInterval];
39 | NSString *dateString = [dateFormatter stringFromDate:date];
40 | return dateString;
41 | }
42 | #pragma mark - 返回NSDate部分
43 |
44 | + (NSDate *)dateWithDateString:(NSString *)dateString formatString:(NSString *)format {
45 | NSDateFormatter *dateFormatter = [[self class] setDateFormatter:format];
46 | NSDate *date = [dateFormatter dateFromString:dateString];
47 | return date;
48 | }
49 |
50 | + (NSDate *)dateWithPresentDate:(NSDate*)presentDate year:(NSInteger)year month:(NSInteger)month day:(NSInteger)day{
51 | NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
52 |
53 | NSDateComponents *adcomps = [[NSDateComponents alloc] init];
54 |
55 | [adcomps setYear:year];
56 |
57 | [adcomps setMonth:month];
58 |
59 | [adcomps setDay:day];
60 |
61 | return [calendar dateByAddingComponents:adcomps toDate:presentDate options:0];
62 | }
63 |
64 | + (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day{
65 | NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
66 |
67 | NSDateComponents *adcomps = [[NSDateComponents alloc] init];
68 |
69 | [adcomps setYear:year];
70 |
71 | [adcomps setMonth:month];
72 |
73 | [adcomps setDay:day];
74 |
75 | return [calendar dateFromComponents:adcomps];
76 | }
77 | #pragma mark - 返回整型部分
78 |
79 | + (NSInteger)daysBetweenStartDate:(NSDate *)startDate endDate:(NSDate *)endDate {
80 | NSDateComponents *startComponents = [NSDate components:startDate];
81 | NSDateComponents *endComponents = [NSDate components:endDate];
82 |
83 | NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay fromDateComponents:startComponents toDateComponents:endComponents options:nil];
84 |
85 | return components.day;
86 | }
87 |
88 | // 获取当前月共有多少天
89 | + (NSInteger)totaldaysInMonth:(NSDate *)date {
90 | NSRange daysInLastMonth = [[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date];
91 |
92 | return daysInLastMonth.length;
93 | }
94 |
95 | // 日期判断
96 |
97 | + (BOOL)isCurrentDay:(NSDate *)date {
98 | BOOL result = NO;
99 |
100 | NSString *dateString = [NSDate dateToString:date dateFormatter:@"yyyy-MM-dd"];
101 | NSString *nowString = [NSDate dateToString:[NSDate date] dateFormatter:@"yyyy-MM-dd"];
102 |
103 | if ([dateString isEqualToString:nowString]) {
104 | result = YES;
105 | }
106 |
107 | return result;
108 | }
109 |
110 |
111 | @end
112 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSDictionary+Category.h:
--------------------------------------------------------------------------------
1 | //
2 | // PK-ios
3 | //
4 | // Created by peikua on 15/9/15.
5 | // Copyright (c) 2015年 peikua. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | @interface NSDictionary (Category)
11 |
12 | + (NSDictionary *)JSONStringTransToDic:(NSString *)JSONString;
13 | @end
14 |
15 |
16 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSDictionary+Category.m:
--------------------------------------------------------------------------------
1 | //
2 | // PK-ios
3 | //
4 | // Created by peikua on 15/9/15.
5 | // Copyright (c) 2015年 peikua. All rights reserved.
6 | //
7 |
8 | #import "NSDictionary+Category.h"
9 |
10 |
11 | @implementation NSDictionary (Category)
12 |
13 | + (NSDictionary *)JSONStringTransToDic:(NSString *)JSONString {
14 | if (JSONString == nil) {
15 | return nil;
16 | }
17 | NSData *jsonData = [JSONString dataUsingEncoding:NSUTF8StringEncoding];
18 | NSError *err;
19 | NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
20 |
21 | options:NSJSONReadingMutableContainers
22 |
23 | error:&err];
24 | if(err) {
25 | NSLog(@"json解析失败:%@",err);
26 | return nil;
27 | }
28 | return dic;
29 | }
30 |
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSDictionary+Safe.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSDictionary+Safe.h
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2018/5/18.
6 | // Copyright © 2018年 BBFC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSDictionary (Safe)
12 |
13 | - (id)safeObjectForKey:(NSString *)key;
14 |
15 | - (void)safeSetValue:(id)object forKey:(id)key;
16 |
17 | - (id)objectForKeyCustom:(id)aKey;
18 |
19 | - (id)safeKeyForValue:(id)value;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSDictionary+Safe.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSDictionary+Safe.m
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2018/5/18.
6 | // Copyright © 2018年 BBFC. All rights reserved.
7 | //
8 |
9 | #import "NSDictionary+Safe.h"
10 |
11 | @implementation NSDictionary (Safe)
12 |
13 | - (id)safeObjectForKey:(NSString *)key {
14 | if (key == nil || [self isKindOfClass:[NSNull class]]) {
15 | return nil;
16 | }
17 | id object = [self objectForKey:key];
18 | if (object==nil || object == [NSNull null]) {
19 | return @"";
20 | }
21 | return object;
22 | }
23 |
24 |
25 | - (void)safeSetValue:(id)object forKey:(id)key {
26 | if ([key isKindOfClass:[NSNull class]]) {
27 | return;
28 | }
29 | if ([object isKindOfClass:[NSNull class]]) {
30 | [self setValue:@"" forKey:key];
31 | }else{
32 | [self setValue:object forKey:key];
33 | }
34 | }
35 |
36 | - (id)objectForKeyCustom:(id)aKey {
37 | id object = nil;
38 |
39 | // 检查是否字典对象
40 | if (![self isKindOfClass:[NSDictionary class]]) {
41 | return object;
42 | }
43 |
44 | // 保证key必须为字符串
45 | if (aKey && [aKey isKindOfClass:[NSString class]]) {
46 | object = [self objectForKeyCustom:aKey];
47 | }
48 |
49 | return object;
50 | }
51 |
52 | - (id)safeKeyForValue:(id)value {
53 | for (id key in self.allKeys) {
54 | if ([value isEqual:[self objectForKey:key]]) {
55 | return key;
56 | }
57 | }
58 | return nil;
59 | }
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSMutableArray+Safe.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSMutableArray+Safe.h
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2018/5/18.
6 | // Copyright © 2018年 BBFC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSMutableArray (Safe)
12 | - (void)safeAddObject:(id)object;
13 |
14 | - (void)safeInsertObject:(id)object atIndex:(NSUInteger)index;
15 |
16 | - (void)safeInsertObjects:(NSArray *)objects atIndexes:(NSIndexSet *)indexs;
17 |
18 | - (void)safeRemoveObjectAtIndex:(NSUInteger)index;
19 |
20 | - (void)safeRemoveObjectsInRange:(NSRange)range;
21 | @end
22 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSMutableArray+Safe.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSMutableArray+Safe.m
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2018/5/18.
6 | // Copyright © 2018年 BBFC. All rights reserved.
7 | //
8 |
9 | #import "NSMutableArray+Safe.h"
10 |
11 | @implementation NSMutableArray (Safe)
12 |
13 | - (void)safeAddObject:(id)object
14 | {
15 | if (object == nil) {
16 | return;
17 | } else {
18 | [self addObject:object];
19 | }
20 | }
21 |
22 | - (void)safeInsertObject:(id)object atIndex:(NSUInteger)index
23 | {
24 | if (object == nil) {
25 | return;
26 | } else if (index > self.count) {
27 | return;
28 | } else {
29 | [self insertObject:object atIndex:index];
30 | }
31 | }
32 |
33 | - (void)safeInsertObjects:(NSArray *)objects atIndexes:(NSIndexSet *)indexs
34 | {
35 | NSUInteger firstIndex = indexs.firstIndex;
36 | if (indexs == nil) {
37 | return;
38 | } else if (indexs.count!=objects.count || firstIndex>objects.count) {
39 | return;
40 | } else {
41 | [self insertObjects:objects atIndexes:indexs];
42 | }
43 | }
44 |
45 | - (void)safeRemoveObjectAtIndex:(NSUInteger)index
46 | {
47 | if (index >= self.count) {
48 | return;
49 | } else {
50 | [self removeObjectAtIndex:index];
51 | }
52 | }
53 |
54 | - (void)safeRemoveObjectsInRange:(NSRange)range
55 | {
56 | NSUInteger location = range.location;
57 | NSUInteger length = range.length;
58 | if (location + length > self.count) {
59 | return;
60 | } else {
61 | [self removeObjectsInRange:range];
62 | }
63 | }
64 | @end
65 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSMutableDictionary+Safe.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSMutableDictionary+Safe.h
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2018/5/18.
6 | // Copyright © 2018年 BBFC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSMutableDictionary (Safe)
12 |
13 | - (void)safeSetObject:(id)aObj forKey:(id)aKey;
14 |
15 | - (id)safeObjectForKey:(id)aKey;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSMutableDictionary+Safe.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSMutableDictionary+Safe.m
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2018/5/18.
6 | // Copyright © 2018年 BBFC. All rights reserved.
7 | //
8 |
9 | #import "NSMutableDictionary+Safe.h"
10 |
11 | @implementation NSMutableDictionary (Safe)
12 |
13 | - (void)safeSetObject:(id)aObj forKey:(id)aKey
14 | {
15 | if (aObj && ![aObj isKindOfClass:[NSNull class]] && aKey) {
16 | [self setObject:aObj forKey:aKey];
17 | } else {
18 | return;
19 | }
20 | }
21 |
22 | - (id)safeObjectForKey:(id)aKey
23 | {
24 | if (aKey != nil) {
25 | return [self objectForKey:aKey];
26 | } else {
27 | return nil;
28 | }
29 | }
30 | @end
31 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSMutableString+Safe.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSMutableString+Safe.h
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/8/24.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSMutableString (Safe)
12 | - (void)safeInsertString:(NSString *)aString atIndex:(NSUInteger)loc;
13 |
14 | - (void)safeAppendString:(NSString *)aString;
15 |
16 | - (void)safeSetString:(NSString *)aString;
17 |
18 | - (NSUInteger)safeReplaceOccurrencesOfString:(NSString *)target withString:(NSString *)replacement options:(NSStringCompareOptions)options range:(NSRange)searchRange;
19 | @end
20 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSMutableString+Safe.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSMutableString+Safe.m
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/8/24.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import "NSMutableString+Safe.h"
10 |
11 | @implementation NSMutableString (Safe)
12 |
13 | - (void)safeInsertString:(NSString *)aString atIndex:(NSUInteger)loc
14 | {
15 | if (aString == nil) {
16 | return;
17 | } else if (loc > self.length) {
18 | return;
19 | } else {
20 | [self insertString:aString atIndex:loc];
21 | }
22 | }
23 |
24 | - (void)safeAppendString:(NSString *)aString
25 | {
26 | if (aString == nil) {
27 | return;
28 | } else {
29 | [self appendString:aString];
30 | }
31 | }
32 |
33 | - (void)safeSetString:(NSString *)aString
34 | {
35 | if (aString == nil) {
36 | return;
37 | } else {
38 | [self setString:aString];
39 | }
40 | }
41 |
42 | - (NSUInteger)safeReplaceOccurrencesOfString:(NSString *)target withString:(NSString *)replacement options:(NSStringCompareOptions)options range:(NSRange)searchRange
43 | {
44 | NSUInteger location = searchRange.location;
45 | NSUInteger length = searchRange.length;
46 |
47 | if (target == nil || replacement == nil) {
48 | return 0;
49 | } else if (location + length > self.length) {
50 | return 0;
51 | } else {
52 | return [self replaceOccurrencesOfString:target withString:replacement options:options range:searchRange];
53 | }
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSObject+Category.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Category.h
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/8/23.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface NSObject (Category)
13 | @property (nonatomic, strong, readonly) NSMutableArray *associatedObjectNames;
14 |
15 | /**
16 | * 为当前object动态增加分类
17 | *
18 | * @param propertyName 分类名称
19 | * @param value 分类值
20 | * @param policy 分类内存管理类型
21 | */
22 | - (void)objc_setAssociatedObject:(NSString *)propertyName value:(id)value policy:(objc_AssociationPolicy)policy;
23 | /**
24 | * 获取当前object某个动态增加的分类
25 | *
26 | * @param propertyName 分类名称
27 | *
28 | * @return 值
29 | */
30 | - (id)objc_getAssociatedObject:(NSString *)propertyName;
31 | /**
32 | * 删除动态增加的所有分类
33 | */
34 | - (void)objc_removeAssociatedObjects;
35 |
36 | /**
37 | * 获取对象的所有属性
38 | *
39 | * @return 属性dict
40 | */
41 | - (NSArray *)getProperties;
42 |
43 |
44 | @end
45 |
46 |
47 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSObject+Category.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Category.m
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/8/23.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import "NSObject+Category.h"
10 |
11 | @implementation NSObject (Category)
12 | static char associatedObjectNamesKey;
13 |
14 | - (void)setAssociatedObjectNames:(NSMutableArray *)associatedObjectNames
15 | {
16 | objc_setAssociatedObject(self, &associatedObjectNamesKey, associatedObjectNames,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
17 | }
18 |
19 | - (NSMutableArray *)associatedObjectNames
20 | {
21 | NSMutableArray *array = objc_getAssociatedObject(self, &associatedObjectNamesKey);
22 | if (!array) {
23 | array = [NSMutableArray array];
24 | [self setAssociatedObjectNames:array];
25 | }
26 | return array;
27 | }
28 |
29 | - (void)objc_setAssociatedObject:(NSString *)propertyName value:(id)value policy:(objc_AssociationPolicy)policy
30 | {
31 | objc_setAssociatedObject(self, (__bridge objc_objectptr_t)propertyName, value, policy);
32 | [self.associatedObjectNames addObject:propertyName];
33 | }
34 |
35 | - (id)objc_getAssociatedObject:(NSString *)propertyName
36 | {
37 | return objc_getAssociatedObject(self, (__bridge objc_objectptr_t)propertyName);
38 | }
39 |
40 | - (void)objc_removeAssociatedObjects
41 | {
42 | [self.associatedObjectNames removeAllObjects];
43 | objc_removeAssociatedObjects(self);
44 | }
45 |
46 | - (void)setValue:(id)value forUndefinedKey:(NSString *)key
47 | {
48 | NSLog(@"setValue %@ forUndefinedKey %@",value,key);
49 | }
50 |
51 | - (void)setNilValueForKey:(NSString *)key
52 | {
53 | NSLog(@"setNilValue forKey %@",key);
54 | }
55 |
56 | /**
57 | * 获取对象的所有属性,包括父类的。可以一直遍历到JSONModel层。如果不是继承JSONMOdel,最上层为NSObject
58 | *
59 | * @return Properties数组
60 | */
61 | - (NSArray *)getProperties
62 | {
63 | NSMutableArray *props = [NSMutableArray array];
64 | unsigned int outCount, i;
65 | Class targetClass = [self class];
66 | while (targetClass != [NSObject class]) {
67 | objc_property_t *properties = class_copyPropertyList(targetClass, &outCount);
68 | for (i = 0; i < outCount; i++)
69 | {
70 | objc_property_t property = properties[i];
71 | const char *char_f = property_getName(property);
72 | NSString *propertyName = [NSString stringWithUTF8String:char_f];
73 | [props addObject:propertyName];
74 | }
75 | free(properties);
76 | targetClass = [targetClass superclass];
77 | }
78 | return props;
79 | }
80 |
81 | /* 获取对象的所有方法 */
82 | - (void)printMothList
83 | {
84 | unsigned int mothCout_f = 0;
85 | Method *mothList_f = class_copyMethodList([self class], &mothCout_f);
86 | for(int i = 0; i < mothCout_f; i++)
87 | {
88 | Method temp_f = mothList_f[i];
89 | // IMP imp_f = method_getImplementation(temp_f);
90 | SEL name_f = method_getName(temp_f);
91 | const char* name_s = sel_getName(name_f);
92 | int arguments = method_getNumberOfArguments(temp_f);
93 | const char* encoding = method_getTypeEncoding(temp_f);
94 |
95 | NSLog(@"方法名:%@,参数个数:%d,编码方式:%@",[NSString stringWithUTF8String:name_s], arguments, [NSString stringWithUTF8String:encoding]);
96 | }
97 |
98 | free(mothList_f);
99 | }
100 |
101 |
102 | @end
103 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSObject+PerformBlock.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+PerformBlock.h
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/8/23.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSObject (PerformBlock)
12 | // try catch
13 | + (NSException *)tryCatch:(void(^)())block;
14 | + (NSException *)tryCatch:(void(^)())block finally:(void(^)())aFinisheBlock;
15 |
16 | /**
17 | * 在主线程运行block
18 | *
19 | * @param aInMainBlock 被运行的block
20 | */
21 | + (void)performInMainThreadBlock:(void(^)())aInMainBlock;
22 | /**
23 | * 延时在主线程运行block
24 | *
25 | * @param aInMainBlock 被运行的block
26 | * @param delay 延时时间
27 | */
28 | + (void)performInMainThreadBlock:(void(^)())aInMainBlock afterSecond:(NSTimeInterval)delay;
29 | /**
30 | * 在非主线程运行block
31 | *
32 | * @param aInThreadBlock 被运行的block
33 | */
34 | + (void)performInThreadBlock:(void(^)())aInThreadBlock;
35 | /**
36 | * 延时在非主线程运行block
37 | *
38 | * @param aInThreadBlock 被运行的block
39 | * @param delay 延时时间
40 | */
41 | + (void)performInThreadBlock:(void(^)())aInThreadBlock afterSecond:(NSTimeInterval)delay;
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSObject+PerformBlock.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+PerformBlock.m
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/8/23.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import "NSObject+PerformBlock.h"
10 |
11 | @implementation NSObject (PerformBlock)
12 | + (NSException *)tryCatch:(void (^)())block
13 | {
14 | NSException *result = nil;
15 |
16 | @try
17 | {
18 | block();
19 | }
20 | @catch (NSException *e)
21 | {
22 | result = e;
23 | }
24 |
25 | return result;
26 | }
27 |
28 | + (NSException *)tryCatch:(void (^)())block finally:(void(^)())aFinisheBlock
29 | {
30 | NSException *result = nil;
31 |
32 | @try
33 | {
34 | block();
35 | }
36 | @catch (NSException *e)
37 | {
38 | result = e;
39 | }
40 | @finally
41 | {
42 | aFinisheBlock();
43 | }
44 |
45 | return result;
46 | }
47 |
48 | + (void)performInMainThreadBlock:(void(^)())aInMainBlock
49 | {
50 | dispatch_async(dispatch_get_main_queue(), ^{
51 |
52 | aInMainBlock();
53 |
54 | });
55 | }
56 |
57 | + (void)performInThreadBlock:(void(^)())aInThreadBlock
58 | {
59 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
60 |
61 | aInThreadBlock();
62 |
63 | });
64 | }
65 |
66 | + (void)performInMainThreadBlock:(void(^)())aInMainBlock afterSecond:(NSTimeInterval)delay
67 | {
68 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t) (delay * NSEC_PER_SEC));
69 |
70 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
71 |
72 | aInMainBlock();
73 |
74 | });
75 | }
76 |
77 | + (void)performInThreadBlock:(void(^)())aInThreadBlock afterSecond:(NSTimeInterval)delay
78 | {
79 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t) (delay * NSEC_PER_SEC));
80 |
81 | dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
82 |
83 | aInThreadBlock();
84 |
85 | });
86 | }
87 |
88 | @end
89 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSObject+Swizzle.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Swizzle.h
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/8/23.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSObject (Swizzle)
12 |
13 | //覆盖实例方法
14 | + (void)overrideInstanceMethod:(SEL)origSelector withInstanceMethod:(SEL)newSelector;
15 |
16 | //覆盖类方法
17 | + (void)overrideClassMethod:(SEL)origSelector withClassMethod:(SEL)newSelector;
18 |
19 |
20 | //拦截实例方法
21 | + (void)exchangeInstanceMethod:(SEL)origSelector withInstanceMethod:(SEL)newSelector;
22 |
23 | //拦截类方法
24 | + (void)exchangeClassMethod:(SEL)origSelector withClassMethod:(SEL)newSelector;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSObject+Swizzle.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+Swizzle.m
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/8/23.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import "NSObject+Swizzle.h"
10 | #import
11 |
12 | @implementation NSObject (Swizzle)
13 | + (void)overrideInstanceMethod:(SEL)origSelector withInstanceMethod:(SEL)newSelector
14 | {
15 | Class class = [self class];
16 |
17 | Method originalMethod = class_getInstanceMethod(class, origSelector);
18 | if (!originalMethod) {
19 | NSLog(@"original method %@ not found for class %@", NSStringFromSelector(origSelector), [self class]);
20 | return;
21 | }
22 |
23 | Method overrideMethod = class_getInstanceMethod(class, newSelector);
24 | if (!overrideMethod) {
25 | NSLog(@"original method %@ not found for class %@", NSStringFromSelector(newSelector), [self class]);
26 | return;
27 | }
28 |
29 |
30 | BOOL didAddMethod = class_addMethod(class,
31 | origSelector,
32 | method_getImplementation(overrideMethod),
33 | method_getTypeEncoding(overrideMethod));
34 | if (didAddMethod) {
35 | class_replaceMethod(class,
36 | newSelector,
37 | method_getImplementation(originalMethod),
38 | method_getTypeEncoding(originalMethod));
39 | } else {
40 | method_setImplementation(originalMethod, class_getMethodImplementation(self, newSelector));
41 | }
42 | }
43 |
44 | + (void)overrideClassMethod:(SEL)origSelector withClassMethod:(SEL)newSelector
45 | {
46 | Class class = [self class];
47 |
48 | Method originalMethod = class_getClassMethod(class, origSelector);
49 | Method overrideMethod = class_getClassMethod(class, newSelector);
50 |
51 | BOOL didAddMethod = class_addMethod(class,
52 | origSelector,
53 | method_getImplementation(overrideMethod),
54 | method_getTypeEncoding(overrideMethod));
55 | if (didAddMethod) {
56 | class_replaceMethod(class,
57 | newSelector,
58 | method_getImplementation(originalMethod),
59 | method_getTypeEncoding(originalMethod));
60 | } else {
61 | method_setImplementation(originalMethod, class_getMethodImplementation(self, newSelector));
62 | }
63 | }
64 |
65 |
66 | + (void)exchangeInstanceMethod:(SEL)origSelector withInstanceMethod:(SEL)newSelector
67 | {
68 | Class class = [self class];
69 |
70 | Method originalMethod = class_getInstanceMethod(class, origSelector);
71 | Method swizzledMethod = class_getInstanceMethod(class, newSelector);
72 |
73 | BOOL didAddMethod = class_addMethod(class,
74 | origSelector,
75 | method_getImplementation(swizzledMethod),
76 | method_getTypeEncoding(swizzledMethod));
77 | if (didAddMethod) {
78 | class_replaceMethod(class,
79 | newSelector,
80 | method_getImplementation(originalMethod),
81 | method_getTypeEncoding(originalMethod));
82 | } else {
83 | method_exchangeImplementations(originalMethod, swizzledMethod);
84 | }
85 | }
86 |
87 | + (void)exchangeClassMethod:(SEL)origSelector withClassMethod:(SEL)newSelector
88 | {
89 | Class class = [self class];
90 |
91 | Method originalMethod = class_getClassMethod(class, origSelector);
92 | Method swizzledMethod = class_getClassMethod(class, newSelector);
93 |
94 | BOOL didAddMethod = class_addMethod(class,
95 | origSelector,
96 | method_getImplementation(swizzledMethod),
97 | method_getTypeEncoding(swizzledMethod));
98 | if (didAddMethod) {
99 | class_replaceMethod(class,
100 | newSelector,
101 | method_getImplementation(originalMethod),
102 | method_getTypeEncoding(originalMethod));
103 | } else {
104 | method_exchangeImplementations(originalMethod, swizzledMethod);
105 | }
106 | }
107 |
108 | @end
109 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSString+Category.h:
--------------------------------------------------------------------------------
1 | //
2 | // PK-ios
3 | //
4 | // Created by peikua on 15/9/15.
5 | // Copyright (c) 2015年 peikua. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | #import
11 |
12 | @interface NSString (Category)
13 | /// 字典转Json字符串
14 | /// @param dic
15 | + (NSString *) dicTransToJSONStringWith:(NSDictionary *)dic;
16 | /**
17 | 电话号码中间4位*显示
18 |
19 | @param phoneNum 电话号码
20 | @return 135*****262
21 | */
22 | + (NSString*) getSecrectStringWithPhoneNumber:(NSString*)phoneNum;
23 |
24 |
25 | /**
26 | 银行卡号中间8位*显示
27 |
28 | @param accountNo 银行卡号
29 | @return <#return value description#>
30 | */
31 | + (NSString*) getSecrectStringWithAccountNo:(NSString*)accountNo;
32 |
33 |
34 | /**
35 | 转为手机格式,默认为-
36 |
37 | @param mobile
38 | @return <#return value description#>
39 | */
40 | + (NSString*) stringMobileFormat:(NSString*)mobile;
41 |
42 | //数组中文格式(几万)可自行添加
43 |
44 | /**
45 | 金额数字添加单位(暂时写了万和亿,有更多的需求请参考写法来自行添加)
46 |
47 | @param value 金额
48 | @return <#return value description#>
49 | */
50 | + (NSString*) stringChineseFormat:(double)value;
51 |
52 |
53 | /**
54 | 添加数字的千位符
55 |
56 | @param num <#num description#>
57 | @return <#return value description#>
58 | */
59 | + (NSString*) countNumAndChangeformat:(NSString *)num;
60 |
61 | /**
62 | * NSString转为NSNumber
63 | *
64 | * @return NSNumber
65 | */
66 | - (NSNumber*) toNumber;
67 |
68 | /**
69 | 计算文字高度
70 |
71 | @param fontSize 字体
72 | @param width 最大宽度
73 | @return <#return value description#>
74 | */
75 | - (CGFloat ) heightWithFontSize:(CGFloat)fontSize width:(CGFloat)width;
76 |
77 | /**
78 | 计算文字宽度
79 |
80 | @param fontSize 字体
81 | @param maxHeight 最大高度
82 | @return <#return value description#>
83 | */
84 | - (CGFloat ) widthWithFontSize:(CGFloat)fontSize height:(CGFloat)maxHeight;
85 | /**
86 | 抹除小数末尾的0
87 |
88 | @return <#return value description#>
89 | */
90 | - (NSString*) removeUnwantedZero;
91 |
92 | /**
93 | //去掉前后空格
94 |
95 | @return <#return value description#>
96 | */
97 | - (NSString*) trimmedString;
98 |
99 | @end
100 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSString+Category.m:
--------------------------------------------------------------------------------
1 | //
2 | // PK-ios
3 | //
4 | // Created by peikua on 15/9/15.
5 | // Copyright (c) 2015年 peikua. All rights reserved.
6 | //
7 |
8 | #import "NSString+Category.h"
9 |
10 | @implementation NSString (Category)
11 | + (NSString *) dicTransToJSONStringWith:(NSDictionary *)dic{
12 | NSError *error;
13 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&error];
14 | NSString *jsonString;
15 | if (!jsonData) {
16 | return nil;
17 | }else{
18 | jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
19 | }
20 |
21 | NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
22 | //去掉字符串中的空格
23 | NSRange range = {0,jsonString.length};
24 | [mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
25 |
26 | //去掉字符串中的换行符
27 | NSRange range2 = {0,mutStr.length};
28 | [mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
29 | return mutStr;
30 | }
31 |
32 |
33 |
34 |
35 | + (NSString*) getSecrectStringWithPhoneNumber:(NSString*)phoneNum
36 | {
37 | if (phoneNum.length==11) {
38 | NSMutableString *newStr = [NSMutableString stringWithString:phoneNum];
39 | NSRange range = NSMakeRange(3, 7);
40 | [newStr replaceCharactersInRange:range withString:@"*****"];
41 | return newStr;
42 | }
43 | return nil;
44 | }
45 |
46 | + (NSString*) getSecrectStringWithAccountNo:(NSString*)accountNo
47 | {
48 | NSMutableString *newStr = [NSMutableString stringWithString:accountNo];
49 | NSRange range = NSMakeRange(4, 8);
50 | if (newStr.length>12) {
51 | [newStr replaceCharactersInRange:range withString:@" **** **** "];
52 | }
53 | return newStr;
54 | }
55 |
56 | + (NSString*) stringMobileFormat:(NSString *)mobile {
57 | if (mobile.length==11) {
58 | NSMutableString* value = [[NSMutableString alloc] initWithString:mobile];
59 | [value insertString:@"-" atIndex:3];
60 | [value insertString:@"-" atIndex:8];
61 | return value;
62 | }
63 |
64 | return nil;
65 | }
66 |
67 | + (NSString*) stringChineseFormat:(double)value{
68 |
69 | if (value / 100000000 >= 1) {
70 | return [NSString stringWithFormat:@"%.0f亿",value/100000000];
71 | }
72 | else if (value / 10000 >= 1 && value / 100000000 < 1) {
73 | return [NSString stringWithFormat:@"%.0f万",value/10000];
74 | }
75 | else {
76 | return [NSString stringWithFormat:@"%.0f",value];
77 | }
78 | }
79 |
80 | +(NSString *)countNumAndChangeformat:(NSString *)num
81 | {
82 | NSNumberFormatter *moneyFormatter = [[NSNumberFormatter alloc] init];
83 | moneyFormatter.positiveFormat = @"###,###";
84 | //如要增加小数点请自行修改为@"###,###,##"
85 | return [moneyFormatter stringFromNumber:[num toNumber]];
86 | }
87 |
88 | -(CGFloat)heightWithFontSize:(CGFloat)fontSize width:(CGFloat)width
89 | {
90 | NSDictionary *attrs = @{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]};
91 | return [self boundingRectWithSize:CGSizeMake(width, 0) options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attrs context:nil].size.height;
92 | }
93 |
94 | - (CGFloat) widthWithFontSize:(CGFloat)fontSize height:(CGFloat)maxHeight
95 | {
96 | NSDictionary *attrs = @{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]};
97 | return [self boundingRectWithSize:CGSizeMake(0, maxHeight) options:NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attrs context:nil].size.width;
98 | }
99 |
100 | - (NSNumber*)toNumber
101 | {
102 | NSNumberFormatter *formatter=[[NSNumberFormatter alloc] init];
103 | [formatter setNumberStyle:NSNumberFormatterDecimalStyle];
104 | NSNumber *number=[formatter numberFromString:self];
105 | return number;
106 | }
107 |
108 | /*抹除运费小数末尾的0*/
109 | - (NSString *)removeUnwantedZero {
110 | if ([[self substringWithRange:NSMakeRange(self.length- 3, 3)] isEqualToString:@"000"]) {
111 | return [self substringWithRange:NSMakeRange(0, self.length-4)]; // 多一个小数点
112 | } else if ([[self substringWithRange:NSMakeRange(self.length- 2, 2)] isEqualToString:@"00"]) {
113 | return [self substringWithRange:NSMakeRange(0, self.length-2)];
114 | } else if ([[self substringWithRange:NSMakeRange(self.length- 1, 1)] isEqualToString:@"0"]) {
115 | return [self substringWithRange:NSMakeRange(0, self.length-1)];
116 | } else {
117 | return self;
118 | }
119 | }
120 |
121 | //去掉前后空格
122 | - (NSString *)trimmedString{
123 | return [self stringByTrimmingCharactersInSet:[NSCharacterSet decimalDigitCharacterSet]];
124 | }
125 |
126 |
127 | @end
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSString+DisplayTime.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+DisplayTime.h
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 16/7/20.
6 | // Copyright © 2016年 BBFC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSString (DisplayTime)
12 | /**
13 | 通过时间戳计算时间差(几小时前、几天前
14 |
15 | @param compareDate <#compareDate description#>
16 | @return <#return value description#>
17 | */
18 | + (NSString *) compareCurrentTime:(NSTimeInterval) compareDate;
19 |
20 | /**
21 | 通过时间戳得出对应的时间
22 |
23 | @param timestamp 时间戳
24 | @return <#return value description#>
25 | */
26 | + (NSString *) getDateStringWithTimestamp:(NSTimeInterval)timestamp;
27 |
28 | /**
29 | //通过时间戳和显示时间
30 | @param timestamp 时间戳
31 | @param formatter 格式
32 | @return <#return value description#>
33 | */
34 | + (NSString *) getStringWithTimestamp:(NSTimeInterval)timestamp formatter:(NSString*)formatter;
35 | @end
36 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSString+DisplayTime.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+DisplayTime.m
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 16/7/20.
6 | // Copyright © 2016年 BBFC. All rights reserved.
7 | //
8 |
9 | #import "NSString+DisplayTime.h"
10 |
11 | @implementation NSString (DisplayTime)
12 |
13 | +(NSString *) compareCurrentTime:(NSTimeInterval) compareDate
14 | {
15 | NSDate *confromTimesp = [NSDate dateWithTimeIntervalSince1970:compareDate/1000];
16 |
17 | NSTimeInterval timeInterval = [confromTimesp timeIntervalSinceNow];
18 | timeInterval = -timeInterval;
19 | long temp = 0;
20 | NSString *result;
21 |
22 | NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
23 | NSInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday |
24 | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
25 | NSDateComponents*referenceComponents=[calendar components:unitFlags fromDate:confromTimesp];
26 | // NSInteger referenceYear =referenceComponents.year;
27 | // NSInteger referenceMonth =referenceComponents.month;
28 | // NSInteger referenceDay =referenceComponents.day;
29 | NSInteger referenceHour =referenceComponents.hour;
30 | // NSInteger referemceMinute=referenceComponents.minute;
31 |
32 | if (timeInterval < 60) {
33 | result = [NSString stringWithFormat:@"刚刚"];
34 | }
35 | else if((temp= timeInterval/60) < 60){
36 | result = [NSString stringWithFormat:@"%ld分钟前",temp];
37 | }
38 |
39 | else if((temp = timeInterval/3600) <24){
40 | result = [NSString stringWithFormat:@"%ld小时前",temp];
41 | }
42 | else if ((temp = timeInterval/3600/24)==1)
43 | {
44 | result = [NSString stringWithFormat:@"昨天%ld时",(long)referenceHour];
45 | }
46 | else if ((temp = timeInterval/3600/24)==2)
47 | {
48 | result = [NSString stringWithFormat:@"前天%ld时",(long)referenceHour];
49 | }
50 |
51 | else if((temp = timeInterval/3600/24) <31){
52 | result = [NSString stringWithFormat:@"%ld天前",temp];
53 | }
54 |
55 | else if((temp = timeInterval/3600/24/30) <12){
56 | result = [NSString stringWithFormat:@"%ld个月前",temp];
57 | }
58 | else{
59 | temp = temp/12;
60 | result = [NSString stringWithFormat:@"%ld年前",temp];
61 | }
62 |
63 | return result;
64 | }
65 | + (NSString*) getDateStringWithTimestamp:(NSTimeInterval)timestamp
66 | {
67 | NSDate *confromTimesp = [NSDate dateWithTimeIntervalSince1970:timestamp/1000];
68 | NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
69 | NSInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday |
70 | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
71 | NSDateComponents*referenceComponents=[calendar components:unitFlags fromDate:confromTimesp];
72 | NSInteger referenceYear =referenceComponents.year;
73 | NSInteger referenceMonth =referenceComponents.month;
74 | NSInteger referenceDay =referenceComponents.day;
75 |
76 | return [NSString stringWithFormat:@"%ld年%ld月%ld日",referenceYear,(long)referenceMonth,(long)referenceDay];
77 | }
78 |
79 |
80 |
81 | + (NSString*) getStringWithTimestamp:(NSTimeInterval)timestamp formatter:(NSString*)formatter
82 | {
83 | if ([NSString stringWithFormat:@"%@", @(timestamp)].length == 13) {
84 | timestamp /= 1000.0f;
85 | }
86 | NSDate*timestampDate=[NSDate dateWithTimeIntervalSince1970:timestamp];
87 |
88 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
89 | [dateFormatter setDateFormat:formatter];
90 | NSString *strDate = [dateFormatter stringFromDate:timestampDate];
91 |
92 | return strDate;
93 | }
94 | @end
95 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSString+MD5.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+MD5.h
3 | // PKWSevers
4 | //
5 | // Created by peikua on 16/4/27.
6 | // Copyright © 2016年 peikua. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSString (MD5)
12 | - (NSString *) md5WithString;//MD5加密
13 | @end
14 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSString+MD5.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+MD5.m
3 | // PKWSevers
4 | //
5 | // Created by peikua on 16/4/27.
6 | // Copyright © 2016年 peikua. All rights reserved.
7 | //
8 |
9 | #import "NSString+MD5.h"
10 | #import
11 |
12 | @implementation NSString (MD5)
13 |
14 | - (NSString *) md5WithString
15 | {
16 | if (self==nil || [self length]==0) {
17 | return nil;
18 | }
19 |
20 | const char *value = [self UTF8String];
21 |
22 | unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
23 | CC_MD5(value, (CC_LONG)strlen(value), outputBuffer);
24 |
25 | NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
26 | for (NSInteger count=0; count
10 |
11 | @interface NSString (Predicate)
12 |
13 | //有效的电话号码
14 | - (BOOL) isValidMobileNumber;
15 |
16 | //有效的真实姓名
17 | - (BOOL) isValidRealName;
18 |
19 | //是否只有中文
20 | - (BOOL) isOnlyChinese;
21 |
22 | //有效的验证码(根据自家的验证码位数进行修改)
23 | - (BOOL) isValidVerifyCode;
24 |
25 | //有效的银行卡号
26 | - (BOOL) isValidBankCardNumber;
27 |
28 | //有效的邮箱
29 | - (BOOL) isValidEmail;
30 |
31 | //有效的字母数字密码
32 | - (BOOL) isValidAlphaNumberPassword;
33 |
34 | //检测有效身份证
35 | //15位
36 | - (BOOL) isValidIdentifyFifteen;
37 |
38 | //18位
39 | - (BOOL) isValidIdentifyEighteen;
40 |
41 | //限制只能输入数字
42 | - (BOOL) isOnlyNumber;
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSString+Predicate.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+Predicate.m
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 16/7/20.
6 | // Copyright © 2016年 BBFC. All rights reserved.
7 | //
8 |
9 | #import "NSString+Predicate.h"
10 |
11 | @implementation NSString (Predicate)
12 | - (BOOL) isValidMobileNumber {
13 | NSString* const MOBILE = @"^1(3|4|5|7|8)\\d{9}$";
14 |
15 | NSPredicate* predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
16 | return [predicate evaluateWithObject:self];
17 | }
18 |
19 | - (BOOL) isValidVerifyCode
20 | {
21 | NSString *pattern = @"^[0-9]{4}";
22 | NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
23 | return [predicate evaluateWithObject:self];
24 | }
25 |
26 | - (BOOL) isValidRealName
27 |
28 | {
29 | NSString *nicknameRegex = @"^[\u4e00-\u9fa5]{2,8}$";
30 |
31 | NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",nicknameRegex];
32 |
33 | return [predicate evaluateWithObject:self];
34 | }
35 |
36 | - (BOOL) isOnlyChinese
37 | {
38 | NSString * chineseTest=@"^[\u4e00-\u9fa5]{0,}$";
39 | NSPredicate*chinesePredicate=[NSPredicate predicateWithFormat:@"SELF MATCHES %@",chineseTest];
40 | return [chinesePredicate evaluateWithObject:self];
41 | }
42 |
43 |
44 | - (BOOL) isValidBankCardNumber {
45 | NSString* const BANKCARD = @"^(\\d{16}|\\d{19})$";
46 |
47 | NSPredicate* predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", BANKCARD];
48 | return [predicate evaluateWithObject:self];
49 | }
50 |
51 |
52 | - (BOOL) isValidEmail
53 | {
54 |
55 | NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
56 | NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
57 |
58 | return [emailTest evaluateWithObject:self];
59 |
60 | }
61 | - (BOOL) validateNickName
62 | {
63 | NSString *userNameRegex = @"^[A-Za-z0-9\u4e00-\u9fa5]{1,24}+$";
64 |
65 | NSPredicate *userNamePredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",userNameRegex];
66 |
67 | return [userNamePredicate evaluateWithObject:self];
68 | }
69 | - (BOOL) isValidAlphaNumberPassword
70 | {
71 | NSString *regex = @"^(?!\\d+$|[a-zA-Z]+$)\\w{6,12}$";
72 | NSPredicate *identityCardPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
73 | return [identityCardPredicate evaluateWithObject:self];
74 | }
75 |
76 |
77 | - (BOOL) isValidIdentifyFifteen
78 | {
79 | NSString * identifyTest=@"^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$";
80 | NSPredicate*identifyPredicate=[NSPredicate predicateWithFormat:@"SELF MATCHES %@",identifyTest];
81 | return [identifyPredicate evaluateWithObject:self];
82 | }
83 |
84 | - (BOOL) isValidIdentifyEighteen
85 | {
86 | NSString * identifyTest=@"^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$";
87 | NSPredicate*identifyPredicate=[NSPredicate predicateWithFormat:@"SELF MATCHES %@",identifyTest];
88 | return [identifyPredicate evaluateWithObject:self];
89 | }
90 |
91 |
92 | - (BOOL) isOnlyNumber
93 | {
94 | BOOL res = YES;
95 | NSCharacterSet* tmpSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
96 | int i = 0;
97 | while (i < self.length) {
98 | NSString * string = [self substringWithRange:NSMakeRange(i, 1)];
99 | NSRange range = [string rangeOfCharacterFromSet:tmpSet];
100 | if (range.length == 0) {
101 | res = NO;
102 | break;
103 | }
104 | i++;
105 | }
106 |
107 | return res;
108 | }
109 |
110 |
111 | @end
112 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSString+Safe.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+Safe.h
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/8/24.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSString (Safe)
12 | //避免Format所得的字符串带有null
13 | + (instancetype)noNULLStringWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1,2);
14 |
15 | - (NSString *)safeSubstringFromIndex:(NSUInteger)from;
16 |
17 | - (NSString *)safeSubstringToIndex:(NSUInteger)to;
18 |
19 | - (NSString *)safeSubstringWithRange:(NSRange)range;
20 |
21 | - (NSRange)safeRangeOfString:(NSString *)aString;
22 |
23 | - (NSRange)safeRangeOfString:(NSString *)aString options:(NSStringCompareOptions)mask;
24 |
25 | - (NSString *)safeStringByAppendingString:(NSString *)aString;
26 |
27 | - (NSString *)safeStringByReplacingCharactersInRange:(NSRange)aRange withString:(NSString *)aString;
28 | @end
29 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/NSString+Safe.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+Safe.m
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/8/24.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import "NSString+Safe.h"
10 |
11 | @implementation NSString (Safe)
12 | + (instancetype)noNULLStringWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2) {
13 | va_list arglist;
14 | va_start(arglist, format);
15 | NSString *outStr = [[NSString alloc] initWithFormat:format arguments:arglist];
16 | va_end(arglist);
17 |
18 | if ([outStr containsString:@"(null)"])
19 | return [outStr stringByReplacingOccurrencesOfString:@"(null)" withString:@""];
20 | return outStr;
21 | }
22 |
23 |
24 | - (NSString *)safeSubstringFromIndex:(NSUInteger)from
25 | {
26 | if (from > self.length) {
27 | return nil;
28 | } else {
29 | return [self substringFromIndex:from];
30 | }
31 | }
32 |
33 | - (NSString *)safeSubstringToIndex:(NSUInteger)to
34 | {
35 | if (to > self.length) {
36 | return nil;
37 | } else {
38 | return [self substringToIndex:to];
39 | }
40 | }
41 |
42 | - (NSString *)safeSubstringWithRange:(NSRange)range
43 | {
44 | NSUInteger location = range.location;
45 | NSUInteger length = range.length;
46 | if (location+length > self.length) {
47 | return nil;
48 | } else {
49 | return [self substringWithRange:range];
50 | }
51 | }
52 |
53 | - (NSRange)safeRangeOfString:(NSString *)aString
54 | {
55 | if (aString == nil) {
56 | return NSMakeRange(NSNotFound, 0);
57 | } else {
58 | return [self rangeOfString:aString];
59 | }
60 | }
61 |
62 | - (NSRange)safeRangeOfString:(NSString *)aString options:(NSStringCompareOptions)mask
63 | {
64 | if (aString == nil) {
65 | return NSMakeRange(NSNotFound, 0);
66 | } else {
67 | return [self rangeOfString:aString options:mask];
68 | }
69 | }
70 |
71 | - (NSString *)safeStringByAppendingString:(NSString *)aString
72 | {
73 | if (aString == nil) {
74 | return [self stringByAppendingString:@""];
75 | } else {
76 | return [self stringByAppendingString:aString];
77 | }
78 | }
79 |
80 | - (NSString *)safeStringByReplacingCharactersInRange:(NSRange)aRange withString:(NSString *)aString
81 | {
82 | if (aString == nil || ![aString isKindOfClass:[NSString class]]) {
83 | return self;
84 | }
85 | return [self safeStringByReplacingCharactersInRange:aRange withString:aString];
86 | }
87 |
88 | @end
89 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/UIButton+Category.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIButton+Category.h
3 | // haitao
4 | //
5 | // Created by Yuen-iMac on 16/5/4.
6 | // Copyright © 2016年 上海市配夸网络科技有限公司. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef void(^ButtonActionCallBack)(UIButton *button);
12 | @interface UIButton (Category)
13 |
14 | -(void)addCallBackAction:(ButtonActionCallBack)action
15 | forControlEvents:(UIControlEvents)controlEvents;
16 |
17 | -(void)addCallBackAction:(ButtonActionCallBack)action;
18 |
19 | @end
20 |
21 | @interface UIButton (EnlargeTouchArea)
22 |
23 | /**
24 | * 扩大 UIButton 的點擊範圍
25 | * 控制上下左右的延長範圍
26 | *
27 | * @param top <#top description#>
28 | * @param right <#right description#>
29 | * @param bottom <#bottom description#>
30 | * @param left <#left description#>
31 | */
32 | - (void)setEnlargeEdgeWithTop:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom left:(CGFloat)left;
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/UIButton+Category.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIButton+Category.m
3 | // haitao
4 | //
5 | // Created by Yuen-iMac on 16/5/4.
6 | // Copyright © 2016年 上海市配夸网络科技有限公司. All rights reserved.
7 | //
8 |
9 | #import "UIButton+Category.h"
10 | #import
11 |
12 | @interface UIButton ()
13 | @property(nonatomic ,copy) ButtonActionCallBack block;
14 | @end
15 |
16 | @implementation UIButton (Category)
17 |
18 | -(void)addCallBackAction:(ButtonActionCallBack)action
19 | forControlEvents:(UIControlEvents)controlEvents
20 | {
21 | self.block = action;
22 | [self addTarget:self action:@selector(click:)forControlEvents:controlEvents];
23 | }
24 |
25 | -(void)addCallBackAction:(ButtonActionCallBack)action
26 | {
27 | [self addCallBackAction:action forControlEvents:UIControlEventTouchUpInside];
28 | }
29 |
30 | -(void)click:(UIButton*)btn
31 | {
32 | if(self.block) {
33 | self.block(btn);
34 | }
35 | }
36 |
37 | -(void)setBlock:(void(^)(UIButton*))block
38 |
39 | {
40 | objc_setAssociatedObject(self,@selector(block), block,OBJC_ASSOCIATION_COPY_NONATOMIC);
41 |
42 | }
43 |
44 | -(void(^)(UIButton*))block
45 |
46 | {
47 | return objc_getAssociatedObject(self,@selector(block));
48 | }
49 | @end
50 |
51 |
52 |
53 | @implementation UIButton (EnlargeTouchArea)
54 |
55 | static char topNameKey;
56 | static char rightNameKey;
57 | static char bottomNameKey;
58 | static char leftNameKey;
59 |
60 | - (void)setEnlargeEdgeWithTop:(CGFloat)top right:(CGFloat)right bottom:(CGFloat)bottom left:(CGFloat)left
61 | {
62 | objc_setAssociatedObject(self, &topNameKey, [NSNumber numberWithFloat:top], OBJC_ASSOCIATION_COPY_NONATOMIC);
63 | objc_setAssociatedObject(self, &rightNameKey, [NSNumber numberWithFloat:right], OBJC_ASSOCIATION_COPY_NONATOMIC);
64 | objc_setAssociatedObject(self, &bottomNameKey, [NSNumber numberWithFloat:bottom], OBJC_ASSOCIATION_COPY_NONATOMIC);
65 | objc_setAssociatedObject(self, &leftNameKey, [NSNumber numberWithFloat:left], OBJC_ASSOCIATION_COPY_NONATOMIC);
66 | }
67 |
68 | - (CGRect)enlargedRect
69 | {
70 | NSNumber *topEdge = objc_getAssociatedObject(self, &topNameKey);
71 | NSNumber *rightEdge = objc_getAssociatedObject(self, &rightNameKey);
72 | NSNumber *bottomEdge = objc_getAssociatedObject(self, &bottomNameKey);
73 | NSNumber *leftEdge = objc_getAssociatedObject(self, &leftNameKey);
74 | if (topEdge && rightEdge && bottomEdge && leftEdge) {
75 | return CGRectMake(self.bounds.origin.x - leftEdge.floatValue,
76 | self.bounds.origin.y - topEdge.floatValue,
77 | self.bounds.size.width + leftEdge.floatValue + rightEdge.floatValue,
78 | self.bounds.size.height + topEdge.floatValue + bottomEdge.floatValue);
79 | }
80 | else
81 | {
82 | return self.bounds;
83 | }
84 | }
85 |
86 | - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
87 | {
88 | CGRect rect = [self enlargedRect];
89 | if (CGRectEqualToRect(rect, self.bounds)) {
90 | return [super hitTest:point withEvent:event];
91 | }
92 | return CGRectContainsPoint(rect, point) ? self : nil;
93 | }
94 |
95 | @end
96 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/UIColor+Category.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+Category.h
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/8/23.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | /**
13 | * 功能:通过RGB创建颜色
14 | *
15 | * @param red <范围:0~255.0>
16 | * @param green <范围:0~255.0>
17 | * @param blue <范围:0~255.0>
18 | *
19 | * @return UIColor
20 | *
21 | * example: rgb(173.0,23.0,11.0)
22 | */
23 | UIColor *rgb(CGFloat red, CGFloat green, CGFloat blue);
24 |
25 | /**
26 | * 功能:通过RGB以及alpha创建颜色
27 | *
28 | * @param red <范围:0~255.0>
29 | * @param green <范围:0~255.0>
30 | * @param blue <范围:0~255.0>
31 | * @param alpha <范围:0~1.0>
32 | *
33 | * @return UIColor
34 | *
35 | * example: rgbA(173.0,23.0,11.0,0.5)
36 | */
37 | UIColor *rgbA(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha);
38 |
39 |
40 | @interface UIColor (Category)
41 |
42 | /**
43 | * Create a color from a HEX string.
44 | * It supports the following type:
45 | * - #RGB
46 | * - #ARGB
47 | * - #RRGGBB
48 | * - #AARRGGBB
49 | *
50 | * @param hexString NSString
51 | *
52 | * @return Returns the UIColor instance
53 | */
54 | + (UIColor *)hex:(NSString *)hexString;
55 |
56 | /**
57 | * 通过0xffffff的16进制数字创建颜色
58 | *
59 | * @param aRGB 0xffffff
60 | *
61 | * @return UIColor
62 | */
63 | + (UIColor *)colorWithRGB:(NSUInteger)aRGB;
64 |
65 |
66 | /**
67 | 调节颜色的明亮度
68 |
69 | @param color 颜色
70 | @param delta 明亮度
71 | @return <#return value description#>
72 | */
73 | + (UIColor*) colorRGBonvertToHSB:(UIColor*)color withBrighnessDelta:(CGFloat)delta;
74 |
75 |
76 | /**
77 | 调整颜色的透明度
78 |
79 | @param color 颜色
80 | @param delta 透明度
81 | @return <#return value description#>
82 | */
83 | + (UIColor*) colorRGBonvertToHSB:(UIColor*)color withAlphaDelta:(CGFloat)delta;
84 |
85 |
86 | @end
87 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/UIColor+Category.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+Category.m
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/8/23.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import "UIColor+Category.h"
10 |
11 | @implementation UIColor (Category)
12 | + (UIColor *)hex:(NSString *)hexString
13 | {
14 | NSString *cString = [[hexString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
15 |
16 | if ([cString length] < 6)
17 | return [UIColor blackColor];
18 | if ([cString hasPrefix:@"#"])
19 | cString = [cString substringFromIndex:1];
20 | if ([cString length] != 6)
21 | return [UIColor blackColor];
22 |
23 | NSRange range;
24 | range.location = 0;
25 | range.length = 2;
26 | NSString *rString = [cString substringWithRange:range];
27 |
28 | range.location = 2;
29 | NSString *gString = [cString substringWithRange:range];
30 |
31 | range.location = 4;
32 | NSString *bString = [cString substringWithRange:range];
33 |
34 | unsigned int r, g, b;
35 | [[NSScanner scannerWithString:rString] scanHexInt:&r];
36 | [[NSScanner scannerWithString:gString] scanHexInt:&g];
37 | [[NSScanner scannerWithString:bString] scanHexInt:&b];
38 |
39 | return [UIColor colorWithRed:((float) r / 255.0f)
40 | green:((float) g / 255.0f)
41 | blue:((float) b / 255.0f)
42 | alpha:1.0f];
43 | }
44 |
45 |
46 | + (UIColor *)colorWithRGB:(NSUInteger)aRGB
47 | {
48 | return [UIColor colorWithRed:((float)((aRGB & 0xFF0000) >> 16))/255.0 green:((float)((aRGB & 0xFF00) >> 8))/255.0 blue:((float)(aRGB & 0xFF))/255.0 alpha:1.0];
49 | }
50 |
51 |
52 | + (UIColor*) colorRGBonvertToHSB:(UIColor*)color withBrighnessDelta:(CGFloat)delta {
53 | CGFloat hue = 0.0f;
54 | CGFloat saturation = 0.0f;
55 | CGFloat brightness = 0.0f;
56 | CGFloat alpha = 0.0f;
57 |
58 | [color getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha];
59 |
60 | brightness += delta;
61 |
62 | return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha];
63 | }
64 |
65 | + (UIColor*) colorRGBonvertToHSB:(UIColor*)color withAlphaDelta:(CGFloat)delta {
66 | CGFloat hue = 0.0f;
67 | CGFloat saturation = 0.0f;
68 | CGFloat brightness = 0.0f;
69 | CGFloat alpha = 0.0f;
70 |
71 | [color getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha];
72 |
73 | alpha += delta;
74 |
75 | return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha];
76 | }
77 | @end
78 |
79 | UIColor *rgb(CGFloat red, CGFloat green, CGFloat blue)
80 | {
81 | return [UIColor colorWithRed:red/255.0 green:green/255.0 blue:blue/255.0 alpha:1];
82 | }
83 |
84 | UIColor *rgbA(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha)
85 | {
86 | return [UIColor colorWithRed:red/255.0 green:green/255.0 blue:blue/255.0 alpha:alpha];
87 | }
88 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/UIImage+Category.h:
--------------------------------------------------------------------------------
1 | //
2 | // PK-ios
3 | //
4 | // Created by peikua on 15/9/15.
5 | // Copyright (c) 2015年 peikua. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 |
11 | @interface UIImage (Category)
12 |
13 | //由颜色生成图片
14 | + (UIImage *) imageWithColor:(UIColor*)color;
15 |
16 | //将图片剪裁至目标尺寸
17 | + (UIImage *) imageByScalingAndCroppingForSourceImage:(UIImage *)sourceImage targetSize:(CGSize)targetSize;
18 |
19 | //图片旋转角度
20 | - (UIImage *) imageRotatedByDegrees:(CGFloat)degrees;
21 |
22 | //拉伸图片UIEdgeInsets
23 | - (UIImage *) resizableImage:(UIEdgeInsets)insets;
24 |
25 | //拉伸图片CGFloat
26 | - (UIImage *) imageByResizeToScale:(CGFloat)scale;
27 |
28 | //放大图片CGSize
29 | - (UIImage *) imageByResizeWithMaxSize:(CGSize)size;
30 |
31 | //小样图图片CGSize
32 | - (UIImage *) imageWithThumbnailForSize:(CGSize)size;
33 |
34 | //通过Rect剪裁图片
35 | - (UIImage *) imageByCropToRect:(CGRect)rect;
36 |
37 | //图片增加圆角
38 | - (UIImage *) imageByRoundCornerRadius:(CGFloat)radius;
39 |
40 | //图片增加圆角及边框
41 | - (UIImage *) imageByRoundCornerRadius:(CGFloat)radius
42 | borderWidth:(CGFloat)borderWidth
43 | borderColor:(UIColor *)borderColor;
44 |
45 | //图片向左90度
46 | - (UIImage *)imageByRotateLeft90;
47 |
48 | //图片向右90度
49 | - (UIImage *)imageByRotateRight90;
50 |
51 | //图片转180度
52 | - (UIImage *)imageByRotate180;
53 |
54 |
55 | @end
56 |
57 |
58 | @interface UIImage (Blur)
59 | //玻璃化效果,这里与系统的玻璃化枚举效果一样,但只是一张图
60 | - (UIImage *)imageByBlurSoft;
61 |
62 | - (UIImage *)imageByBlurLight;
63 |
64 | - (UIImage *)imageByBlurExtraLight;
65 |
66 | - (UIImage *)imageByBlurDark;
67 |
68 | - (UIImage *)imageByBlurWithTint:(UIColor *)tintColor;
69 |
70 | - (UIImage *)imageByBlurRadius:(CGFloat)blurRadius
71 | tintColor:(UIColor *)tintColor
72 | tintMode:(CGBlendMode)tintBlendMode
73 | saturation:(CGFloat)saturation
74 | maskImage:(UIImage *)maskImage;
75 |
76 | - (UIImage *) boxblurImageWithBlur:(CGFloat)blur exclusionPath:(UIBezierPath *)exclusionPath;
77 | @end
78 |
79 |
80 |
81 |
82 |
83 | @interface UIImage (ImageEffects)
84 |
85 | //图片效果
86 |
87 | - (UIImage *)applyLightEffect;
88 | - (UIImage *)applyExtraLightEffect;
89 | - (UIImage *)applyDarkEffect;
90 | - (UIImage *)applyBlurEffect;
91 | - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor;
92 | - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius
93 | tintColor:(UIColor *)tintColor
94 | saturationDeltaFactor:(CGFloat)saturationDeltaFactor
95 | maskImage:(UIImage *)maskImage;
96 | @end
97 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/UIImage+Category.m:
--------------------------------------------------------------------------------
1 | //
2 | // PK-ios
3 | //
4 | // Created by peikua on 15/9/15.
5 | // Copyright (c) 2015年 peikua. All rights reserved.
6 | //
7 |
8 | #import "UIImage+Category.h"
9 | #import
10 | #import
11 | #define ORIGINAL_MAX_WIDTH 640.0f
12 | #define YY_SWAP(_a_, _b_) do { __typeof__(_a_) _tmp_ = (_a_); (_a_) = (_b_); (_b_) = _tmp_; } while (0)
13 | @implementation UIImage (Category)
14 |
15 | - (UIImage*)imageRotatedByDegrees:(CGFloat)degrees
16 | {
17 |
18 | CGFloat width = CGImageGetWidth(self.CGImage);
19 | CGFloat height = CGImageGetHeight(self.CGImage);
20 |
21 | CGSize rotatedSize;
22 |
23 | rotatedSize.width = width;
24 | rotatedSize.height = height;
25 |
26 | UIGraphicsBeginImageContext(rotatedSize);
27 | CGContextRef bitmap = UIGraphicsGetCurrentContext();
28 | CGContextTranslateCTM(bitmap, rotatedSize.width/2, rotatedSize.height/2);
29 | CGContextRotateCTM(bitmap, degrees * M_PI / 180);
30 | CGContextRotateCTM(bitmap, M_PI);
31 | CGContextScaleCTM(bitmap, -1.0, 1.0);
32 | CGContextDrawImage(bitmap, CGRectMake(-rotatedSize.width/2, -rotatedSize.height/2, rotatedSize.width, rotatedSize.height), self.CGImage);
33 | UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
34 | UIGraphicsEndImageContext();
35 | return newImage;
36 | }
37 |
38 | - (UIImage*) resizableImage:(UIEdgeInsets)insets {
39 | if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0f) {
40 | return [self resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeStretch];
41 | }
42 |
43 | return [self stretchableImageWithLeftCapWidth:insets.left topCapHeight:insets.top];
44 | }
45 |
46 |
47 | + (UIImage *) imageByScalingAndCroppingForSourceImage:(UIImage *)sourceImage targetSize:(CGSize)targetSize {
48 | UIImage *newImage = nil;
49 | CGSize imageSize = sourceImage.size;
50 | CGFloat width = imageSize.width;
51 | CGFloat height = imageSize.height;
52 | CGFloat targetWidth = targetSize.width;
53 | CGFloat targetHeight = targetSize.height;
54 | CGFloat scaleFactor = 0.0;
55 | CGFloat scaledWidth = targetWidth;
56 | CGFloat scaledHeight = targetHeight;
57 | CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
58 | if (CGSizeEqualToSize(imageSize, targetSize) == NO)
59 | {
60 | CGFloat widthFactor = targetWidth / width;
61 | CGFloat heightFactor = targetHeight / height;
62 |
63 | if (widthFactor > heightFactor)
64 | scaleFactor = widthFactor; // scale to fit height
65 | else
66 | scaleFactor = heightFactor; // scale to fit width
67 | scaledWidth = width * scaleFactor;
68 | scaledHeight = height * scaleFactor;
69 |
70 | // center the image
71 | if (widthFactor > heightFactor)
72 | {
73 | thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
74 | }
75 | else
76 | if (widthFactor < heightFactor)
77 | {
78 | thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
79 | }
80 | }
81 | UIGraphicsBeginImageContext(targetSize); // this will crop
82 | CGRect thumbnailRect = CGRectZero;
83 | thumbnailRect.origin = thumbnailPoint;
84 | thumbnailRect.size.width = scaledWidth;
85 | thumbnailRect.size.height = scaledHeight;
86 |
87 | [sourceImage drawInRect:thumbnailRect];
88 |
89 | newImage = UIGraphicsGetImageFromCurrentImageContext();
90 | if(newImage == nil) NSLog(@"could not scale image");
91 |
92 | //pop the context to get back to the default
93 | UIGraphicsEndImageContext();
94 | return newImage;
95 | }
96 | + (UIImage*) imageWithColor:(UIColor *)color {
97 | CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
98 | UIGraphicsBeginImageContext(rect.size);
99 | CGContextRef context = UIGraphicsGetCurrentContext();
100 | CGContextSetFillColorWithColor(context, color.CGColor);
101 | CGContextFillRect(context, rect);
102 |
103 | UIImage* image = UIGraphicsGetImageFromCurrentImageContext();
104 | UIGraphicsEndImageContext();
105 |
106 | NSData* imageData = UIImageJPEGRepresentation(image, 1.0f);
107 | image = [UIImage imageWithData:imageData];
108 | return image;
109 | }
110 |
111 |
112 | - (UIImage *)imageByResizeToScale:(CGFloat)scale{
113 | CGSize size = CGSizeMake(self.size.width *scale, self.size.height * scale);
114 | if (size.width <= 0 || size.height <= 0) return nil;
115 | UIGraphicsBeginImageContextWithOptions(size, NO, self.scale);
116 | [self drawInRect:CGRectMake(0, 0, size.width, size.height)];
117 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
118 | UIGraphicsEndImageContext();
119 | return image;
120 | }
121 | - (UIImage *)imageByResizeWithMaxSize:(CGSize)size{
122 | CGSize resize = self.size;
123 | if(resize.width > size.width){
124 | resize = CGSizeMake(size.width, size.width/resize.width * resize.height);
125 | }
126 | if(resize.height > size.height){
127 | resize = CGSizeMake(size.height/resize.height * resize.width, size.height);
128 | }
129 | if (resize.width <= 0 || resize.height <= 0) return nil;
130 | UIGraphicsBeginImageContextWithOptions(resize, NO, self.scale);
131 | [self drawInRect:CGRectMake(0, 0, resize.width, resize.height)];
132 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
133 | UIGraphicsEndImageContext();
134 | return image;
135 | }
136 |
137 | - (UIImage *)imageWithThumbnailForSize:(CGSize)size{
138 | CGSize imageSize = self.size;
139 | if(imageSize.width < imageSize.height){
140 | imageSize = CGSizeMake(size.width, size.width/imageSize.width * imageSize.height);
141 | }
142 | else{
143 | imageSize = CGSizeMake(size.height/imageSize.height * imageSize.width, size.height);
144 | }
145 | if (imageSize.width <= 0 || imageSize.height <= 0) return nil;
146 | UIGraphicsBeginImageContextWithOptions(imageSize, NO, self.scale);
147 | [self drawInRect:CGRectMake(0, 0, imageSize.width, imageSize.height)];
148 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
149 | UIGraphicsEndImageContext();
150 | return image;
151 | }
152 |
153 | - (UIImage *)imageByCropToRect:(CGRect)rect {
154 | rect.origin.x *= self.scale;
155 | rect.origin.y *= self.scale;
156 | rect.size.width *= self.scale;
157 | rect.size.height *= self.scale;
158 | if (rect.size.width <= 0 || rect.size.height <= 0) return nil;
159 | CGImageRef imageRef = CGImageCreateWithImageInRect(self.CGImage, rect);
160 | UIImage *image = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation];
161 | CGImageRelease(imageRef);
162 | return image;
163 | }
164 |
165 | - (UIImage *)imageByRoundCornerRadius:(CGFloat)radius {
166 | return [self imageByRoundCornerRadius:radius borderWidth:0 borderColor:nil];
167 | }
168 |
169 | - (UIImage *)imageByRoundCornerRadius:(CGFloat)radius
170 | borderWidth:(CGFloat)borderWidth
171 | borderColor:(UIColor *)borderColor {
172 | return [self imageByRoundCornerRadius:radius
173 | corners:UIRectCornerAllCorners
174 | borderWidth:borderWidth
175 | borderColor:borderColor
176 | borderLineJoin:kCGLineJoinMiter];
177 | }
178 |
179 | - (UIImage *)imageByRoundCornerRadius:(CGFloat)radius
180 | corners:(UIRectCorner)corners
181 | borderWidth:(CGFloat)borderWidth
182 | borderColor:(UIColor *)borderColor
183 | borderLineJoin:(CGLineJoin)borderLineJoin {
184 |
185 | UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
186 | CGContextRef context = UIGraphicsGetCurrentContext();
187 | CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
188 | CGContextScaleCTM(context, 1, -1);
189 | CGContextTranslateCTM(context, 0, -rect.size.height);
190 |
191 | CGFloat minSize = MIN(self.size.width, self.size.height);
192 | if (borderWidth < minSize / 2) {
193 | UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(rect, borderWidth, borderWidth) byRoundingCorners:corners cornerRadii:CGSizeMake(radius, borderWidth)];
194 | [path closePath];
195 |
196 | CGContextSaveGState(context);
197 | [path addClip];
198 | CGContextDrawImage(context, rect, self.CGImage);
199 | CGContextRestoreGState(context);
200 | }
201 |
202 | if (borderColor && borderWidth < minSize / 2 && borderWidth > 0) {
203 | CGFloat strokeInset = (floor(borderWidth * self.scale) + 0.5) / self.scale;
204 | CGRect strokeRect = CGRectInset(rect, strokeInset, strokeInset);
205 | CGFloat strokeRadius = radius > self.scale / 2 ? radius - self.scale / 2 : 0;
206 | UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:strokeRect byRoundingCorners:corners cornerRadii:CGSizeMake(strokeRadius, borderWidth)];
207 | [path closePath];
208 |
209 | path.lineWidth = borderWidth;
210 | path.lineJoinStyle = borderLineJoin;
211 | [borderColor setStroke];
212 | [path stroke];
213 | }
214 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
215 | UIGraphicsEndImageContext();
216 | return image;
217 | }
218 |
219 |
220 |
221 | - (UIImage *)_yy_flipHorizontal:(BOOL)horizontal vertical:(BOOL)vertical {
222 | if (!self.CGImage) return nil;
223 | size_t width = (size_t)CGImageGetWidth(self.CGImage);
224 | size_t height = (size_t)CGImageGetHeight(self.CGImage);
225 | size_t bytesPerRow = width * 4;
226 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
227 | CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
228 | CGColorSpaceRelease(colorSpace);
229 | if (!context) return nil;
230 |
231 | CGContextDrawImage(context, CGRectMake(0, 0, width, height), self.CGImage);
232 | UInt8 *data = (UInt8 *)CGBitmapContextGetData(context);
233 | if (!data) {
234 | CGContextRelease(context);
235 | return nil;
236 | }
237 | vImage_Buffer src = { data, height, width, bytesPerRow };
238 | vImage_Buffer dest = { data, height, width, bytesPerRow };
239 | if (vertical) {
240 | vImageVerticalReflect_ARGB8888(&src, &dest, kvImageBackgroundColorFill);
241 | }
242 | if (horizontal) {
243 | vImageHorizontalReflect_ARGB8888(&src, &dest, kvImageBackgroundColorFill);
244 | }
245 | CGImageRef imgRef = CGBitmapContextCreateImage(context);
246 | CGContextRelease(context);
247 | UIImage *img = [UIImage imageWithCGImage:imgRef scale:self.scale orientation:self.imageOrientation];
248 | CGImageRelease(imgRef);
249 | return img;
250 | }
251 |
252 | - (UIImage *)imageByRotate180 {
253 | return [self _yy_flipHorizontal:YES vertical:YES];
254 | }
255 |
256 | - (UIImage *)imageByFlipVertical {
257 | return [self _yy_flipHorizontal:NO vertical:YES];
258 | }
259 |
260 | - (UIImage *)imageByFlipHorizontal {
261 | return [self _yy_flipHorizontal:YES vertical:NO];
262 | }
263 |
264 | static inline CGFloat DegreesToRadians(CGFloat degrees) {
265 | return degrees * M_PI / 180;
266 | }
267 | @end
268 |
269 |
270 | @implementation UIImage (Blur)
271 |
272 | - (UIImage *)imageByBlurSoft {
273 | return [self imageByBlurRadius:60 tintColor:[UIColor colorWithWhite:0.84 alpha:0.36] tintMode:kCGBlendModeNormal saturation:1.8 maskImage:nil];
274 | }
275 |
276 | - (UIImage *)imageByBlurLight {
277 | return [self imageByBlurRadius:60 tintColor:[UIColor colorWithWhite:1.0 alpha:0.3] tintMode:kCGBlendModeNormal saturation:1.8 maskImage:nil];
278 | }
279 |
280 | - (UIImage *)imageByBlurExtraLight {
281 | return [self imageByBlurRadius:40 tintColor:[UIColor colorWithWhite:0.97 alpha:0.82] tintMode:kCGBlendModeNormal saturation:1.8 maskImage:nil];
282 | }
283 |
284 | - (UIImage *)imageByBlurDark {
285 | return [self imageByBlurRadius:40 tintColor:[UIColor colorWithWhite:0.11 alpha:0.73] tintMode:kCGBlendModeNormal saturation:1.8 maskImage:nil];
286 | }
287 |
288 | - (UIImage *)imageByBlurWithTint:(UIColor *)tintColor {
289 | const CGFloat EffectColorAlpha = 0.6;
290 | UIColor *effectColor = tintColor;
291 | size_t componentCount = CGColorGetNumberOfComponents(tintColor.CGColor);
292 | if (componentCount == 2) {
293 | CGFloat b;
294 | if ([tintColor getWhite:&b alpha:NULL]) {
295 | effectColor = [UIColor colorWithWhite:b alpha:EffectColorAlpha];
296 | }
297 | } else {
298 | CGFloat r, g, b;
299 | if ([tintColor getRed:&r green:&g blue:&b alpha:NULL]) {
300 | effectColor = [UIColor colorWithRed:r green:g blue:b alpha:EffectColorAlpha];
301 | }
302 | }
303 | return [self imageByBlurRadius:20 tintColor:effectColor tintMode:kCGBlendModeNormal saturation:-1.0 maskImage:nil];
304 | }
305 |
306 | - (UIImage *)imageByBlurRadius:(CGFloat)blurRadius
307 | tintColor:(UIColor *)tintColor
308 | tintMode:(CGBlendMode)tintBlendMode
309 | saturation:(CGFloat)saturation
310 | maskImage:(UIImage *)maskImage {
311 | if (self.size.width < 1 || self.size.height < 1) {
312 | NSLog(@"UIImage+YYAdd error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self);
313 | return nil;
314 | }
315 | if (!self.CGImage) {
316 | NSLog(@"UIImage+YYAdd error: inputImage must be backed by a CGImage: %@", self);
317 | return nil;
318 | }
319 | if (maskImage && !maskImage.CGImage) {
320 | NSLog(@"UIImage+YYAdd error: effectMaskImage must be backed by a CGImage: %@", maskImage);
321 | return nil;
322 | }
323 |
324 | // iOS7 and above can use new func.
325 | BOOL hasNewFunc = (long)vImageBuffer_InitWithCGImage != 0 && (long)vImageCreateCGImageFromBuffer != 0;
326 | BOOL hasBlur = blurRadius > __FLT_EPSILON__;
327 | BOOL hasSaturation = fabs(saturation - 1.0) > __FLT_EPSILON__;
328 |
329 | CGSize size = self.size;
330 | CGRect rect = { CGPointZero, size };
331 | CGFloat scale = self.scale;
332 | CGImageRef imageRef = self.CGImage;
333 | BOOL opaque = NO;
334 |
335 | if (!hasBlur && !hasSaturation) {
336 | return [self _yy_mergeImageRef:imageRef tintColor:tintColor tintBlendMode:tintBlendMode maskImage:maskImage opaque:opaque];
337 | }
338 |
339 | vImage_Buffer effect = { 0 }, scratch = { 0 };
340 | vImage_Buffer *input = NULL, *output = NULL;
341 |
342 | vImage_CGImageFormat format = {
343 | .bitsPerComponent = 8,
344 | .bitsPerPixel = 32,
345 | .colorSpace = NULL,
346 | .bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little, //requests a BGRA buffer.
347 | .version = 0,
348 | .decode = NULL,
349 | .renderingIntent = kCGRenderingIntentDefault
350 | };
351 |
352 | if (hasNewFunc) {
353 | vImage_Error err;
354 | err = vImageBuffer_InitWithCGImage(&effect, &format, NULL, imageRef, kvImagePrintDiagnosticsToConsole);
355 | if (err != kvImageNoError) {
356 | NSLog(@"UIImage+YYAdd error: vImageBuffer_InitWithCGImage returned error code %zi for inputImage: %@", err, self);
357 | return nil;
358 | }
359 | err = vImageBuffer_Init(&scratch, effect.height, effect.width, format.bitsPerPixel, kvImageNoFlags);
360 | if (err != kvImageNoError) {
361 | NSLog(@"UIImage+YYAdd error: vImageBuffer_Init returned error code %zi for inputImage: %@", err, self);
362 | return nil;
363 | }
364 | } else {
365 | UIGraphicsBeginImageContextWithOptions(size, opaque, scale);
366 | CGContextRef effectCtx = UIGraphicsGetCurrentContext();
367 | CGContextScaleCTM(effectCtx, 1.0, -1.0);
368 | CGContextTranslateCTM(effectCtx, 0, -size.height);
369 | CGContextDrawImage(effectCtx, rect, imageRef);
370 | effect.data = CGBitmapContextGetData(effectCtx);
371 | effect.width = CGBitmapContextGetWidth(effectCtx);
372 | effect.height = CGBitmapContextGetHeight(effectCtx);
373 | effect.rowBytes = CGBitmapContextGetBytesPerRow(effectCtx);
374 |
375 | UIGraphicsBeginImageContextWithOptions(size, opaque, scale);
376 | CGContextRef scratchCtx = UIGraphicsGetCurrentContext();
377 | scratch.data = CGBitmapContextGetData(scratchCtx);
378 | scratch.width = CGBitmapContextGetWidth(scratchCtx);
379 | scratch.height = CGBitmapContextGetHeight(scratchCtx);
380 | scratch.rowBytes = CGBitmapContextGetBytesPerRow(scratchCtx);
381 | }
382 |
383 | input = &effect;
384 | output = &scratch;
385 |
386 | if (hasBlur) {
387 | // A description of how to compute the box kernel width from the Gaussian
388 | // radius (aka standard deviation) appears in the SVG spec:
389 | // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement
390 | //
391 | // For larger values of 's' (s >= 2.0), an approximation can be used: Three
392 | // successive box-blurs build a piece-wise quadratic convolution kernel, which
393 | // approximates the Gaussian kernel to within roughly 3%.
394 | //
395 | // let d = floor(s * 3*sqrt(2*pi)/4 + 0.5)
396 | //
397 | // ... if d is odd, use three box-blurs of size 'd', centered on the output pixel.
398 | //
399 | CGFloat inputRadius = blurRadius * scale;
400 | if (inputRadius - 2.0 < __FLT_EPSILON__) inputRadius = 2.0;
401 | uint32_t radius = floor((inputRadius * 3.0 * sqrt(2 * M_PI) / 4 + 0.5) / 2);
402 | radius |= 1; // force radius to be odd so that the three box-blur methodology works.
403 | int iterations;
404 | if (blurRadius * scale < 0.5) iterations = 1;
405 | else if (blurRadius * scale < 1.5) iterations = 2;
406 | else iterations = 3;
407 | NSInteger tempSize = vImageBoxConvolve_ARGB8888(input, output, NULL, 0, 0, radius, radius, NULL, kvImageGetTempBufferSize | kvImageEdgeExtend);
408 | void *temp = malloc(tempSize);
409 | for (int i = 0; i < iterations; i++) {
410 | vImageBoxConvolve_ARGB8888(input, output, temp, 0, 0, radius, radius, NULL, kvImageEdgeExtend);
411 | YY_SWAP(input, output);
412 | }
413 | free(temp);
414 | }
415 |
416 |
417 | if (hasSaturation) {
418 | // These values appear in the W3C Filter Effects spec:
419 | // https://dvcs.w3.org/hg/FXTF/raw-file/default/filters/Publish.html#grayscaleEquivalent
420 | CGFloat s = saturation;
421 | CGFloat matrixFloat[] = {
422 | 0.0722 + 0.9278 * s, 0.0722 - 0.0722 * s, 0.0722 - 0.0722 * s, 0,
423 | 0.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s, 0,
424 | 0.2126 - 0.2126 * s, 0.2126 - 0.2126 * s, 0.2126 + 0.7873 * s, 0,
425 | 0, 0, 0, 1,
426 | };
427 | const int32_t divisor = 256;
428 | NSUInteger matrixSize = sizeof(matrixFloat) / sizeof(matrixFloat[0]);
429 | int16_t matrix[matrixSize];
430 | for (NSUInteger i = 0; i < matrixSize; ++i) {
431 | matrix[i] = (int16_t)roundf(matrixFloat[i] * divisor);
432 | }
433 | vImageMatrixMultiply_ARGB8888(input, output, matrix, divisor, NULL, NULL, kvImageNoFlags);
434 | YY_SWAP(input, output);
435 | }
436 |
437 | UIImage *outputImage = nil;
438 | if (hasNewFunc) {
439 | CGImageRef effectCGImage = NULL;
440 | effectCGImage = vImageCreateCGImageFromBuffer(input, &format, &_yy_cleanupBuffer, NULL, kvImageNoAllocate, NULL);
441 | if (effectCGImage == NULL) {
442 | effectCGImage = vImageCreateCGImageFromBuffer(input, &format, NULL, NULL, kvImageNoFlags, NULL);
443 | free(input->data);
444 | }
445 | free(output->data);
446 | outputImage = [self _yy_mergeImageRef:effectCGImage tintColor:tintColor tintBlendMode:tintBlendMode maskImage:maskImage opaque:opaque];
447 | CGImageRelease(effectCGImage);
448 | } else {
449 | CGImageRef effectCGImage;
450 | UIImage *effectImage;
451 | if (input != &effect) effectImage = UIGraphicsGetImageFromCurrentImageContext();
452 | UIGraphicsEndImageContext();
453 | if (input == &effect) effectImage = UIGraphicsGetImageFromCurrentImageContext();
454 | UIGraphicsEndImageContext();
455 | effectCGImage = effectImage.CGImage;
456 | outputImage = [self _yy_mergeImageRef:effectCGImage tintColor:tintColor tintBlendMode:tintBlendMode maskImage:maskImage opaque:opaque];
457 | }
458 | return outputImage;
459 | }
460 |
461 | static void _yy_cleanupBuffer(void *userData, void *buf_data) {
462 | free(buf_data);
463 | }
464 | - (UIImage *)_yy_mergeImageRef:(CGImageRef)effectCGImage
465 | tintColor:(UIColor *)tintColor
466 | tintBlendMode:(CGBlendMode)tintBlendMode
467 | maskImage:(UIImage *)maskImage
468 | opaque:(BOOL)opaque {
469 | BOOL hasTint = tintColor != nil && CGColorGetAlpha(tintColor.CGColor) > __FLT_EPSILON__;
470 | BOOL hasMask = maskImage != nil;
471 | CGSize size = self.size;
472 | CGRect rect = { CGPointZero, size };
473 | CGFloat scale = self.scale;
474 |
475 | if (!hasTint && !hasMask) {
476 | return [UIImage imageWithCGImage:effectCGImage];
477 | }
478 |
479 | UIGraphicsBeginImageContextWithOptions(size, opaque, scale);
480 | CGContextRef context = UIGraphicsGetCurrentContext();
481 | CGContextScaleCTM(context, 1.0, -1.0);
482 | CGContextTranslateCTM(context, 0, -size.height);
483 | if (hasMask) {
484 | CGContextDrawImage(context, rect, self.CGImage);
485 | CGContextSaveGState(context);
486 | CGContextClipToMask(context, rect, maskImage.CGImage);
487 | }
488 | CGContextDrawImage(context, rect, effectCGImage);
489 | if (hasTint) {
490 | CGContextSaveGState(context);
491 | CGContextSetBlendMode(context, tintBlendMode);
492 | CGContextSetFillColorWithColor(context, tintColor.CGColor);
493 | CGContextFillRect(context, rect);
494 | CGContextRestoreGState(context);
495 | }
496 | if (hasMask) {
497 | CGContextRestoreGState(context);
498 | }
499 | UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
500 | UIGraphicsEndImageContext();
501 | return outputImage;
502 | }
503 |
504 |
505 | - (UIImage *) boxblurImageWithBlur:(CGFloat)blur exclusionPath:(UIBezierPath *)exclusionPath {
506 |
507 | if (blur < 0.f || blur > 1.f) {
508 | blur = 0.5f;
509 | }
510 |
511 | int boxSize = (int)(blur * 40);
512 | boxSize = boxSize - (boxSize % 2) + 1;
513 |
514 | CGImageRef img = self.CGImage;
515 | vImage_Buffer inBuffer, outBuffer;
516 | vImage_Error error;
517 | void *pixelBuffer;
518 |
519 | // create unchanged copy of the area inside the exclusionPath
520 | UIImage *unblurredImage = nil;
521 | if (exclusionPath != nil) {
522 | CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
523 | maskLayer.frame = (CGRect){CGPointZero, self.size};
524 | maskLayer.backgroundColor = [UIColor blackColor].CGColor;
525 | maskLayer.fillColor = [UIColor whiteColor].CGColor;
526 | maskLayer.path = exclusionPath.CGPath;
527 |
528 | // create grayscale image to mask context
529 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
530 | CGContextRef context = CGBitmapContextCreate(nil, maskLayer.bounds.size.width, maskLayer.bounds.size.height, 8, 0, colorSpace, kCGImageAlphaNone);
531 | CGContextTranslateCTM(context, 0, maskLayer.bounds.size.height);
532 | CGContextScaleCTM(context, 1.f, -1.f);
533 | [maskLayer renderInContext:context];
534 | CGImageRef imageRef = CGBitmapContextCreateImage(context);
535 | UIImage *maskImage = [UIImage imageWithCGImage:imageRef];
536 | CGImageRelease(imageRef);
537 | CGColorSpaceRelease(colorSpace);
538 | CGContextRelease(context);
539 |
540 | UIGraphicsBeginImageContext(self.size);
541 | context = UIGraphicsGetCurrentContext();
542 | CGContextTranslateCTM(context, 0, maskLayer.bounds.size.height);
543 | CGContextScaleCTM(context, 1.f, -1.f);
544 | CGContextClipToMask(context, maskLayer.bounds, maskImage.CGImage);
545 | CGContextDrawImage(context, maskLayer.bounds, self.CGImage);
546 | unblurredImage = UIGraphicsGetImageFromCurrentImageContext();
547 | UIGraphicsEndImageContext();
548 |
549 | }
550 |
551 | //create vImage_Buffer with data from CGImageRef
552 | CGDataProviderRef inProvider = CGImageGetDataProvider(img);
553 | CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
554 |
555 | inBuffer.width = CGImageGetWidth(img);
556 | inBuffer.height = CGImageGetHeight(img);
557 | inBuffer.rowBytes = CGImageGetBytesPerRow(img);
558 |
559 | inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);
560 |
561 | //create vImage_Buffer for output
562 | pixelBuffer = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
563 |
564 | if(pixelBuffer == NULL)
565 | NSLog(@"No pixelbuffer");
566 |
567 | outBuffer.data = pixelBuffer;
568 | outBuffer.width = CGImageGetWidth(img);
569 | outBuffer.height = CGImageGetHeight(img);
570 | outBuffer.rowBytes = CGImageGetBytesPerRow(img);
571 |
572 | // Create a third buffer for intermediate processing
573 | void *pixelBuffer2 = malloc(CGImageGetBytesPerRow(img) * CGImageGetHeight(img));
574 | vImage_Buffer outBuffer2;
575 | outBuffer2.data = pixelBuffer2;
576 | outBuffer2.width = CGImageGetWidth(img);
577 | outBuffer2.height = CGImageGetHeight(img);
578 | outBuffer2.rowBytes = CGImageGetBytesPerRow(img);
579 |
580 | //perform convolution
581 | error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer2, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
582 | error = vImageBoxConvolve_ARGB8888(&outBuffer2, &inBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
583 | error = vImageBoxConvolve_ARGB8888(&inBuffer, &outBuffer, NULL, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend);
584 |
585 | if (error) {
586 | NSLog(@"error from convolution %ld", error);
587 | }
588 |
589 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
590 | CGContextRef ctx = CGBitmapContextCreate(outBuffer.data,
591 | outBuffer.width,
592 | outBuffer.height,
593 | 8,
594 | outBuffer.rowBytes,
595 | colorSpace,
596 | kCGImageAlphaNoneSkipLast);
597 | CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
598 | UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
599 |
600 | // overlay images?
601 | if (unblurredImage != nil) {
602 | UIGraphicsBeginImageContext(returnImage.size);
603 | [returnImage drawAtPoint:CGPointZero];
604 | [unblurredImage drawAtPoint:CGPointZero];
605 |
606 | returnImage = UIGraphicsGetImageFromCurrentImageContext();
607 |
608 | UIGraphicsEndImageContext();
609 | }
610 |
611 | //clean up
612 | CGContextRelease(ctx);
613 | CGColorSpaceRelease(colorSpace);
614 | free(pixelBuffer);
615 | free(pixelBuffer2);
616 | CFRelease(inBitmapData);
617 | CGImageRelease(imageRef);
618 |
619 | return returnImage;
620 |
621 | }
622 |
623 | @end
624 |
625 |
626 | @implementation UIImage (ResizableImage)
627 |
628 | - (UIImage*) resizableImage:(UIEdgeInsets)insets {
629 | // if (IOS6) {
630 | // return [self resizableImageWithCapInsets:insets resizingMode:UIImageResizingModeStretch];
631 | // }
632 | //
633 | return [self stretchableImageWithLeftCapWidth:insets.left topCapHeight:insets.top];
634 | }
635 | @end
636 |
637 |
638 |
639 | @implementation UIImage (ImageEffects)
640 |
641 | - (UIImage *)applyLightEffect {
642 | UIColor* tintColor = [UIColor colorWithWhite:1.0 alpha:0.3];
643 | return [self applyBlurWithRadius:30 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
644 | }
645 |
646 | - (UIImage *)applyExtraLightEffect {
647 | UIColor* tintColor = [UIColor colorWithWhite:0.97 alpha:0.82];
648 | return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
649 | }
650 |
651 | - (UIImage *)applyDarkEffect {
652 | UIColor* tintColor = [UIColor colorWithWhite:0.11 alpha:0.73];
653 | return [self applyBlurWithRadius:30 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil];
654 | }
655 |
656 | - (UIImage *)applyBlurEffect {
657 | UIColor* tintColor = [UIColor colorWithWhite:0.4f alpha:0.3f];
658 | return [self applyBlurWithRadius:8.0f tintColor:tintColor saturationDeltaFactor:1.8f maskImage:nil];
659 | }
660 |
661 | - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor {
662 | const CGFloat EffectColorAlpha = 0.6;
663 | UIColor* effectColor = tintColor;
664 | NSUInteger componentCount = CGColorGetNumberOfComponents(tintColor.CGColor);
665 | if (componentCount == 2) {
666 | CGFloat b;
667 | if ([tintColor getWhite:&b alpha:nil]) {
668 | effectColor = [UIColor colorWithWhite:b alpha:EffectColorAlpha];
669 | }
670 | } else {
671 | CGFloat r, g, b;
672 | if ([tintColor getRed:&r green:&g blue:&b alpha:nil]) {
673 | effectColor = [UIColor colorWithRed:r green:g blue:b alpha:EffectColorAlpha];
674 | }
675 | }
676 | return [self applyBlurWithRadius:10 tintColor:effectColor saturationDeltaFactor:-1.0 maskImage:nil];
677 | }
678 |
679 | - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius
680 | tintColor:(UIColor *)tintColor
681 | saturationDeltaFactor:(CGFloat)saturationDeltaFactor
682 | maskImage:(UIImage *)maskImage {
683 |
684 | if (self.size.width < 1 || self.size.height < 1) {
685 | NSLog (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self);
686 | return nil;
687 | }
688 | if (!self.CGImage) {
689 | NSLog (@"*** error: image must be backed by a CGImage: %@", self);
690 | return nil;
691 | }
692 | if (maskImage && !maskImage.CGImage) {
693 | NSLog (@"*** error: maskImage must be backed by a CGImage: %@", maskImage);
694 | return nil;
695 | }
696 |
697 | CGRect imageRect = { CGPointZero, self.size };
698 | UIImage *effectImage = self;
699 |
700 | BOOL hasBlur = blurRadius > __FLT_EPSILON__;
701 | BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__;
702 | if (hasBlur || hasSaturationChange) {
703 | UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
704 | CGContextRef effectInContext = UIGraphicsGetCurrentContext();
705 | CGContextScaleCTM(effectInContext, 1.0, -1.0);
706 | CGContextTranslateCTM(effectInContext, 0, -self.size.height);
707 | CGContextDrawImage(effectInContext, imageRect, self.CGImage);
708 |
709 | vImage_Buffer effectInBuffer;
710 | effectInBuffer.data = CGBitmapContextGetData(effectInContext);
711 | effectInBuffer.width = CGBitmapContextGetWidth(effectInContext);
712 | effectInBuffer.height = CGBitmapContextGetHeight(effectInContext);
713 | effectInBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectInContext);
714 |
715 | UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
716 | CGContextRef effectOutContext = UIGraphicsGetCurrentContext();
717 | vImage_Buffer effectOutBuffer;
718 | effectOutBuffer.data = CGBitmapContextGetData(effectOutContext);
719 | effectOutBuffer.width = CGBitmapContextGetWidth(effectOutContext);
720 | effectOutBuffer.height = CGBitmapContextGetHeight(effectOutContext);
721 | effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext);
722 |
723 | if (hasBlur) {
724 | // A description of how to compute the box kernel width from the Gaussian
725 | // radius (aka standard deviation) appears in the SVG spec:
726 | // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement
727 | //
728 | // For larger values of 's' (s >= 2.0), an approximation can be used: Three
729 | // successive box-blurs build a piece-wise quadratic convolution kernel, which
730 | // approximates the Gaussian kernel to within roughly 3%.
731 | //
732 | // let d = floor(s * 3*sqrt(2*pi)/4 + 0.5)
733 | //
734 | // ... if d is odd, use three box-blurs of size 'd', centered on the output pixel.
735 | //
736 | CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale];
737 | NSUInteger radius = floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5);
738 | if (radius % 2 != 1) {
739 | radius += 1; // force radius to be odd so that the three box-blur methodology works.
740 | }
741 | vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, (uint32_t)radius, (uint32_t)radius, 0, kvImageEdgeExtend);
742 | vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, (uint32_t)radius, (uint32_t)radius, 0, kvImageEdgeExtend);
743 | vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, (uint32_t)radius, (uint32_t)radius, 0, kvImageEdgeExtend);
744 | }
745 | BOOL effectImageBuffersAreSwapped = NO;
746 | if (hasSaturationChange) {
747 | CGFloat s = saturationDeltaFactor;
748 | CGFloat floatingPointSaturationMatrix[] = {
749 | 0.0722 + 0.9278 * s, 0.0722 - 0.0722 * s, 0.0722 - 0.0722 * s, 0,
750 | 0.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s, 0,
751 | 0.2126 - 0.2126 * s, 0.2126 - 0.2126 * s, 0.2126 + 0.7873 * s, 0,
752 | 0, 0, 0, 1,
753 | };
754 | const int32_t divisor = 256;
755 | NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]);
756 | int16_t saturationMatrix[matrixSize];
757 | for (NSUInteger i = 0; i < matrixSize; ++i) {
758 | saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor);
759 | }
760 | if (hasBlur) {
761 | vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);
762 | effectImageBuffersAreSwapped = YES;
763 | }
764 | else {
765 | vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags);
766 | }
767 | }
768 | if (!effectImageBuffersAreSwapped)
769 | effectImage = UIGraphicsGetImageFromCurrentImageContext();
770 | UIGraphicsEndImageContext();
771 |
772 | if (effectImageBuffersAreSwapped)
773 | effectImage = UIGraphicsGetImageFromCurrentImageContext();
774 | UIGraphicsEndImageContext();
775 | }
776 |
777 | // Set up output context.
778 | UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]);
779 | CGContextRef outputContext = UIGraphicsGetCurrentContext();
780 | CGContextScaleCTM(outputContext, 1.0, -1.0);
781 | CGContextTranslateCTM(outputContext, 0, -self.size.height);
782 |
783 | // Draw base image.
784 | CGContextDrawImage(outputContext, imageRect, self.CGImage);
785 |
786 | // Draw effect image.
787 | if (hasBlur) {
788 | CGContextSaveGState(outputContext);
789 | if (maskImage) {
790 | CGContextClipToMask(outputContext, imageRect, maskImage.CGImage);
791 | }
792 | CGContextDrawImage(outputContext, imageRect, effectImage.CGImage);
793 | CGContextRestoreGState(outputContext);
794 | }
795 |
796 | // Add in color tint.
797 | if (tintColor) {
798 | CGContextSaveGState(outputContext);
799 | CGContextSetFillColorWithColor(outputContext, tintColor.CGColor);
800 | CGContextFillRect(outputContext, imageRect);
801 | CGContextRestoreGState(outputContext);
802 | }
803 |
804 | // Output image is ready.
805 | UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
806 | UIGraphicsEndImageContext();
807 |
808 | return outputImage;
809 |
810 | }
811 |
812 | @end
813 |
814 |
815 |
816 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/UIMenuItem+Category.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIMenuItem+Category.h
3 | // PKWSevers
4 | //
5 | // Created by chenguangjiang on 16/7/2.
6 | // Copyright © 2016年 peikua. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIMenuItem (Category)
12 | - (instancetype)initWithTitle:(NSString *)title actionBlock:(void (^)(id sender))block;
13 | @end
14 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/UIMenuItem+Category.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIMenuItem+Category.m
3 | // PKWSevers
4 | //
5 | // Created by chenguangjiang on 16/7/2.
6 | // Copyright © 2016年 peikua. All rights reserved.
7 | //
8 |
9 | #import "UIMenuItem+Category.h"
10 | #import
11 | static int UIMenuItem_key;
12 |
13 | @implementation UIMenuItem (Category)
14 |
15 | - (instancetype)initWithTitle:(NSString *)title actionBlock:(void (^)(id sender))block{
16 | self = [self initWithTitle:title action:@selector(invoke:)];
17 | objc_setAssociatedObject(self, &UIMenuItem_key, block, OBJC_ASSOCIATION_COPY_NONATOMIC);
18 | return self;
19 | }
20 |
21 | - (void)invoke:(id)sender {
22 | void(^block)() = objc_getAssociatedObject(self, &UIMenuItem_key);
23 | if(block){
24 | block();
25 | }
26 |
27 | }
28 | @end
29 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/UITableView+CellAnimation.h:
--------------------------------------------------------------------------------
1 | //
2 | // UITableView+CellAnimation.h
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/9/11.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UITableView (CellAnimation)
12 |
13 | - (void)moveAnimation; //左侧飞入
14 | - (void)alphaAnimation; //透明
15 | - (void)fallAnimation; //上面掉落
16 | - (void)shakeAnimation; //抖动动画
17 | - (void)overTurnAnimation; //翻转动画
18 | - (void)toTopAnimation; //从下往上
19 | - (void)springListAnimation; //从上往下弹动动画
20 | - (void)shrinkToTopAnimation;//从下往上挤向顶部
21 | - (void)layDownAnimation; //从上往下展开
22 | - (void)roteAnimation; //翻转动画
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/UITableView+CellAnimation.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIself+CellAnimation.m
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/9/11.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import "UITableView+CellAnimation.h"
10 |
11 | #define XS_SCREEN_WIDTH [[UIScreen mainScreen] bounds].size.width
12 | #define XS_SCREEN_HEIGHT [[UIScreen mainScreen] bounds].size.height
13 |
14 | @implementation UITableView (CellAnimation)
15 |
16 | - (void)moveAnimation
17 | {
18 | NSArray *cells = self.visibleCells;
19 | for (int i = 0; i < cells.count; i++) {
20 | CGFloat totalTime = 0.4;
21 | UITableViewCell *cell = [self.visibleCells objectAtIndex:i];
22 | cell.transform = CGAffineTransformMakeTranslation(-XS_SCREEN_WIDTH, 0);
23 | [UIView animateWithDuration:0.4 delay:i*(totalTime/cells.count) usingSpringWithDamping:0.7 initialSpringVelocity:1/0.7 options:UIViewAnimationOptionCurveEaseIn animations:^{
24 | cell.transform = CGAffineTransformIdentity;
25 | } completion:^(BOOL finished) {
26 |
27 | }];
28 | }
29 | }
30 |
31 | - (void)alphaAnimation
32 | {
33 | NSArray *cells = self.visibleCells;
34 | for (int i = 0; i < cells.count; i++) {
35 | UITableViewCell *cell = [self.visibleCells objectAtIndex:i];
36 | cell.alpha = 0.0;
37 | [UIView animateWithDuration:0.3 delay:i*0.05 options:0 animations:^{
38 | cell.alpha = 1.0;
39 | } completion:^(BOOL finished) {
40 |
41 | }];
42 | }
43 | }
44 |
45 | - (void)fallAnimation
46 | {
47 | NSArray *cells = self.visibleCells;
48 |
49 | NSTimeInterval totalTime = 0.8;
50 |
51 | for (int i = 0; i < cells.count; i++) {
52 | UITableViewCell *cell = [self.visibleCells objectAtIndex:i];
53 | cell.transform = CGAffineTransformMakeTranslation(0, - XS_SCREEN_HEIGHT);
54 | [UIView animateWithDuration:0.3 delay:(cells.count - i)*(totalTime/cells.count) options:0 animations:^{
55 | cell.transform = CGAffineTransformIdentity;
56 | } completion:^(BOOL finished) {
57 |
58 | }];
59 | }
60 | }
61 |
62 | - (void)shakeAnimation
63 | {
64 | NSArray *cells = self.visibleCells;
65 | for (int i = 0; i < cells.count; i++) {
66 | UITableViewCell *cell = [cells objectAtIndex:i];
67 | if (i%2 == 0) {
68 | cell.transform = CGAffineTransformMakeTranslation(-XS_SCREEN_WIDTH,0);
69 | }else {
70 | cell.transform = CGAffineTransformMakeTranslation(XS_SCREEN_WIDTH,0);
71 | }
72 | [UIView animateWithDuration:0.4 delay:i*0.03 usingSpringWithDamping:0.75 initialSpringVelocity:1/0.75 options:0 animations:^{
73 | cell.transform = CGAffineTransformIdentity;
74 | } completion:^(BOOL finished) {
75 |
76 | }];
77 | }
78 | }
79 |
80 | - (void)overTurnAnimation
81 | {
82 | NSArray *cells = self.visibleCells;
83 | for (int i = 0; i < cells.count; i++) {
84 | UITableViewCell *cell = [cells objectAtIndex:i];
85 | cell.layer.opacity = 0.0;
86 | cell.layer.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0);
87 | NSTimeInterval totalTime = 0.7;
88 | [UIView animateWithDuration:0.3 delay:i*(totalTime/cells.count) options:0 animations:^{
89 | cell.layer.opacity = 1.0;
90 | cell.layer.transform = CATransform3DIdentity;
91 | } completion:^(BOOL finished) {
92 |
93 | }];
94 |
95 | }
96 | }
97 |
98 | - (void)toTopAnimation
99 | {
100 | NSArray *cells = self.visibleCells;
101 |
102 | NSTimeInterval totalTime = 0.8;
103 |
104 | for (int i = 0; i < cells.count; i++) {
105 | UITableViewCell *cell = [self.visibleCells objectAtIndex:i];
106 | cell.transform = CGAffineTransformMakeTranslation(0, XS_SCREEN_HEIGHT);
107 | [UIView animateWithDuration:0.35 delay:i*(totalTime/cells.count) options:UIViewAnimationOptionCurveEaseOut animations:^{
108 | cell.transform = CGAffineTransformIdentity;
109 | } completion:^(BOOL finished) {
110 |
111 | }];
112 | }
113 | }
114 |
115 | - (void)springListAnimation
116 | {
117 | NSArray *cells = self.visibleCells;
118 | for (int i = 0; i < cells.count; i++) {
119 | UITableViewCell *cell = [cells objectAtIndex:i];
120 | cell.layer.opacity = 0.7;
121 | cell.layer.transform = CATransform3DMakeTranslation(0, -XS_SCREEN_HEIGHT, 20);
122 | NSTimeInterval totalTime = 1.0;
123 |
124 | [UIView animateWithDuration:0.4 delay:i*(totalTime/cells.count) usingSpringWithDamping:0.65 initialSpringVelocity:1/0.65 options:UIViewAnimationOptionCurveEaseIn animations:^{
125 | cell.layer.opacity = 1.0;
126 | cell.layer.transform = CATransform3DMakeTranslation(0, 0, 20);
127 | } completion:^(BOOL finished) {
128 |
129 | }];
130 | }
131 | }
132 |
133 | - (void)shrinkToTopAnimation
134 | {
135 | NSArray *cells = self.visibleCells;
136 | for (int i = 0; i < cells.count; i++) {
137 | UITableViewCell *cell = [cells objectAtIndex:i];
138 | CGRect rect = [cell convertRect:cell.bounds fromView:self];
139 | cell.transform = CGAffineTransformMakeTranslation(0, -rect.origin.y);
140 | [UIView animateWithDuration:0.5 animations:^{
141 | cell.transform = CGAffineTransformIdentity;
142 | }];
143 | }
144 | }
145 |
146 | - (void)layDownAnimation
147 | {
148 | NSArray *cells = self.visibleCells;
149 | NSMutableArray *rectArr = [[NSMutableArray alloc] init];
150 | for (int i = 0; i < cells.count; i++) {
151 | UITableViewCell *cell = [cells objectAtIndex:i];
152 | CGRect rect = cell.frame;
153 | [rectArr addObject:[NSValue valueWithCGRect:rect]];
154 | rect.origin.y = i * 10;
155 | cell.frame = rect;
156 | cell.layer.transform = CATransform3DMakeTranslation(0, 0, i*5);
157 | }
158 | NSTimeInterval totalTime = 0.8;
159 | for (int i = 0; i < cells.count; i++) {
160 | UITableViewCell *cell = [cells objectAtIndex:i];
161 | CGRect rect = [[rectArr objectAtIndex:i] CGRectValue];
162 | [UIView animateWithDuration:(totalTime/cells.count) * i animations:^{
163 | cell.frame = rect;
164 | } completion:^(BOOL finished) {
165 | cell.layer.transform = CATransform3DIdentity;
166 | }];
167 | }
168 |
169 | }
170 |
171 | - (void)roteAnimation
172 | {
173 | NSArray *cells = self.visibleCells;
174 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
175 | animation.fromValue = @(-M_PI);
176 | animation.toValue = 0;
177 | animation.duration = 0.3;
178 | animation.removedOnCompletion = NO;
179 | animation.repeatCount = 3;
180 | animation.fillMode = kCAFillModeForwards;
181 | animation.autoreverses = NO;
182 |
183 | for (int i = 0; i < cells.count; i++) {
184 | UITableViewCell *cell = [cells objectAtIndex:i];
185 |
186 | cell.alpha = 0.0;
187 | [UIView animateWithDuration:0.1 delay:i*0.25 options:0 animations:^{
188 | cell.alpha = 1.0;
189 | } completion:^(BOOL finished) {
190 | [cell.layer addAnimation:animation forKey:@"rotationYkey"];
191 | }];
192 | }
193 | }
194 |
195 | @end
196 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/UIView+Category.h:
--------------------------------------------------------------------------------
1 | //
2 | // PK-ios
3 | //
4 | // Created by peikua on 15/9/15.
5 | // Copyright (c) 2015年 peikua. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | @interface UIView (Category)
11 | //把View加在Window上
12 | - (void) addToWindow;
13 |
14 | @end
15 |
16 | @interface UIView (Screenshot)
17 |
18 | //View截图
19 | - (UIImage*) screenshot;
20 |
21 | //ScrollView截图 contentOffset
22 | - (UIImage*) screenshotForScrollViewWithContentOffset:(CGPoint)contentOffset;
23 |
24 | //View按Rect截图
25 | - (UIImage*) screenshotInFrame:(CGRect)frame;
26 |
27 | //整个view转成图片
28 | - (UIImage*) convertToImage;
29 | @end
30 |
31 | @interface UIView (Animation)
32 |
33 | //左右抖动动画
34 | - (void) shakeAnimation;
35 |
36 | //旋转180度
37 | - (void) trans180DegreeAnimation;
38 |
39 | @end
40 |
41 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/UIView+Category.m:
--------------------------------------------------------------------------------
1 | //
2 | // PK-ios
3 | //
4 | // Created by peikua on 15/9/15.
5 | // Copyright (c) 2015年 peikua. All rights reserved.
6 | //
7 |
8 | #import "UIView+Category.h"
9 | #import
10 | #import
11 |
12 | @implementation UIView (Category)
13 |
14 | -(void) addToWindow
15 | {
16 | id appDelegate = [[UIApplication sharedApplication] delegate];
17 | if ([appDelegate respondsToSelector:@selector(window)])
18 | {
19 | UIWindow * window = (UIWindow *) [appDelegate performSelector:@selector(window)];
20 | [window addSubview:self];
21 | }
22 | }
23 |
24 |
25 | @end
26 |
27 |
28 | @implementation UIView (Screenshot)
29 |
30 | - (UIImage*) screenshot {
31 |
32 | UIGraphicsBeginImageContext(self.bounds.size);
33 | [self.layer renderInContext:UIGraphicsGetCurrentContext()];
34 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
35 | UIGraphicsEndImageContext();
36 |
37 | // helps w/ our colors when blurring
38 | // feel free to adjust jpeg quality (lower = higher perf)
39 | NSData *imageData = UIImageJPEGRepresentation(image, 0.75);
40 | image = [UIImage imageWithData:imageData];
41 |
42 | return image;
43 |
44 | }
45 |
46 | - (UIImage *) screenshotForScrollViewWithContentOffset:(CGPoint)contentOffset {
47 | UIGraphicsBeginImageContext(self.bounds.size);
48 | //need to translate the context down to the current visible portion of the scrollview
49 | CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0.0f, -contentOffset.y);
50 | [self.layer renderInContext:UIGraphicsGetCurrentContext()];
51 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
52 | UIGraphicsEndImageContext();
53 |
54 | // helps w/ our colors when blurring
55 | // feel free to adjust jpeg quality (lower = higher perf)
56 | NSData *imageData = UIImageJPEGRepresentation(image, 0.55);
57 | image = [UIImage imageWithData:imageData];
58 |
59 | return image;
60 | }
61 |
62 | - (UIImage*) screenshotInFrame:(CGRect)frame {
63 | UIGraphicsBeginImageContext(frame.size);
64 | CGContextTranslateCTM(UIGraphicsGetCurrentContext(), frame.origin.x, frame.origin.y);
65 | [self.layer renderInContext:UIGraphicsGetCurrentContext()];
66 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
67 | UIGraphicsEndImageContext();
68 |
69 | // helps w/ our colors when blurring
70 | // feel free to adjust jpeg quality (lower = higher perf)
71 | NSData *imageData = UIImageJPEGRepresentation(image, 0.75);
72 | image = [UIImage imageWithData:imageData];
73 |
74 | return image;
75 | }
76 |
77 | -(UIImage *) convertToImage {
78 | CGSize viewSize = self.bounds.size;
79 | UIGraphicsBeginImageContextWithOptions(viewSize, NO, [UIScreen mainScreen].scale);
80 | [self.layer renderInContext:UIGraphicsGetCurrentContext()];
81 | UIImage*image = UIGraphicsGetImageFromCurrentImageContext();
82 | UIGraphicsEndImageContext();
83 | return image;
84 | }
85 |
86 | @end
87 |
88 | @implementation UIView (Animation)
89 |
90 | - (void) shakeAnimation {
91 |
92 | CALayer* layer = [self layer];
93 | CGPoint position = [layer position];
94 | CGPoint y = CGPointMake(position.x - 8.0f, position.y);
95 | CGPoint x = CGPointMake(position.x + 8.0f, position.y);
96 | CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"position"];
97 | [animation setTimingFunction:[CAMediaTimingFunction
98 | functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
99 | [animation setFromValue:[NSValue valueWithCGPoint:x]];
100 | [animation setToValue:[NSValue valueWithCGPoint:y]];
101 | [animation setAutoreverses:YES];
102 | [animation setDuration:0.08f];
103 | [animation setRepeatCount:3];
104 | [layer addAnimation:animation forKey:nil];
105 | }
106 |
107 | - (void) trans180DegreeAnimation
108 | {
109 | [UIView animateWithDuration:0.3 animations:^{
110 | self.layer.transform = CATransform3DMakeRotation(M_PI, 0, 1, 0);
111 | }];
112 | }
113 | @end
114 |
115 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/UIView+Frame.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Frame.h
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/8/23.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIView (Frame)
12 | //不用再蛋疼的写某view.frame=CGRectMake(x,y,z,o)了。
13 | - (CGFloat)left;
14 | - (CGFloat)right;
15 | - (CGSize)size;
16 | - (CGFloat)top;
17 | - (CGFloat)bottom;
18 | - (CGFloat)width;
19 | - (CGFloat)height;
20 | - (CGFloat)centerX;
21 | - (CGFloat)centerY;
22 | - (CGFloat)maxX;
23 | - (CGFloat)maxY;
24 |
25 | - (void)setLeft:(CGFloat)left;
26 | - (void)setRight:(CGFloat)right;
27 | - (void)setSize:(CGSize)size;
28 | - (void)setTop:(CGFloat)top;
29 | - (void)setBottom:(CGFloat)bottom;
30 | - (void)setWidth:(CGFloat)width;
31 | - (void)setHeight:(CGFloat)height;
32 | - (void)setCenterX:(CGFloat)centerX;
33 | - (void)setCenterY:(CGFloat)centerY;
34 | - (void)setOrigin:(CGPoint)point;
35 | - (void)setAddTop:(CGFloat)top;
36 | - (void)setAddLeft:(CGFloat)left;
37 | @end
38 |
--------------------------------------------------------------------------------
/iOS-Category/iOS-Category/UIView+Frame.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Frame.m
3 | // iOS-Category
4 | //
5 | // Created by 庄BB的MacBook on 2017/8/23.
6 | // Copyright © 2017年 BBFC. All rights reserved.
7 | //
8 |
9 | #import "UIView+Frame.h"
10 |
11 | @implementation UIView (Frame)
12 | - (CGFloat)left
13 | {
14 | return self.frame.origin.x;
15 | }
16 |
17 | - (CGFloat)right
18 | {
19 | return self.frame.origin.x + self.frame.size.width;
20 | }
21 |
22 | - (CGFloat)top
23 | {
24 | return self.frame.origin.y;
25 | }
26 |
27 | - (CGFloat)bottom
28 | {
29 | return self.frame.origin.y + self.frame.size.height;
30 | }
31 |
32 | - (CGSize)size{
33 | return self.frame.size;
34 | }
35 |
36 | - (CGFloat)width
37 | {
38 | return self.frame.size.width;
39 | }
40 |
41 | - (CGFloat)height
42 | {
43 | return self.frame.size.height;
44 | }
45 |
46 | - (CGFloat)centerX
47 | {
48 | return self.center.x;
49 | }
50 |
51 | - (CGFloat)centerY
52 | {
53 | return self.center.y;
54 | }
55 |
56 | - (CGFloat)maxX
57 | {
58 | return CGRectGetMaxX(self.frame);
59 | }
60 |
61 | - (CGFloat)maxY
62 | {
63 | return CGRectGetMaxY(self.frame);
64 | }
65 |
66 | - (void)setLeft:(CGFloat)left
67 | {
68 | CGRect frame = self.frame;
69 | frame.origin.x = left;
70 | self.frame = frame;
71 | }
72 |
73 | - (void)setRight:(CGFloat)right;
74 | {
75 | CGRect frame = self.frame;
76 | frame.origin.x = right - frame.size.width;
77 | self.frame = frame;
78 | }
79 |
80 | - (void)setBottom:(CGFloat)bottom
81 | {
82 | CGRect frame = self.frame;
83 | frame.origin.y = bottom - frame.size.height;
84 | self.frame = frame;
85 | }
86 |
87 | - (void)setSize:(CGSize)size
88 | {
89 | CGRect frame = self.frame;
90 | frame.size = size;
91 | self.frame = frame;
92 | }
93 |
94 | - (void)setTop:(CGFloat)top
95 | {
96 | CGRect frame = self.frame;
97 | frame.origin.y = top;
98 | self.frame = frame;
99 | }
100 |
101 | - (void)setWidth:(CGFloat)width
102 | {
103 | CGRect frame = self.frame;
104 | frame.size.width = width;
105 | self.frame = frame;
106 | }
107 |
108 | - (void)setHeight:(CGFloat)height
109 | {
110 | CGRect frame = self.frame;
111 | frame.size.height = height;
112 | self.frame = frame;
113 | }
114 |
115 | - (void)setOrigin:(CGPoint)point
116 | {
117 | CGRect frame = self.frame;
118 | frame.origin = point;
119 | self.frame = frame;
120 | }
121 |
122 | - (void)setCenterX:(CGFloat)centerX
123 | {
124 | self.center = CGPointMake(centerX, self.center.y);
125 | }
126 |
127 | - (void)setCenterY:(CGFloat)centerY
128 | {
129 | self.center = CGPointMake(self.center.x, centerY);
130 | }
131 |
132 | - (void)setAddTop:(CGFloat)top
133 | {
134 | CGRect frame = self.frame;
135 | frame.origin.y += top;
136 | self.frame = frame;
137 | }
138 |
139 | - (void)setAddLeft:(CGFloat)left
140 | {
141 | CGRect frame = self.frame;
142 | frame.origin.x += left;
143 | self.frame = frame;
144 | }
145 |
146 | @end
147 |
--------------------------------------------------------------------------------