MMRichTitleCell.m 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. //
  2. // MMRichTitleCell.m
  3. // RichTextEditDemo
  4. //
  5. // Created by aron on 2017/7/21.
  6. // Copyright © 2017年 aron. All rights reserved.
  7. //
  8. #import "MMRichTitleCell.h"
  9. #import "MMTextView.h"
  10. #import "MMRichTitleModel.h"
  11. #import <Masonry.h>
  12. #import "MMRichTextConfig.h"
  13. #import "UtilMacro.h"
  14. @interface MMRichTitleCell () <MMTextViewDelegate, UITextViewDelegate>
  15. @property (nonatomic, strong) MMTextView* textView;
  16. @property (nonatomic, strong) UIView* separatorView;
  17. @property (nonatomic, strong) MMRichTitleModel* titleModel;
  18. @property (nonatomic, assign) BOOL isEditing;
  19. @end
  20. @implementation MMRichTitleCell
  21. - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
  22. self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
  23. if (self) {
  24. [self setupUI];
  25. }
  26. return self;
  27. }
  28. - (void)dealloc {
  29. _textView.delegate = nil;
  30. [[NSNotificationCenter defaultCenter ] removeObserver:self];
  31. }
  32. - (void)setupUI {
  33. [self addSubview:self.textView];
  34. [self addSubview:self.separatorView];
  35. [self.textView mas_makeConstraints:^(MASConstraintMaker *make) {
  36. make.left.top.right.equalTo(self);
  37. make.bottom.equalTo(self).priority(900);
  38. }];
  39. [self.separatorView mas_makeConstraints:^(MASConstraintMaker *make) {
  40. make.left.equalTo(self).offset(convertLength(15));
  41. make.right.equalTo(self).offset(-convertLength(15));
  42. make.bottom.equalTo(self).offset(-convertLength(0.5));
  43. make.height.equalTo(@(convertLength(7.5)));
  44. }];
  45. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange:) name:UITextViewTextDidChangeNotification object:nil];
  46. }
  47. - (void)updateWithData:(id)data indexPath:(NSIndexPath*)indexPath {
  48. if ([data isKindOfClass:[MMRichTitleModel class]]) {
  49. MMRichTitleModel* titleModel = (MMRichTitleModel*)data;
  50. _titleModel = titleModel;
  51. // 重新设置TextView的约束
  52. [self.textView mas_remakeConstraints:^(MASConstraintMaker *make) {
  53. make.left.top.right.equalTo(self);
  54. make.bottom.equalTo(self).priority(900);
  55. make.height.equalTo(@(_titleModel.titleContentHeight));
  56. }];
  57. // Content
  58. self.textView.text = _titleModel.textContent;
  59. }
  60. }
  61. - (void)mm_beginEditing {
  62. [self.textView becomeFirstResponder];
  63. if (![self.textView.text isEqualToString:_titleModel.textContent]) {
  64. self.textView.text = _titleModel.textContent;
  65. // 手动调用回调方法修改
  66. [self textViewDidChange:self.textView];
  67. }
  68. }
  69. - (void)mm_endEditing {
  70. BOOL result = [self.textView resignFirstResponder];
  71. // NSLog(@"result = %d", result);
  72. }
  73. #pragma mark - ......::::::: lazy load :::::::......
  74. - (MMTextView *)textView {
  75. if (!_textView) {
  76. _textView = [MMTextView new];
  77. _textView.font = MMEditConfig.defaultEditTitleFont;
  78. _textView.textContainerInset = UIEdgeInsetsMake(MMEditConfig.editTitleAreaTopPadding, MMEditConfig.editTitleAreaLeftPadding, MMEditConfig.editTitleAreaBottomPadding, MMEditConfig.editTitleAreaRightPadding);
  79. _textView.scrollEnabled = NO;
  80. _textView.maxInputs = MMEditConfig.titleMaxCount;
  81. _textView.placeHolder = @"标题:";
  82. _textView.placeHolderColor = UIColorHex(#999999);
  83. _textView.showPlaceHolder = YES;
  84. _textView.delegate = self;
  85. _textView.mm_delegate = self;
  86. _textView.textColor = UIColorHex(#0A0A0A);
  87. }
  88. return _textView;
  89. }
  90. - (UIView *)separatorView {
  91. if (!_separatorView) {
  92. _separatorView = [UIView new];
  93. _separatorView.backgroundColor = [UIColor whiteColor];
  94. UIView* separatorLine = [UIView new];
  95. separatorLine.backgroundColor = UIColorHex(#C7E4FB);
  96. [_separatorView addSubview:separatorLine];
  97. [separatorLine mas_makeConstraints:^(MASConstraintMaker *make) {
  98. make.height.equalTo(@(convertLength(0.5)));
  99. make.left.top.right.equalTo(_separatorView);
  100. }];
  101. }
  102. return _separatorView;
  103. }
  104. #pragma mark - ......::::::: UITextViewDelegate :::::::......
  105. - (void)textViewDidChange:(UITextView *)textView {
  106. }
  107. - (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
  108. if ([self.delegate respondsToSelector:@selector(mm_shouldShowAccessoryView:)]) {
  109. [self.delegate mm_shouldShowAccessoryView:NO];
  110. }
  111. self.isEditing = YES;
  112. return YES;
  113. }
  114. - (BOOL)textViewShouldEndEditing:(UITextView *)textView {
  115. self.isEditing = NO;
  116. return YES;
  117. }
  118. - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
  119. NSLog(@"");
  120. // 处理删除,防止输入的字数为最大值的时候删除无效
  121. if ([text isEqualToString:@""]) {
  122. return YES;
  123. }
  124. if (NO == self.isEditing) {
  125. // 隐藏键盘,TextView会自动填充选中的联想词,这个地方返回NO做特殊处理,
  126. // 不让TextView自动填充选中的联想词
  127. self.isEditing = YES;
  128. return NO;
  129. }
  130. // 中间位置不能插入更多导致超过最大值
  131. // 结尾位置支持插入更多 && range.location < textView.text.length
  132. if (textView.text.length + text.length > MMEditConfig.titleMaxCount) {
  133. return NO;
  134. }
  135. return YES;
  136. }
  137. - (void)handleTextViewDidChange {
  138. CGRect frame = self.textView.frame;
  139. CGSize constraintSize = CGSizeMake(frame.size.width, MAXFLOAT);
  140. CGSize size = [self.textView sizeThatFits:constraintSize];
  141. // 更新模型数据
  142. _titleModel.titleContentHeight = size.height;
  143. _titleModel.textContent = self.textView.text;
  144. _titleModel.selectedRange = self.textView.selectedRange;
  145. _titleModel.isEditing = YES;
  146. if (ABS(_textView.frame.size.height - size.height) > 5) {
  147. // 重新设置TextView的约束
  148. [self.textView mas_remakeConstraints:^(MASConstraintMaker *make) {
  149. make.left.top.right.equalTo(self);
  150. make.bottom.equalTo(self).priority(900);
  151. make.height.equalTo(@(_titleModel.titleContentHeight));
  152. }];
  153. UITableView* tableView = [self containerTableView];
  154. [tableView beginUpdates];
  155. [tableView endUpdates];
  156. }
  157. }
  158. #pragma mark - ......::::::: notification :::::::......
  159. - (void)textDidChange:(NSNotification*)notification {
  160. NSObject* obj = notification.object;
  161. if (obj == self.textView) {
  162. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  163. [self handleTextViewDidChange];
  164. });
  165. }
  166. }
  167. @end