TYHWaterMark.m 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. //
  2. // TYHWaterMark.m
  3. //
  4. // Created by yuhua Tang on 2022/8/5.
  5. //
  6. #import "TYHWaterMark.h"
  7. @import ObjectiveC;
  8. @import PhotosUI;
  9. BOOL isPresentAbleSystemVC(UIViewController *vc) {
  10. static NSArray *list = nil;
  11. static dispatch_once_t onceToken;
  12. dispatch_once(&onceToken, ^{
  13. NSMutableArray *array = @[].mutableCopy;
  14. [array addObject:[UIImagePickerController class]];
  15. [array addObject:[UIDocumentPickerViewController class]];
  16. [array addObject:[UIDocumentMenuViewController class]];
  17. if (@available(iOS 13.0, *)) {
  18. [array addObject:[UIFontPickerViewController class]];
  19. }
  20. if (@available(iOS 14.0, *)) {
  21. [array addObject:[UIColorPickerViewController class]];
  22. [array addObject:[PHPickerViewController class]];
  23. }
  24. list = [array copy];
  25. });
  26. for(Class aClass in list) {
  27. if([vc isKindOfClass:aClass]) {
  28. return YES;
  29. }
  30. }
  31. return NO;
  32. }
  33. static NSString *g_characteristicStr = @"";
  34. static NSString *g_formatStr = @"MM-dd HH:mm";
  35. static UIFont *g_font= nil;
  36. static UIColor *g_color = nil;
  37. static TYHWaterMarkView *g_waterMarkView = nil;
  38. @interface UIViewController(TYHWaterMarkView)
  39. @end
  40. @implementation UIViewController(TYHWaterMarkView)
  41. + (void)load {
  42. [UIViewController tyhwatermark_swizzleInstanceMethod:@selector(presentViewController:animated:completion:) with:@selector(tyhwatermark_presentViewController:animated:completion:)];
  43. [UIViewController tyhwatermark_swizzleInstanceMethod:@selector(dismissViewControllerAnimated:completion:) with:@selector(tyhwatermark_dismissViewControllerAnimated:completion:)];
  44. }
  45. + (BOOL)tyhwatermark_swizzleInstanceMethod:(SEL)originalSel with:(SEL)newSel {
  46. Method originalMethod = class_getInstanceMethod(self, originalSel);
  47. Method newMethod = class_getInstanceMethod(self, newSel);
  48. if (!originalMethod || !newMethod) return NO;
  49. class_addMethod(self,
  50. originalSel,
  51. class_getMethodImplementation(self, originalSel),
  52. method_getTypeEncoding(originalMethod));
  53. class_addMethod(self,
  54. newSel,
  55. class_getMethodImplementation(self, newSel),
  56. method_getTypeEncoding(newMethod));
  57. method_exchangeImplementations(class_getInstanceMethod(self, originalSel),
  58. class_getInstanceMethod(self, newSel));
  59. return YES;
  60. }
  61. - (void)tyhwatermark_presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^ __nullable)(void))completion {
  62. NSString *vcClassName = NSStringFromClass([viewControllerToPresent class]);
  63. if(isPresentAbleSystemVC(viewControllerToPresent) ||
  64. (([vcClassName hasPrefix:@"UI"]
  65. && ![viewControllerToPresent isKindOfClass:[UIAlertController class]]
  66. && ![viewControllerToPresent isMemberOfClass:[UIViewController class]])))
  67. {
  68. if (g_waterMarkView)
  69. {
  70. g_waterMarkView.hidden = YES;
  71. }
  72. }
  73. [self tyhwatermark_presentViewController:viewControllerToPresent animated:flag completion:completion];
  74. }
  75. - (void)tyhwatermark_dismissViewControllerAnimated: (BOOL)flag completion: (void (^ __nullable)(void))completion {
  76. if (g_waterMarkView)
  77. {
  78. g_waterMarkView.hidden = NO;
  79. }
  80. [self tyhwatermark_dismissViewControllerAnimated:flag completion:completion];
  81. }
  82. @end
  83. @interface TYHWaterMarkView ()
  84. @property (nonatomic, strong) UITextView *textView;
  85. @property (nonatomic, strong) NSDictionary *textAttributes;
  86. @property (nonatomic, strong) NSTimer *timer;
  87. @end
  88. @implementation TYHWaterMarkView
  89. + (void)setCharacter:(NSString *)str
  90. {
  91. if (g_waterMarkView)
  92. {
  93. [g_waterMarkView setCharacteristic:str];
  94. }
  95. else
  96. {
  97. g_characteristicStr = str;
  98. }
  99. }
  100. + (void)setTimeFormat:(NSString *)format
  101. {
  102. if (g_waterMarkView)
  103. {
  104. [g_waterMarkView setTimeFormat:format];
  105. }
  106. else
  107. {
  108. g_formatStr = format;
  109. }
  110. }
  111. + (void)setFont:(UIFont *)font {
  112. g_font = font;
  113. g_waterMarkView.textAttributes = nil;
  114. [g_waterMarkView updateContent];
  115. }
  116. + (void)setColor:(UIColor *)color {
  117. g_color = color;
  118. g_waterMarkView.textAttributes = nil;
  119. [g_waterMarkView updateContent];
  120. }
  121. + (void)updateDate
  122. {
  123. if (g_waterMarkView)
  124. {
  125. [g_waterMarkView updateContent];
  126. }
  127. else
  128. {
  129. }
  130. }
  131. - (instancetype)init
  132. {
  133. self = [super init];
  134. if (self)
  135. {
  136. [self commonInit];
  137. }
  138. return self;
  139. }
  140. - (void)commonInit
  141. {
  142. float width = [UIScreen mainScreen].bounds.size.width;
  143. float height = [UIScreen mainScreen].bounds.size.height;
  144. self.backgroundColor = [UIColor clearColor];
  145. self.frame = CGRectMake(-0.5 * width, -0.5 * height, 2 * width, 2 * height);
  146. self.layer.zPosition = 999;
  147. [self addSubview:self.textView];
  148. self.textView.frame = CGRectMake(0, 0, 2 * width, 2 * height);
  149. self.textView.attributedText = [[NSAttributedString alloc] initWithString:[self markContent] attributes:self.textAttributes];
  150. self.transform = CGAffineTransformMakeRotation(-15 * M_PI / 180);
  151. g_waterMarkView = self;
  152. }
  153. - (NSString *)markContent
  154. {
  155. NSString *dateString = [self stringWithFormat:g_formatStr];
  156. NSString *mark = [NSString stringWithFormat:@"%@ %@", g_characteristicStr, dateString];
  157. NSMutableString *all = @"".mutableCopy;
  158. for (int i = 0; i < 100; i++)
  159. {
  160. [all appendString:mark];
  161. [all appendString:@" "];
  162. }
  163. return all;
  164. }
  165. - (void)setCharacteristic:(NSString *)str
  166. {
  167. g_characteristicStr = str;
  168. [self updateContent];
  169. }
  170. - (void)setTimeFormat:(NSString *)format
  171. {
  172. g_formatStr = format;
  173. [self updateContent];
  174. }
  175. - (void)updateContent
  176. {
  177. self.textView.attributedText = [[NSAttributedString alloc] initWithString:[self markContent] attributes:self.textAttributes];
  178. }
  179. - (NSDictionary *)textAttributes {
  180. if (!_textAttributes) {
  181. NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
  182. paragraphStyle.lineSpacing = 75; // 字体的行间距
  183. UIFont *font = g_font ?:[UIFont systemFontOfSize:18];
  184. UIColor *color = g_color ?:[UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:0.14];
  185. _textAttributes = @{
  186. NSFontAttributeName : font,
  187. NSParagraphStyleAttributeName : paragraphStyle,
  188. NSForegroundColorAttributeName : color
  189. };
  190. }
  191. return _textAttributes;
  192. }
  193. - (NSString *)stringWithFormat:(NSString *)format
  194. {
  195. static NSDateFormatter *formatter = nil;
  196. static dispatch_once_t onceToken;
  197. dispatch_once(&onceToken, ^{
  198. formatter = [[NSDateFormatter alloc] init];
  199. [formatter setLocale:[NSLocale currentLocale]];
  200. });
  201. [formatter setDateFormat:format];
  202. return [formatter stringFromDate:[NSDate date]];
  203. }
  204. - (UITextView *)textView
  205. {
  206. if (!_textView)
  207. {
  208. UITextView *textView = [UITextView new];
  209. textView.backgroundColor = [UIColor clearColor];
  210. textView.editable = NO;
  211. textView.selectable = NO;
  212. textView.userInteractionEnabled = NO;
  213. _textView = textView;
  214. }
  215. return _textView;
  216. }
  217. + (void)autoUpdateDate:(BOOL)enable {
  218. if(enable) {
  219. g_waterMarkView.timer = [NSTimer scheduledTimerWithTimeInterval:10 repeats:true block:^(NSTimer * _Nonnull timer) {
  220. [TYHWaterMarkView updateDate];
  221. }];
  222. } else {
  223. [g_waterMarkView.timer invalidate];
  224. g_waterMarkView.timer = nil;
  225. }
  226. }
  227. @end