FLEXSystemLogCell.m 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. //
  2. // FLEXSystemLogCell.m
  3. // FLEX
  4. //
  5. // Created by Ryan Olson on 1/25/15.
  6. // Copyright (c) 2015 f. All rights reserved.
  7. //
  8. #import "FLEXSystemLogCell.h"
  9. #import "FLEXSystemLogMessage.h"
  10. #import "UIFont+FLEX.h"
  11. NSString *const kFLEXSystemLogCellIdentifier = @"FLEXSystemLogCellIdentifier";
  12. @interface FLEXSystemLogCell ()
  13. @property (nonatomic) UILabel *logMessageLabel;
  14. @property (nonatomic) NSAttributedString *logMessageAttributedText;
  15. @end
  16. @implementation FLEXSystemLogCell
  17. - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
  18. self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
  19. if (self) {
  20. self.logMessageLabel = [UILabel new];
  21. self.logMessageLabel.numberOfLines = 0;
  22. self.separatorInset = UIEdgeInsetsZero;
  23. self.selectionStyle = UITableViewCellSelectionStyleNone;
  24. [self.contentView addSubview:self.logMessageLabel];
  25. }
  26. return self;
  27. }
  28. - (void)setLogMessage:(FLEXSystemLogMessage *)logMessage {
  29. if (![_logMessage isEqual:logMessage]) {
  30. _logMessage = logMessage;
  31. self.logMessageAttributedText = nil;
  32. [self setNeedsLayout];
  33. }
  34. }
  35. - (void)setHighlightedText:(NSString *)highlightedText {
  36. if (![_highlightedText isEqual:highlightedText]) {
  37. _highlightedText = highlightedText;
  38. self.logMessageAttributedText = nil;
  39. [self setNeedsLayout];
  40. }
  41. }
  42. - (NSAttributedString *)logMessageAttributedText {
  43. if (!_logMessageAttributedText) {
  44. _logMessageAttributedText = [[self class] attributedTextForLogMessage:self.logMessage highlightedText:self.highlightedText];
  45. }
  46. return _logMessageAttributedText;
  47. }
  48. static const UIEdgeInsets kFLEXLogMessageCellInsets = {10.0, 10.0, 10.0, 10.0};
  49. - (void)layoutSubviews {
  50. [super layoutSubviews];
  51. self.logMessageLabel.attributedText = self.logMessageAttributedText;
  52. self.logMessageLabel.frame = UIEdgeInsetsInsetRect(self.contentView.bounds, kFLEXLogMessageCellInsets);
  53. }
  54. #pragma mark - Stateless helpers
  55. + (NSAttributedString *)attributedTextForLogMessage:(FLEXSystemLogMessage *)logMessage highlightedText:(NSString *)highlightedText {
  56. NSString *text = [self displayedTextForLogMessage:logMessage];
  57. NSDictionary<NSString *, id> *attributes = @{ NSFontAttributeName : UIFont.flex_codeFont };
  58. NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:attributes];
  59. if (highlightedText.length > 0) {
  60. NSMutableAttributedString *mutableAttributedText = attributedText.mutableCopy;
  61. NSMutableDictionary<NSString *, id> *highlightAttributes = attributes.mutableCopy;
  62. highlightAttributes[NSBackgroundColorAttributeName] = UIColor.yellowColor;
  63. NSRange remainingSearchRange = NSMakeRange(0, text.length);
  64. while (remainingSearchRange.location < text.length) {
  65. remainingSearchRange.length = text.length - remainingSearchRange.location;
  66. NSRange foundRange = [text rangeOfString:highlightedText options:NSCaseInsensitiveSearch range:remainingSearchRange];
  67. if (foundRange.location != NSNotFound) {
  68. remainingSearchRange.location = foundRange.location + foundRange.length;
  69. [mutableAttributedText setAttributes:highlightAttributes range:foundRange];
  70. } else {
  71. break;
  72. }
  73. }
  74. attributedText = mutableAttributedText;
  75. }
  76. return attributedText;
  77. }
  78. + (NSString *)displayedTextForLogMessage:(FLEXSystemLogMessage *)logMessage {
  79. return [NSString stringWithFormat:@"%@: %@", [self logTimeStringFromDate:logMessage.date], logMessage.messageText];
  80. }
  81. + (CGFloat)preferredHeightForLogMessage:(FLEXSystemLogMessage *)logMessage inWidth:(CGFloat)width {
  82. UIEdgeInsets insets = kFLEXLogMessageCellInsets;
  83. CGFloat availableWidth = width - insets.left - insets.right;
  84. NSAttributedString *attributedLogText = [self attributedTextForLogMessage:logMessage highlightedText:nil];
  85. CGSize labelSize = [attributedLogText boundingRectWithSize:CGSizeMake(availableWidth, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading context:nil].size;
  86. return labelSize.height + insets.top + insets.bottom;
  87. }
  88. + (NSString *)logTimeStringFromDate:(NSDate *)date {
  89. static NSDateFormatter *formatter = nil;
  90. static dispatch_once_t onceToken;
  91. dispatch_once(&onceToken, ^{
  92. formatter = [NSDateFormatter new];
  93. formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSS";
  94. });
  95. return [formatter stringFromDate:date];
  96. }
  97. @end