LKS_PerspectiveHierarchyCell.m 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. //
  2. // LKS_PerspectiveHierarchyCell.m
  3. // LookinServer
  4. //
  5. // Created by Li Kai on 2018/12/24.
  6. // https://lookin.work
  7. //
  8. #import "LKS_PerspectiveHierarchyCell.h"
  9. #import "LookinDisplayItem.h"
  10. #import "LookinIvarTrace.h"
  11. #import "LookinServerDefines.h"
  12. @interface LKS_PerspectiveHierarchyCell ()
  13. @property(nonatomic, strong) UILabel *titleLabel;
  14. @property(nonatomic, strong) UILabel *subtitleLabel;
  15. @property(nonatomic, strong) CALayer *strikethroughLayer;
  16. @property(nonatomic, assign) CGFloat cachedContentWidth;
  17. @end
  18. @implementation LKS_PerspectiveHierarchyCell {
  19. CGFloat _horInset;
  20. CGFloat _indicatorWidth;
  21. CGFloat _iconImageMarginLeft;
  22. CGFloat _indentUnitWidth;
  23. CGFloat _titleLeft;
  24. CGFloat _subtitleLeft;
  25. }
  26. - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
  27. if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
  28. _horInset = 10;
  29. _indicatorWidth = 15;
  30. _iconImageMarginLeft = 5;
  31. _indentUnitWidth = 10;
  32. _titleLeft = 6;
  33. _subtitleLeft = 10;
  34. _indicatorButton = [UIButton new];
  35. [self.contentView addSubview:self.indicatorButton];
  36. self.titleLabel = [UILabel new];
  37. self.titleLabel.font = [UIFont systemFontOfSize:12];
  38. [self.contentView addSubview:self.titleLabel];
  39. self.subtitleLabel = [UILabel new];
  40. self.subtitleLabel.font = [UIFont systemFontOfSize:11];
  41. [self.contentView addSubview:self.subtitleLabel];
  42. }
  43. return self;
  44. }
  45. - (void)layoutSubviews {
  46. [super layoutSubviews];
  47. self.indicatorButton.frame = ({
  48. CGFloat x = self.displayItem.indentLevel * _indentUnitWidth + _horInset;
  49. CGRectMake(x, 0, _indicatorWidth, self.bounds.size.height);
  50. });
  51. self.titleLabel.frame = ({
  52. CGFloat width = self.titleLabel.lks_bestWidth;
  53. CGRectMake(CGRectGetMaxX(self.indicatorButton.frame) + _titleLeft, 0, width, self.bounds.size.height);
  54. });
  55. CGFloat labelMaxX = CGRectGetMaxX(self.titleLabel.frame);
  56. if (!self.subtitleLabel.hidden) {
  57. self.subtitleLabel.frame = ({
  58. CGFloat width = self.subtitleLabel.lks_bestWidth;
  59. CGRectMake(CGRectGetMaxX(self.titleLabel.frame) + _subtitleLeft, 0, width, self.bounds.size.height);
  60. });
  61. labelMaxX = CGRectGetMaxX(self.subtitleLabel.frame);
  62. }
  63. if (self.strikethroughLayer && !self.strikethroughLayer.hidden) {
  64. self.strikethroughLayer.frame = ({
  65. CGFloat x = CGRectGetMinX(self.titleLabel.frame) - 2;
  66. CGFloat maxX = self.subtitleLabel.hidden ? (CGRectGetMaxX(self.titleLabel.frame) + 2) : (CGRectGetMaxX(self.subtitleLabel.frame) + 2);
  67. CGFloat width = maxX - x;
  68. CGRectMake(x, CGRectGetMidY(self.bounds), width, 1);
  69. });
  70. }
  71. }
  72. - (CGSize)sizeThatFits:(CGSize)size {
  73. size.width = self.cachedContentWidth;
  74. return size;
  75. }
  76. - (void)setDisplayItem:(LookinDisplayItem *)displayItem {
  77. _displayItem = displayItem;
  78. [self reRender];
  79. }
  80. - (void)reRender {
  81. // text
  82. self.titleLabel.text = self.displayItem.title;
  83. // subtitle
  84. self.subtitleLabel.text = self.displayItem.subtitle;
  85. self.subtitleLabel.hidden = (self.displayItem.subtitle.length == 0);
  86. // select
  87. if (self.displayItem.isSelected) {
  88. self.backgroundColor = LookinColorRGBAMake(172, 177, 191, .4);
  89. self.subtitleLabel.textColor = [UIColor whiteColor];
  90. } else {
  91. self.backgroundColor = [UIColor clearColor];
  92. self.subtitleLabel.textColor = LookinColorMake(133, 140, 150);
  93. }
  94. // icon
  95. if (!self.displayItem.isExpandable) {
  96. self.indicatorButton.hidden = YES;
  97. } else if (self.displayItem.isExpanded) {
  98. [self.indicatorButton setImage:[self _arrowDownImage] forState:UIControlStateNormal];
  99. self.indicatorButton.hidden = NO;
  100. } else {
  101. [self.indicatorButton setImage:[self _arrowRightImage] forState:UIControlStateNormal];
  102. self.indicatorButton.hidden = NO;
  103. }
  104. // strike
  105. if (self.displayItem.inNoPreviewHierarchy) {
  106. if (!self.strikethroughLayer) {
  107. self.strikethroughLayer = [CALayer layer];
  108. [self.strikethroughLayer lookin_removeImplicitAnimations];
  109. self.strikethroughLayer.backgroundColor = LookinColorRGBAMake(255, 255, 255, .3).CGColor;
  110. [self.layer addSublayer:self.strikethroughLayer];
  111. }
  112. self.strikethroughLayer.hidden = NO;
  113. if (self.displayItem.isSelected) {
  114. self.titleLabel.textColor = [UIColor whiteColor];
  115. } else {
  116. self.titleLabel.textColor = LookinColorMake(113, 120, 130);
  117. }
  118. } else {
  119. self.strikethroughLayer.hidden = YES;
  120. self.titleLabel.textColor = [UIColor whiteColor];
  121. }
  122. [self setNeedsLayout];
  123. self.cachedContentWidth = ({
  124. CGFloat width = 0;
  125. width = _horInset + self.displayItem.indentLevel * _indentUnitWidth + _indicatorWidth + _iconImageMarginLeft + _titleLeft + self.titleLabel.lks_bestWidth + _horInset;
  126. if (!self.subtitleLabel.hidden) {
  127. width += self.subtitleLabel.lks_bestWidth + _subtitleLeft;
  128. }
  129. width;
  130. });
  131. }
  132. - (UIImage *)_arrowRightImage {
  133. static UIImage *image = nil;
  134. if (image) {
  135. return image;
  136. }
  137. CGFloat width = 10;
  138. UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, width), NO, 0);
  139. CGContextRef context = UIGraphicsGetCurrentContext();
  140. UIBezierPath *path = [UIBezierPath bezierPath];
  141. [path moveToPoint:CGPointMake(0, 0)];
  142. [path addLineToPoint:CGPointMake(width - 2, width / 2.0)];
  143. [path addLineToPoint:CGPointMake(0, width)];
  144. [path closePath];
  145. CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
  146. [path fill];
  147. image = UIGraphicsGetImageFromCurrentImageContext();
  148. UIGraphicsEndImageContext();
  149. return image;
  150. }
  151. - (UIImage *)_arrowDownImage {
  152. static UIImage *image = nil;
  153. if (image) {
  154. return image;
  155. }
  156. CGFloat width = 10;
  157. UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, width), NO, 0);
  158. CGContextRef context = UIGraphicsGetCurrentContext();
  159. UIBezierPath *path = [UIBezierPath bezierPath];
  160. [path moveToPoint:CGPointMake(0, 0)];
  161. [path addLineToPoint:CGPointMake(width, 0)];
  162. [path addLineToPoint:CGPointMake(width / 2.0, width - 2)];
  163. [path closePath];
  164. CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);
  165. [path fill];
  166. image = UIGraphicsGetImageFromCurrentImageContext();
  167. UIGraphicsEndImageContext();
  168. return image;
  169. }
  170. @end