MMPlaceHolderTextView.m 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. //
  2. // PlaceHolderTextView.m
  3. // RichTextEditDemo
  4. //
  5. // Created by aron on 2017/3/10.
  6. // Copyright © 2017年 aron. All rights reserved.
  7. //
  8. #import "MMPlaceHolderTextView.h"
  9. #import "UtilMacro.h"
  10. @implementation MMPlaceHolderTextView {
  11. UILabel* _placeHolderLabel;
  12. }
  13. - (instancetype)initWithCoder:(NSCoder *)aDecoder {
  14. self = [super initWithCoder:aDecoder];
  15. if (self) {
  16. [self defaultConfig];
  17. [self setupUI];
  18. }
  19. return self;
  20. }
  21. - (instancetype)initWithFrame:(CGRect)frame textContainer:(NSTextContainer *)textContainer {
  22. self = [super initWithFrame:frame textContainer:textContainer];
  23. if (self) {
  24. [self defaultConfig];
  25. [self setupUI];
  26. }
  27. return self;
  28. }
  29. - (void)dealloc {
  30. [[NSNotificationCenter defaultCenter ] removeObserver:self];
  31. }
  32. - (void)defaultConfig {
  33. _maxInputs = 1000;
  34. _showPlaceHolder = YES;
  35. _placeHolderFrame = CGRectMake(12, 10, kScreenWidth, 18);
  36. _debugMode = NO;
  37. }
  38. - (void)setupUI {
  39. UILabel* placeHolderLabel = [UILabel new];
  40. placeHolderLabel.textColor = [UIColor lightGrayColor];
  41. placeHolderLabel.font = self.font;
  42. placeHolderLabel.text = @"";
  43. placeHolderLabel.frame = _placeHolderFrame;
  44. [self addSubview:placeHolderLabel];
  45. _placeHolderLabel = placeHolderLabel;
  46. // 设置内容的内边距
  47. self.textContainerInset = UIEdgeInsetsMake(9, 7, 0, 7);
  48. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange:) name:UITextViewTextDidChangeNotification object:nil];
  49. }
  50. - (void)layoutSubviews {
  51. [super layoutSubviews];
  52. _placeHolderLabel.font = self.font;
  53. _placeHolderLabel.frame = _placeHolderFrame;
  54. }
  55. - (void)updateConstraints {
  56. [super updateConstraints];
  57. _placeHolderLabel.font = self.font;
  58. _placeHolderLabel.frame = _placeHolderFrame;
  59. }
  60. // Code from apple developer forum - @Steve Krulewitz, @Mark Marszal, @Eric Silverberg
  61. - (CGFloat)measureHeight
  62. {
  63. return ceilf([self sizeThatFits:self.frame.size].height + 10);
  64. }
  65. #pragma mark - ......::::::: notification :::::::......
  66. - (void)textDidChange:(NSNotification*)notification {
  67. NSObject* obj = notification.object;
  68. if ([obj isKindOfClass:[MMPlaceHolderTextView class]] && obj == self) {
  69. [self handleTextDidChange];
  70. }
  71. }
  72. - (void)handleTextDidChange {
  73. if (_debugMode) {
  74. return;
  75. }
  76. [self handlePlaceholder];
  77. // 字数限制
  78. NSString *toBeString = self.text;
  79. NSString *lang = [[UITextInputMode currentInputMode] primaryLanguage]; // 键盘输入模式
  80. if ([lang isEqualToString:@"zh-Hans"]) { // 简体中文输入,包括简体拼音,健体五笔,简体手写
  81. UITextRange *selectedRange = [self markedTextRange];
  82. //获取高亮部分
  83. UITextPosition *position = [self positionFromPosition:selectedRange.start offset:0];
  84. // 没有高亮选择的字,则对已输入的文字进行字数统计和限制
  85. if (!position) {
  86. if (toBeString.length > _maxInputs) {
  87. self.text = [toBeString substringToIndex:_maxInputs];
  88. }
  89. } else{
  90. // 有高亮选择的字符串,则暂不对文字进行统计和限制 pandahomeapi.ifjing.com
  91. }
  92. } else{
  93. // 中文输入法以外的直接对其统计限制即可,不考虑其他语种情况
  94. if (toBeString.length > _maxInputs) {
  95. self.text = [toBeString substringToIndex:_maxInputs];
  96. }
  97. }
  98. }
  99. #pragma mark - ......::::::: override :::::::......
  100. - (void)setFont:(UIFont *)font {
  101. [super setFont:font];
  102. _placeHolderLabel.font = font;
  103. [self resetPlaceHolderFrame];
  104. }
  105. - (void)setTextContainerInset:(UIEdgeInsets)textContainerInset {
  106. [super setTextContainerInset:textContainerInset];
  107. [self resetPlaceHolderFrame];
  108. }
  109. - (void)setText:(NSString *)text {
  110. [super setText:text];
  111. [self handlePlaceholder];
  112. }
  113. #pragma mark - ......::::::: private :::::::......
  114. // 重新设置PlaceHolder的Frame
  115. // 设置了font、textContainerInset之后需要重新设置
  116. - (void)resetPlaceHolderFrame {
  117. CGFloat leftDelta = 5;
  118. CGFloat topDelta = -1;
  119. UIEdgeInsets insets = self.textContainerInset;
  120. [self setPlaceHolderFrame:CGRectMake(insets.left + leftDelta, insets.top + topDelta, kScreenWidth - insets.left - insets.right, self.font.lineHeight + 2)];
  121. }
  122. - (void)handlePlaceholder {
  123. if (_showPlaceHolder) {
  124. if (self.text != nil && self.text.length > 0) {
  125. _placeHolderLabel.hidden = YES;
  126. } else {
  127. _placeHolderLabel.hidden = NO;
  128. }
  129. } else {
  130. _placeHolderLabel.hidden = YES;
  131. }
  132. }
  133. #pragma mark - ......::::::: public :::::::......
  134. - (void)setPlaceHolder:(NSString *)placeHolder {
  135. _placeHolderLabel.text = placeHolder;
  136. }
  137. - (void)setPlaceHolderFrame:(CGRect)placeHolderFrame {
  138. _placeHolderFrame = placeHolderFrame;
  139. _placeHolderLabel.frame = placeHolderFrame;
  140. }
  141. - (void)setPlaceHolderColor:(UIColor *)placeHolderColor {
  142. _placeHolderColor = placeHolderColor;
  143. _placeHolderLabel.textColor = placeHolderColor;
  144. }
  145. - (void)setShowPlaceHolder:(BOOL)showPlaceHolder {
  146. _showPlaceHolder = showPlaceHolder;
  147. [self handlePlaceholder];
  148. }
  149. @end