ABUNativeAdView+CustomRender.m 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. //
  2. // ABUNativeAdView+Custom_Render.m
  3. // ABUDemo
  4. //
  5. // Created by bytedance on 2022/2/11.
  6. // Copyright © 2022 bytedance. All rights reserved.
  7. //
  8. #import "ABUNativeAdView+CustomRender.h"
  9. static UIEdgeInsets const gromore_demo_native_padding = { 10, 15, 10, 15 };
  10. static CGFloat const gromore_demo_padding = 5;
  11. @implementation ABUNativeAdView (CustomRender)
  12. - (void)customRender {
  13. if (self.isExpressAd) return;
  14. self.backgroundColor = [UIColor whiteColor];
  15. [self _commonRender];
  16. CGFloat limitWidth = self.frame.size.width - CGRectGetMaxX(self.iconImageView.frame) - gromore_demo_padding - gromore_demo_native_padding.right;
  17. CGRect limitFrame = CGRectMake(self.titleLabel.frame.origin.x, CGRectGetMaxY(self.descLabel.frame) + gromore_demo_padding, limitWidth, self.frame.size.height - CGRectGetMaxY(self.descLabel.frame) - 2 * gromore_demo_padding - self.callToActionBtn.frame.size.height - gromore_demo_native_padding.bottom);
  18. switch (self.data.imageMode) {
  19. case ABUMediatedNativeAdModeSmallImage:
  20. case ABUMediatedNativeAdModeLargeImage:
  21. case ABUMediatedNativeAdModePortraitImage:
  22. [self _renderSmallImageWithLimitFrame:limitFrame];
  23. break;
  24. case ABUMediatedNativeAdModeGroupImage:
  25. [self _renderGroupImageWithLimitFrame:limitFrame];
  26. break;
  27. case ABUMediatedNativeAdModeLandscapeVideo:
  28. case ABUMediatedNativeAdModePortraitVideo:
  29. [self _renderVideoWithLimitFrame:limitFrame];
  30. break;
  31. default:
  32. break;
  33. }
  34. }
  35. - (void)_commonRender {
  36. // 头像
  37. [self _fillAvatarWithOrigin:CGPointMake(gromore_demo_native_padding.left, gromore_demo_native_padding.top)];
  38. // 标题
  39. CGFloat limitWidth = self.frame.size.width - CGRectGetMaxX(self.iconImageView.frame) - gromore_demo_padding - gromore_demo_native_padding.right;
  40. [self _fillTitleWithFrame:CGRectMake(CGRectGetMaxX(self.iconImageView.frame) + gromore_demo_padding, gromore_demo_native_padding.top, limitWidth, self.iconImageView.frame.size.height)];
  41. // 关闭
  42. [self _fillCloseButtonWithFrame:CGRectMake(self.frame.size.width - gromore_demo_native_padding.right - 24, gromore_demo_native_padding.top, 24, 24)];
  43. // 描述
  44. [self _fillBodyWithFrame:CGRectMake(self.titleLabel.frame.origin.x, CGRectGetMaxY(self.titleLabel.frame) + gromore_demo_padding, limitWidth, 0)];
  45. // 广告标识
  46. [self _fillLogoWithFrame:CGRectMake(gromore_demo_native_padding.left, self.frame.size.height - gromore_demo_native_padding.bottom - 24, 24, 24)];
  47. // 详情按钮
  48. [self _fillDetailButtonWithTail:CGPointMake(self.frame.size.width - gromore_demo_native_padding.right, self.frame.size.height - gromore_demo_native_padding.bottom)];
  49. }
  50. // 广告app图标
  51. - (void)_fillAvatarWithOrigin:(CGPoint)origin {
  52. if (!self.iconImageView) {
  53. self.iconImageView = [[UIImageView alloc] init];
  54. [self addSubview:self.iconImageView];
  55. }
  56. ABUImage *image = self.data.icon;
  57. if (image) {
  58. [self.iconImageView yy_setImageWithURL:image.imageURL placeholder:image.image];
  59. } else {
  60. self.iconImageView.backgroundColor = [UIColor lightGrayColor];
  61. }
  62. self.iconImageView.layer.cornerRadius = 4.f;
  63. self.iconImageView.clipsToBounds = YES;
  64. self.iconImageView.frame = (CGRect){origin, CGSizeMake(44, 44)};
  65. }
  66. // 广告标题
  67. - (void)_fillTitleWithFrame:(CGRect)frame {
  68. self.titleLabel.text = self.data.adTitle ?: self.titleLabel.text ?: @"[广告标题]";
  69. self.titleLabel.font = RQRegularFont(14);
  70. self.titleLabel.textColor = RQ_MAIN_TEXT_COLOR_1;
  71. self.titleLabel.frame = frame;
  72. [self.titleLabel sizeToFit];
  73. }
  74. // 广告描述
  75. - (void)_fillBodyWithFrame:(CGRect)frame {
  76. if (self.descLabel.text == nil) {
  77. self.descLabel.text = self.data.adDescription ?: @"[广告描述]";
  78. }
  79. self.descLabel.font = RQRegularFont(12);
  80. self.descLabel.textColor = RQ_MAIN_TEXT_COLOR_1;
  81. self.descLabel.numberOfLines = 0;
  82. self.descLabel.frame = frame;
  83. [self.descLabel sizeToFit];
  84. }
  85. // 广告标识
  86. - (void)_fillLogoWithFrame:(CGRect)frame {
  87. if (!self.adLogoView) {
  88. ABUImage *logo = self.data.adLogo;
  89. self.adLogoView = [[UIImageView alloc] init];
  90. [(UIImageView *)self.adLogoView yy_setImageWithURL:logo.imageURL placeholder:logo.image];
  91. [self addSubview:self.adLogoView];
  92. CGFloat width = logo.width;
  93. CGFloat height = logo.height;
  94. CGFloat displayHeight = frame.size.height;
  95. CGFloat displayWidth = frame.size.width;
  96. if (height != 0) {
  97. displayWidth = width / height * displayHeight;
  98. }
  99. self.adLogoView.frame = (CGRect){frame.origin, CGSizeMake(displayWidth, displayHeight)};
  100. [self addSubview:self.adLogoView];
  101. } else {
  102. CGFloat width = self.adLogoView.frame.size.width;
  103. CGFloat height = self.adLogoView.frame.size.height;
  104. CGFloat displayHeight = frame.size.height;
  105. CGFloat displayWidth = frame.size.width;
  106. if (height != 0) {
  107. displayWidth = width / height * displayHeight;
  108. }
  109. self.adLogoView.frame = (CGRect){frame.origin, CGSizeMake(displayWidth, displayHeight)};
  110. if ([self.adLogoView isKindOfClass:[UIImageView class]] && ![(UIImageView *)self.adLogoView image]) {
  111. ABUImage *logo = self.data.adLogo;
  112. self.adLogoView = [[UIImageView alloc] init];
  113. [(UIImageView *)self.adLogoView yy_setImageWithURL:logo.imageURL placeholder:logo.image];
  114. }
  115. }
  116. }
  117. - (void)_fillCloseButtonWithFrame:(CGRect)frame {
  118. if (!self.dislikeBtn) {
  119. self.dislikeBtn = [[UIButton alloc] init];
  120. [self.dislikeBtn setImage:[UIImage imageNamed:@"feedClose"] forState:UIControlStateNormal];
  121. [self.dislikeBtn addTarget:self action:@selector(closeAction) forControlEvents:UIControlEventTouchUpInside];
  122. }
  123. self.dislikeBtn.frame = frame;
  124. }
  125. - (void)_fillDetailButtonWithTail:(CGPoint)tail {
  126. // 详情按钮
  127. if (self.hasSupportActionBtn) {
  128. CGFloat customBtnWidth = 80;
  129. CGFloat customBtnHeight = 24;
  130. self.callToActionBtn.frame = CGRectMake(tail.x - customBtnWidth, tail.y - customBtnHeight, customBtnWidth, customBtnHeight);
  131. if (self.data.buttonText.length > 0) {
  132. [self.callToActionBtn setTitle:self.data.buttonText forState:UIControlStateNormal];
  133. } else {
  134. [self.callToActionBtn setTitle:@"查看详情" forState:UIControlStateNormal];
  135. }
  136. self.callToActionBtn.backgroundColor = RQ_MAIN_BACKGROUNDCOLOR;
  137. self.callToActionBtn.titleLabel.font = RQRegularFont(12);
  138. self.callToActionBtn.layer.cornerRadius = 4.f;
  139. self.callToActionBtn.layer.masksToBounds = YES;
  140. }
  141. }
  142. - (void)_renderSmallImageWithLimitFrame:(CGRect)limitFrame {
  143. // 小图
  144. ABUImage *image = self.data.imageList.firstObject;
  145. CGSize imageSize = [self _maxConstrainSizeWithOriginSize:CGSizeMake(image.width, image.height) andLimitSize:limitFrame.size];
  146. if (CGSizeEqualToSize(imageSize, CGSizeZero)) {
  147. imageSize = limitFrame.size;
  148. }
  149. self.imageView.frame = (CGRect){limitFrame.origin, imageSize};
  150. if (image) {
  151. [self.imageView yy_setImageWithURL:image.imageURL placeholder:image.image];
  152. }
  153. [self registerClickableViews:@[
  154. self.titleLabel,
  155. self.descLabel,
  156. self.imageView,
  157. self.iconImageView,
  158. self.callToActionBtn
  159. ]];
  160. }
  161. - (void)_renderGroupImageWithLimitFrame:(CGRect)limitFrame {
  162. NSInteger count = self.data.imageList.count;
  163. CGFloat imagePadding = 2;
  164. CGFloat singleWidth = (limitFrame.size.width - (count - 1) * imagePadding) / count;
  165. CGFloat offsetX = limitFrame.origin.x;
  166. CGFloat offsetY = limitFrame.origin.y;
  167. for (ABUImage *image in self.data.imageList ) {
  168. UIImageView *imageView = [[UIImageView alloc] init];
  169. CGSize size = [self _maxConstrainSizeWithOriginSize:CGSizeMake(singleWidth, limitFrame.size.height) andLimitSize:limitFrame.size];
  170. imageView.frame = CGRectMake(offsetX, offsetY, size.width, size.height);
  171. if (image) {
  172. [imageView yy_setImageWithURL:image.imageURL placeholder:image.image];
  173. } else {
  174. imageView.backgroundColor = [UIColor lightGrayColor];
  175. }
  176. [self addSubview:imageView];
  177. offsetX += size.width + imagePadding;
  178. }
  179. [self registerClickableViews:@[
  180. self.titleLabel,
  181. self.descLabel,
  182. self.iconImageView,
  183. self.callToActionBtn
  184. ]];
  185. }
  186. - (void)_renderVideoWithLimitFrame:(CGRect)limitFrame {
  187. ABUImage *image = self.data.imageList.firstObject;
  188. CGSize imageSize = [self _maxConstrainSizeWithOriginSize:CGSizeMake(image.width, image.height) andLimitSize:limitFrame.size];
  189. if (CGSizeEqualToSize(imageSize, CGSizeZero)) {
  190. imageSize = limitFrame.size;
  191. }
  192. self.mediaView.frame = (CGRect){limitFrame.origin, imageSize};
  193. self.imageView.hidden = YES;
  194. [self registerClickableViews:@[
  195. self.titleLabel,
  196. self.descLabel,
  197. self.callToActionBtn,
  198. self.mediaView
  199. ]];
  200. }
  201. - (void)closeAction {
  202. [self removeFromSuperview];
  203. }
  204. - (NSString *)_otherDescInfo {
  205. NSMutableString *result = [NSMutableString string];
  206. // 返回不为空表示物料可用
  207. if (self.data.appPrice.length > 0) {
  208. NSString *price = [NSString stringWithFormat:@"价格:%@", self.data.appPrice];
  209. [result appendString:price];
  210. }
  211. if (self.data.score > 0) {
  212. NSString *score = [NSString stringWithFormat:@"评分:%ld", self.data.score];
  213. [result appendFormat:@"%@%@", result.length ? @":" : @"", score];
  214. }
  215. if (self.data.source.length > 0) {
  216. NSString *source = [NSString stringWithFormat:@"来源:%@", self.data.source];
  217. [result appendFormat:@"%@%@", result.length ? @":" : @"", source];
  218. }
  219. return result.copy;
  220. }
  221. - (CGSize)_maxConstrainSizeWithOriginSize:(CGSize)size andLimitSize:(CGSize)limitSize {
  222. if (size.height <= 0 || limitSize.height <= 0) return CGSizeZero;
  223. CGFloat factor = size.width / size.height;
  224. CGFloat limitFactor = limitSize.width / limitSize.height;
  225. if (factor > limitFactor) {
  226. CGFloat resultWidth = limitSize.width;
  227. CGFloat resultHeight = resultWidth * factor;
  228. return CGSizeMake(resultWidth, resultHeight);
  229. } else {
  230. CGFloat resultHeight = limitSize.height;
  231. CGFloat resultWidth = resultHeight * factor;
  232. return CGSizeMake(resultWidth, resultHeight);
  233. }
  234. }
  235. @end