SLEditTextView.m 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. //
  2. // SLEditTextView.m
  3. // DarkMode
  4. //
  5. // Created by wsl on 2019/10/17.
  6. // Copyright © 2019 wsl. All rights reserved.
  7. //
  8. #import "SLEditTextView.h"
  9. #import "SLPaddingLabel.h"
  10. @interface SLEditTextView ()<UITextViewDelegate>
  11. {
  12. CGFloat _keyboardHeight;
  13. }
  14. @property (nonatomic, strong) UIButton *cancleEditBtn; //取消编辑
  15. @property (nonatomic, strong) UIButton *doneEditBtn; //完成编辑
  16. @property (nonatomic, strong) UITextView *textView; //文本输入
  17. @property (nonatomic, strong) NSArray *colors; //颜色集合
  18. @property (nonatomic, assign) int currentIndex; // 当前颜色索引
  19. @property (nonatomic, strong) UIColor *currentColor; // 当前颜色
  20. @property (nonatomic, assign) BOOL colorSwitch; // 颜色开关 0:默认设置文本颜色 1:背景颜色
  21. @end
  22. @implementation SLEditTextView
  23. #pragma mark - Override
  24. - (instancetype)initWithFrame:(CGRect)frame {
  25. self = [super initWithFrame:frame];
  26. if (self) {
  27. self.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.7];
  28. _currentColor = [UIColor whiteColor];
  29. _currentIndex = 0;
  30. _colors = @[[UIColor whiteColor], [UIColor blackColor], [UIColor redColor], [UIColor yellowColor], [UIColor greenColor], [UIColor blueColor], [UIColor purpleColor]];
  31. [self setupUI];
  32. }
  33. return self;
  34. }
  35. - (void)didMoveToSuperview {
  36. [super didMoveToSuperview];
  37. if (self.superview != nil) {
  38. [self.textView becomeFirstResponder];
  39. }
  40. }
  41. - (void)dealloc {
  42. [[NSNotificationCenter defaultCenter] removeObserver:self];
  43. }
  44. #pragma mark - UI
  45. - (void)setupUI {
  46. [self addSubview:self.textView];
  47. __weak typeof(self) weakSelf = self;
  48. self.configureEditParameters = ^(NSDictionary * _Nonnull parameters) {
  49. weakSelf.textView.textColor = parameters[@"textColor"];
  50. weakSelf.textView.backgroundColor = parameters[@"backgroundColor"];
  51. weakSelf.textView.text = parameters[@"text"];
  52. weakSelf.currentColor = weakSelf.textView.textColor;
  53. for (UIColor *color in weakSelf.colors) {
  54. if (CGColorEqualToColor(color.CGColor, weakSelf.currentColor.CGColor)) {
  55. weakSelf.currentIndex = (int)[weakSelf.colors indexOfObject:color];
  56. }
  57. }
  58. [weakSelf textViewDidChange:weakSelf.textView];
  59. };
  60. [self addSubview:self.cancleEditBtn];
  61. [self addSubview:self.doneEditBtn];
  62. //监听键盘frame改变
  63. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
  64. //添加键盘消失监听事件
  65. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
  66. }
  67. //颜色选择菜单视图
  68. - (void)colorSelectionView:(CGFloat)keyboardHeight {
  69. for (UIView *subView in self.subviews) {
  70. if (subView != self.doneEditBtn || subView != self.cancleEditBtn || subView != self.textView) {
  71. continue;
  72. }
  73. [subView removeFromSuperview];
  74. }
  75. int count = (int)_colors.count + 1;
  76. CGSize itemSize = CGSizeMake(20, 20);
  77. CGFloat space = (self.frame.size.width - count * itemSize.width)/(count + 1);
  78. for (int i = 0; i < count; i++) {
  79. UIButton * colorBtn = [[UIButton alloc] initWithFrame:CGRectMake(space + (itemSize.width + space)*i, self.sl_height - keyboardHeight - 20 - 20, itemSize.width, itemSize.height)];
  80. [self addSubview:colorBtn];
  81. if (i == 0) {
  82. [colorBtn addTarget:self action:@selector(colorSwitchBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  83. [colorBtn setImage:[UIImage imageNamed:@"EditMenuTextColor"] forState:UIControlStateNormal];
  84. [colorBtn setImage:[UIImage imageNamed:@"EditMenuTextBackgroundColor"] forState:UIControlStateSelected];
  85. }else {
  86. colorBtn.backgroundColor = _colors[(i - 1)];
  87. colorBtn.tag = 10 + (i - 1);
  88. [colorBtn addTarget:self action:@selector(textColorBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  89. colorBtn.layer.cornerRadius = itemSize.width/2.0;
  90. colorBtn.layer.borderColor = [UIColor whiteColor].CGColor;
  91. if(_currentIndex == (i - 1)) {
  92. colorBtn.layer.borderWidth = 4;
  93. colorBtn.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0f, 1.0f);
  94. }else {
  95. colorBtn.layer.borderWidth = 2;
  96. colorBtn.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.8f, 0.8f);
  97. }
  98. }
  99. }
  100. }
  101. #pragma mark - Getter
  102. - (UIButton *)cancleEditBtn {
  103. if (_cancleEditBtn == nil) {
  104. _cancleEditBtn = [[UIButton alloc] initWithFrame:CGRectMake(15, 30, 40, 30)];
  105. [_cancleEditBtn setTitle:@"取消" forState:UIControlStateNormal];
  106. [_cancleEditBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  107. _cancleEditBtn.titleLabel.font = [UIFont systemFontOfSize:14];
  108. [_cancleEditBtn addTarget:self action:@selector(cancleEditBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  109. }
  110. return _cancleEditBtn;
  111. }
  112. - (UIButton *)doneEditBtn {
  113. if (_doneEditBtn == nil) {
  114. _doneEditBtn = [[UIButton alloc] initWithFrame:CGRectMake(self.sl_width - 50 - 15, 30, 40, 30)];
  115. _doneEditBtn.backgroundColor = [UIColor colorWithRed:45/255.0 green:175/255.0 blue:45/255.0 alpha:1];
  116. [_doneEditBtn setTitle:@"完成" forState:UIControlStateNormal];
  117. [_doneEditBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  118. _doneEditBtn.titleLabel.font = [UIFont systemFontOfSize:14];
  119. _doneEditBtn.layer.cornerRadius = 4;
  120. [_doneEditBtn addTarget:self action:@selector(doneEditBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
  121. }
  122. return _doneEditBtn;
  123. }
  124. - (UITextView *)textView {
  125. if (!_textView) {
  126. _textView = [[UITextView alloc] initWithFrame:CGRectMake(30, 100, 0, 50)];
  127. _textView.backgroundColor = [UIColor clearColor];
  128. _textView.font = [UIFont systemFontOfSize:26];
  129. _textView.textColor = _currentColor;
  130. _textView.scrollEnabled = NO;
  131. _textView.delegate = self;
  132. _textView.clipsToBounds = NO;
  133. _textView.keyboardAppearance = UIKeyboardAppearanceDark;
  134. _textView.tintColor = [UIColor colorWithRed:45/255.0 green:175/255.0 blue:45/255.0 alpha:1];
  135. }
  136. return _textView;
  137. }
  138. #pragma mark - Help Methods
  139. // 返回一个文本水印视图
  140. - (UILabel *)copyTextView:(UITextView *)textView {
  141. SLPaddingLabel *label = [[SLPaddingLabel alloc] initWithFrame:textView.bounds];
  142. label.font = textView.font;
  143. label.userInteractionEnabled = YES;
  144. label.backgroundColor = textView.backgroundColor;
  145. label.textColor = textView.textColor;
  146. label.lineBreakMode = NSLineBreakByCharWrapping;
  147. label.textPadding = UIEdgeInsetsMake(textView.textContainerInset.top, 4, textView.textContainerInset.bottom, 4);
  148. label.text = textView.text;
  149. label.numberOfLines = 0;
  150. return label;
  151. }
  152. #pragma mark - EventsHandle
  153. //取消编辑
  154. - (void)cancleEditBtnClicked:(id)sender {
  155. [self.textView resignFirstResponder];
  156. if (self.editTextCompleted) {
  157. self.editTextCompleted(nil);
  158. }
  159. [self removeFromSuperview];
  160. }
  161. //完成编辑
  162. - (void)doneEditBtnClicked:(id)sender {
  163. [self.textView resignFirstResponder];
  164. if (self.editTextCompleted) {
  165. self.editTextCompleted([self copyTextView:self.textView]);
  166. }
  167. [self removeFromSuperview];
  168. }
  169. //选中的当前颜色
  170. - (void)textColorBtnClicked:(UIButton *)colorBtn {
  171. UIButton *previousBtn = (UIButton *)[self viewWithTag:(10 + _currentIndex)];
  172. previousBtn.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.8f, 0.8f);
  173. previousBtn.layer.borderWidth = 2;
  174. colorBtn.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);
  175. colorBtn.layer.borderWidth = 4;
  176. _currentIndex = (int)colorBtn.tag- 10;
  177. _currentColor = colorBtn.backgroundColor;
  178. if (_colorSwitch) {
  179. self.textView.backgroundColor = colorBtn.backgroundColor;
  180. }else {
  181. self.textView.textColor = colorBtn.backgroundColor;
  182. }
  183. }
  184. //选择当前是文本颜色菜单还是背景颜色菜单
  185. - (void)colorSwitchBtnClicked:(UIButton *)colorSwitch {
  186. _colorSwitch = !_colorSwitch;
  187. colorSwitch.selected = _colorSwitch;
  188. if (_colorSwitch) {
  189. self.textView.backgroundColor = [UIColor clearColor];
  190. self.textView.textColor = _currentColor;
  191. }else {
  192. self.textView.backgroundColor = _currentColor;
  193. self.textView.textColor = [UIColor whiteColor];
  194. }
  195. }
  196. //键盘即将弹出
  197. - (void)keyboardWillShow:(NSNotification *)notification {
  198. //获取键盘高度 keyboardHeight
  199. NSDictionary *userInfo = [notification userInfo];
  200. NSValue *aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
  201. CGRect keyboardRect = [aValue CGRectValue];
  202. _keyboardHeight = keyboardRect.size.height;
  203. [self colorSelectionView:_keyboardHeight];
  204. }
  205. //键盘即将消失
  206. - (void)keyboardWillHide:(NSNotification *)notification{
  207. [self.textView resignFirstResponder];
  208. if (self.editTextCompleted) {
  209. self.editTextCompleted(nil);
  210. }
  211. [self removeFromSuperview];
  212. }
  213. #pragma mark - UITextViewDelegate
  214. -(void)textViewDidChange:(UITextView *)textView{
  215. //最大高度
  216. CGFloat maxHeight = self.sl_height - 100 - _keyboardHeight - 20 - 20 - 20;
  217. CGSize constraintSize = CGSizeMake(self.sl_width - 2*30, MAXFLOAT);
  218. CGSize size = [textView sizeThatFits:constraintSize];
  219. if (size.height >= maxHeight) {
  220. textView.sl_y = 100 - (size.height - maxHeight);
  221. } else {
  222. textView.sl_y = 100;
  223. }
  224. textView.sl_height = size.height;
  225. textView.sl_width = size.width;
  226. }
  227. @end