TUIDarkModel.m 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. //
  2. // TUIDarkModel.m
  3. // TUICore
  4. //
  5. // Created by xiangzhang on 2021/9/9.
  6. // Copyright © 2023 Tencent. All rights reserved.
  7. //
  8. #import "TUIDarkModel.h"
  9. #import <objc/message.h>
  10. #import "TUIDefine.h"
  11. @implementation UIColor (TUIDarkModel)
  12. + (UIColor *)d_colorWithColorLight:(UIColor *)light dark:(UIColor *)dark {
  13. if (@available(iOS 13.0, *)) {
  14. return [self colorWithDynamicProvider:^UIColor *_Nonnull(UITraitCollection *_Nonnull traitCollection) {
  15. switch (traitCollection.userInterfaceStyle) {
  16. case UIUserInterfaceStyleDark:
  17. return dark;
  18. case UIUserInterfaceStyleLight:
  19. case UIUserInterfaceStyleUnspecified:
  20. default:
  21. return light;
  22. }
  23. }];
  24. } else {
  25. return light;
  26. }
  27. }
  28. + (UIColor *)d_systemBlackColor {
  29. if (@available(iOS 13.0, *)) {
  30. return [self systemBackgroundColor];
  31. } else {
  32. return [UIColor whiteColor];
  33. }
  34. }
  35. + (UIColor *)d_systemGrayColor {
  36. if (@available(iOS 13.0, *)) {
  37. return [self systemGrayColor];
  38. } else {
  39. return [UIColor grayColor];
  40. }
  41. }
  42. + (UIColor *)d_systemRedColor {
  43. if (@available(iOS 13.0, *)) {
  44. return [self systemRedColor];
  45. } else {
  46. return [UIColor redColor];
  47. }
  48. }
  49. + (UIColor *)d_systemBlueColor {
  50. if (@available(iOS 13.0, *)) {
  51. return [self systemBlueColor];
  52. } else {
  53. return [UIColor blueColor];
  54. }
  55. }
  56. @end
  57. @implementation UIImage (TUIDarkModel)
  58. + (UIImage *)d_imagePath:(NSString *)path {
  59. UIImage *image = [UIImage d_imageWithImageLight:path dark:[NSString stringWithFormat:@"%@_dark", path]];
  60. return image;
  61. }
  62. + (UIImage *)d_imageNamed:(NSString *)imageName bundle:(NSString *)bundleName;
  63. {
  64. NSString *path = nil;
  65. if ([bundleName isEqualToString:TUIDemoBundle]) {
  66. path = TUIDemoImagePath(imageName);
  67. } else if ([bundleName isEqualToString:TUICoreBundle]) {
  68. path = TUICoreImagePath(imageName);
  69. } else if ([bundleName isEqualToString:TUIChatBundle]) {
  70. path = TUIChatImagePath(imageName);
  71. } else if ([bundleName isEqualToString:TUIChatFaceBundle]) {
  72. path = TUIChatFaceImagePath(imageName);
  73. } else if ([bundleName isEqualToString:TUIConversationBundle]) {
  74. path = TUIConversationImagePath(imageName);
  75. } else if ([bundleName isEqualToString:TUIContactBundle]) {
  76. path = TUIContactImagePath(imageName);
  77. } else if ([bundleName isEqualToString:TUISearchBundle]) {
  78. path = TUISearchImagePath(imageName);
  79. }
  80. if (path) {
  81. return [UIImage d_imageWithImageLight:path dark:[NSString stringWithFormat:@"%@_dark", path]];
  82. }
  83. return nil;
  84. }
  85. + (void)d_fixResizableImage {
  86. if (@available(iOS 13.0, *)) {
  87. Class klass = UIImage.class;
  88. SEL selector = @selector(resizableImageWithCapInsets:resizingMode:);
  89. Method method = class_getInstanceMethod(klass, selector);
  90. if (method == NULL) {
  91. return;
  92. }
  93. IMP originalImp = class_getMethodImplementation(klass, selector);
  94. if (!originalImp) {
  95. return;
  96. }
  97. IMP dynamicColorCompatibleImp = imp_implementationWithBlock(^UIImage *(UIImage *_self, UIEdgeInsets insets, UIImageResizingMode resizingMode) {
  98. UITraitCollection *lightTrait = [self lightTrait];
  99. UITraitCollection *darkTrait = [self darkTrait];
  100. UIImage *resizable = ((UIImage * (*)(UIImage *, SEL, UIEdgeInsets, UIImageResizingMode)) originalImp)(_self, selector, insets, resizingMode);
  101. UIImage *resizableInLight = [_self.imageAsset imageWithTraitCollection:lightTrait];
  102. UIImage *resizableInDark = [_self.imageAsset imageWithTraitCollection:darkTrait];
  103. if (resizableInLight) {
  104. [resizable.imageAsset registerImage:((UIImage * (*)(UIImage *, SEL, UIEdgeInsets, UIImageResizingMode)) originalImp)(resizableInLight, selector,
  105. insets, resizingMode)
  106. withTraitCollection:lightTrait];
  107. }
  108. if (resizableInDark) {
  109. [resizable.imageAsset registerImage:((UIImage * (*)(UIImage *, SEL, UIEdgeInsets, UIImageResizingMode)) originalImp)(resizableInDark, selector,
  110. insets, resizingMode)
  111. withTraitCollection:darkTrait];
  112. }
  113. return resizable;
  114. });
  115. class_replaceMethod(klass, selector, dynamicColorCompatibleImp, method_getTypeEncoding(method));
  116. }
  117. }
  118. + (UITraitCollection *)lightTrait API_AVAILABLE(ios(13.0)) {
  119. static UITraitCollection *trait = nil;
  120. static dispatch_once_t onceToken;
  121. dispatch_once(&onceToken, ^{
  122. trait = [UITraitCollection traitCollectionWithTraitsFromCollections:@[
  123. [UITraitCollection traitCollectionWithDisplayScale:UIScreen.mainScreen.scale],
  124. [UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]
  125. ]];
  126. });
  127. return trait;
  128. }
  129. + (UITraitCollection *)darkTrait API_AVAILABLE(ios(13.0)) {
  130. static UITraitCollection *trait = nil;
  131. static dispatch_once_t onceToken;
  132. dispatch_once(&onceToken, ^{
  133. trait = [UITraitCollection traitCollectionWithTraitsFromCollections:@[
  134. [UITraitCollection traitCollectionWithDisplayScale:UIScreen.mainScreen.scale],
  135. [UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]
  136. ]];
  137. });
  138. return trait;
  139. }
  140. + (UIImage *)d_imageWithImageLight:(NSString *)lightImagePath dark:(NSString *)darkImagePath {
  141. UIImage *lightImage = [UIImage imageNamed:lightImagePath];
  142. if (!lightImage) {
  143. return nil;
  144. }
  145. if (@available(iOS 13.0, *)) {
  146. UIImage *darkImage = [UIImage imageNamed:darkImagePath];
  147. UITraitCollection *const scaleTraitCollection = [UITraitCollection currentTraitCollection];
  148. UITraitCollection *const darkUnscaledTraitCollection = [UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark];
  149. UITraitCollection *const darkScaledTraitCollection =
  150. [UITraitCollection traitCollectionWithTraitsFromCollections:@[ scaleTraitCollection, darkUnscaledTraitCollection ]];
  151. UIImage *image = [lightImage
  152. imageWithConfiguration:[lightImage.configuration
  153. configurationWithTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]]];
  154. darkImage = [darkImage
  155. imageWithConfiguration:[darkImage.configuration
  156. configurationWithTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]]];
  157. [image.imageAsset registerImage:darkImage withTraitCollection:darkScaledTraitCollection];
  158. return image;
  159. } else {
  160. return lightImage;
  161. }
  162. return nil;
  163. }
  164. + (UIImage *)d_imageWithImageLightImg:(UIImage *)lightImage dark:(UIImage *)darkImage {
  165. if (!lightImage) {
  166. return nil;
  167. }
  168. if (@available(iOS 13.0, *)) {
  169. UITraitCollection *const scaleTraitCollection = [UITraitCollection currentTraitCollection];
  170. UITraitCollection *const darkUnscaledTraitCollection = [UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark];
  171. UITraitCollection *const darkScaledTraitCollection =
  172. [UITraitCollection traitCollectionWithTraitsFromCollections:@[ scaleTraitCollection, darkUnscaledTraitCollection ]];
  173. UIImage *image = [lightImage
  174. imageWithConfiguration:[lightImage.configuration
  175. configurationWithTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleLight]]];
  176. darkImage = [darkImage
  177. imageWithConfiguration:[darkImage.configuration
  178. configurationWithTraitCollection:[UITraitCollection traitCollectionWithUserInterfaceStyle:UIUserInterfaceStyleDark]]];
  179. [image.imageAsset registerImage:darkImage withTraitCollection:darkScaledTraitCollection];
  180. return image;
  181. } else {
  182. return lightImage;
  183. }
  184. return nil;
  185. }
  186. @end