YYTextAsyncExample.m 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. //
  2. // YYTextAsyncExample.m
  3. // YYKitExample
  4. //
  5. // Created by ibireme on 15/9/3.
  6. // Copyright (c) 2015 ibireme. All rights reserved.
  7. //
  8. #import "YYTextAsyncExample.h"
  9. #import "YYText.h"
  10. #import "YYImage.h"
  11. #import "UIImage+YYWebImage.h"
  12. #import "UIView+YYAdd.h"
  13. #import "NSBundle+YYAdd.h"
  14. #import "NSString+YYAdd.h"
  15. #import "CALayer+YYAdd.h"
  16. #import "UIControl+YYAdd.h"
  17. #import "YYTextExampleHelper.h"
  18. #import "YYFPSLabel.h"
  19. #define kCellHeight 34
  20. @interface YYTextAsyncExampleCell : UITableViewCell
  21. @property (nonatomic, assign) BOOL async;
  22. - (void)setAyncText:(NSAttributedString *)text;
  23. @end
  24. @implementation YYTextAsyncExampleCell {
  25. UILabel *_uiLabel;
  26. YYLabel *_yyLabel;
  27. }
  28. - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
  29. self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
  30. _uiLabel = [UILabel new];
  31. _uiLabel.font = [UIFont systemFontOfSize:8];
  32. _uiLabel.numberOfLines = 0;
  33. _uiLabel.size = CGSizeMake(kScreenWidth, kCellHeight);
  34. _yyLabel = [YYLabel new];
  35. _yyLabel.font = _uiLabel.font;
  36. _yyLabel.numberOfLines = _uiLabel.numberOfLines;
  37. _yyLabel.size = _uiLabel.size;
  38. _yyLabel.displaysAsynchronously = YES; /// enable async display
  39. _yyLabel.hidden = YES;
  40. [self.contentView addSubview:_uiLabel];
  41. [self.contentView addSubview:_yyLabel];
  42. return self;
  43. }
  44. - (void)setAsync:(BOOL)async {
  45. if (_async == async) return;
  46. _async = async;
  47. _uiLabel.hidden = async;
  48. _yyLabel.hidden = !async;
  49. }
  50. - (void)setAyncText:(id)text {
  51. if (_async) {
  52. _yyLabel.layer.contents = nil;
  53. _yyLabel.textLayout = text;
  54. } else {
  55. _uiLabel.attributedText = text;
  56. }
  57. }
  58. @end
  59. @interface YYTextAsyncExample () <UITableViewDelegate, UITableViewDataSource>
  60. @property (nonatomic, assign) BOOL async;
  61. @property (nonatomic, strong) NSArray *strings;
  62. @property (nonatomic, strong) NSArray *layouts;
  63. @property (nonatomic, strong) UITableView *tableView;
  64. @end
  65. @implementation YYTextAsyncExample
  66. - (void)viewDidLoad {
  67. [super viewDidLoad];
  68. self.tableView = [UITableView new];
  69. self.tableView.frame = self.view.bounds;
  70. self.tableView.delegate = self;
  71. self.tableView.dataSource = self;
  72. [self.tableView registerClass:[YYTextAsyncExampleCell class] forCellReuseIdentifier:@"id"];
  73. [self.view addSubview:self.tableView];
  74. NSMutableArray *strings = [NSMutableArray new];
  75. NSMutableArray *layouts = [NSMutableArray new];
  76. for (int i = 0; i < 300; i++) {
  77. NSString *str = [NSString stringWithFormat:@"%d Async Display Test ✺◟(∗❛ัᴗ❛ั∗)◞✺ ✺◟(∗❛ัᴗ❛ั∗)◞✺ 😀😖😐😣😡🚖🚌🚋🎊💖💗💛💙🏨🏦🏫 Async Display Test ✺◟(∗❛ัᴗ❛ั∗)◞✺ ✺◟(∗❛ัᴗ❛ั∗)◞✺ 😀😖😐😣😡🚖🚌🚋🎊💖💗💛💙🏨🏦🏫",i];
  78. NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString:str];
  79. text.yy_font = [UIFont systemFontOfSize:10];
  80. text.yy_lineSpacing = 0;
  81. text.yy_strokeWidth = @(-3);
  82. text.yy_strokeColor = [UIColor redColor];
  83. text.yy_lineHeightMultiple = 1;
  84. text.yy_maximumLineHeight = 12;
  85. text.yy_minimumLineHeight = 12;
  86. NSShadow *shadow = [NSShadow new];
  87. shadow.shadowBlurRadius = 1;
  88. shadow.shadowColor = [UIColor redColor];
  89. shadow.shadowOffset = CGSizeMake(0, 1);
  90. [strings addObject:text];
  91. // it better to do layout in background queue...
  92. YYTextContainer *container = [YYTextContainer containerWithSize:CGSizeMake(kScreenWidth, kCellHeight)];
  93. YYTextLayout *layout = [YYTextLayout layoutWithContainer:container text:text];
  94. [layouts addObject:layout];
  95. }
  96. self.strings = strings;
  97. self.layouts = layouts;
  98. UIView *toolbar;
  99. if ([UIVisualEffectView class]) {
  100. toolbar = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight]];
  101. } else {
  102. toolbar = [UIToolbar new];
  103. }
  104. toolbar.size = CGSizeMake(kScreenWidth, 40);
  105. toolbar.top = kiOS7Later ? 64 : 0;
  106. [self.view addSubview:toolbar];
  107. YYFPSLabel *fps = [YYFPSLabel new];
  108. fps.centerY = toolbar.height / 2;
  109. fps.left = 5;
  110. [toolbar addSubview:fps];
  111. UILabel *label = [UILabel new];
  112. label.backgroundColor = [UIColor clearColor];
  113. label.text = @"UILabel/YYLabel(Async): ";
  114. label.font = [UIFont systemFontOfSize:14];
  115. [label sizeToFit];
  116. label.centerY = toolbar.height / 2;
  117. label.left = fps.right + 10;
  118. [toolbar addSubview:label];
  119. UISwitch *switcher = [UISwitch new];
  120. [switcher sizeToFit];
  121. switcher.centerY = toolbar.height / 2;
  122. switcher.left = label.right + (kiOS7Later ? 10 : -10);
  123. switcher.layer.transformScale = 0.7;
  124. __weak typeof(self) _self = self;
  125. [switcher addBlockForControlEvents:UIControlEventValueChanged block:^(UISwitch *switcher) {
  126. typeof(_self) self = _self;
  127. if (!self) return;
  128. [self setAsync:switcher.isOn];
  129. }];
  130. [toolbar addSubview:switcher];
  131. }
  132. - (void)setAsync:(BOOL)async {
  133. _async = async;
  134. [self.tableView.visibleCells enumerateObjectsUsingBlock:^(YYTextAsyncExampleCell *cell, NSUInteger idx, BOOL *stop) {
  135. cell.async = async;
  136. NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
  137. if (_async) {
  138. [cell setAyncText:_layouts[indexPath.row]];
  139. } else {
  140. [cell setAyncText:_strings[indexPath.row]];
  141. }
  142. }];
  143. }
  144. #pragma mark - Table view data source
  145. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  146. return _strings.count;
  147. }
  148. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  149. return kCellHeight;
  150. }
  151. - (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath {
  152. return NO;
  153. }
  154. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  155. YYTextAsyncExampleCell *cell = [tableView dequeueReusableCellWithIdentifier:@"id" forIndexPath:indexPath];
  156. cell.async = _async;
  157. if (_async) {
  158. [cell setAyncText:_layouts[indexPath.row]];
  159. } else {
  160. [cell setAyncText:_strings[indexPath.row]];
  161. }
  162. return cell;
  163. }
  164. @end