### 需求:1. textView 需要placeholder用來提示輸入2. textView 要做字數限制 3. textView 禁止表情符號的輸入### 思考:因為需求比較通用,便想通過自定義SJTextView來實現:1. placeholder 通過在textView上添加一個透明的l... ...
### 需求: 1. textView 需要placeholder用來提示輸入 2. textView 要做字數限制 3. textView 禁止表情符號的輸入 ### 思考: 因為需求比較通用,便想通過自定義SJTextView來實現: 1. placeholder 通過在textView上添加一個透明的label,輸入開始後隱藏實現。 2. 字數限制可以在代理方法中實現,字數達到最大後禁止輸入 3. 表情符號禁止輸入(這個不常用,因為我們伺服器不接收,於是做了限制輸入),用了github中 [SearchEmojiOnString-iOS](https://github.com/GabrielMassana/SearchEmojiOnString-iOS) 關於表情的 NSString+EMOEmoji 可以很方便實現 問題:如果在自定義SJTextView時使用了UITextView的代理方法,如果在使用這個自定義的TextView中再使用代理方法,就會覆蓋SJTextView中的代理方法。 解決:UITextVeiw 給了三種編輯狀態 `UITextViewTextDidBeginEditingNotification UITextViewTextDidChangeNotification UITextViewTextDidEndEditingNotification` 可以通過監聽 UITextViewTextDidChangeNotification 來對textView進行處理。 ### 實現: #### 添加外部屬性 ``` /** 占位字元串 */ @property (nonatomic, strong) NSString *placeholder; /** 占位字元串顏色 */ @property (nonatomic, strong) UIColor *placeholderColor; /** 字元串長度限制 */ @property (nonatomic, assign) NSUInteger limitedLength; /** 是否機制字表情符號的輸入 */ @property (nonatomic, assign) BOOL emojiDisable; ``` #### 添加方法 ##### 1. 添加占位字元label ``` /** 占位字元串 @param placeholder 占位字元串 */ - (void)setPlaceholder:(NSString *)placeholder { if (placeholder) { _placeholder = placeholder; self.placeholderLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 8, self.frame.size.width - 10, 0)]; self.placeholderLabel.numberOfLines = 0; self.placeholderLabel.text = placeholder; self.placeholderLabel.textColor = [UIColor lightGrayColor]; self.placeholderLabel.font = [UIFont systemFontOfSize:13]; // UITextView 預設的字體大小為13 [self adjustLabelFrameHeight:self.placeholderLabel]; // placeholder適應高度 [self addSubview:self.placeholderLabel]; } } ``` ##### 2. 限製表情符號輸入 ``` /** 限製表情符號的輸入 需要引入 NSString+EMOEmoji 分類,也可以把方法複製過來 */ - (void)disableEmoji { if([self.text emo_containsEmoji]) { // emo_disableEmoji 方法是,在 NSString+EMOEmoji中改寫了一個方法,具體看代碼 [self setText:[self.text emo_disableEmoji]]; } } ``` ##### 3. 添加字元長度限制 ``` // 給SJTextView添加一個屬性 記錄上一次最後顯示在textView中的字元串的內部屬性, 是完成字元串長度限制的關鍵 // 最後一次顯示在textView中的符合限制字元串 @property (nonatomic, strong) NSString *lastText; // 初始化時,添加監聽 [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(textViewEditChanged) name:UITextViewTextDidChangeNotification object:self]; // 監聽方法實現 - (void)textViewEditChanged { // ----- placeholderLabel 的顯示與隱藏 ----- if (self.text.length == 0) { [self.placeholderLabel setHidden:NO]; } else { [self.placeholderLabel setHidden:YES]; } // ----- 禁止輸入表情符號 ----- if (self.emojiDisable) { [self disableEmoji]; } // ----- 字數限制 ----- // 獲取高亮部分 UITextRange *selectedRange = [self markedTextRange]; UITextPosition *pos = [self positionFromPosition:selectedRange.start offset:0]; // 如果輸入的字還可以變化,就不做限制,self.lastText也不會記錄還在變化狀態的文字 if (selectedRange && pos) { return; } if (self.text.length > self.lastText.length) { NSString *newInputText = [self.text substringFromIndex:self.lastText.length]; NSUInteger canInputLength = self.limitedLength - self.lastText.length; // 如果長度超出了可輸入長度,還原為上次輸入的字元串,也就是說如果你是複製的一大段文字,長度超過了可輸入的長度,這段文字一個字都不會輸入到TextView中(你要重新編輯好了再重新粘貼,輸入一部分,還是要刪除的) if (newInputText.length > canInputLength || canInputLength == 0) { [self setText:self.lastText]; // 這裡給出提示,輸入超過了限制 NSLog(@"%@",[NSString stringWithFormat:@"字數不能超過%lu個。",(unsigned long)self.limitedLength]); } } self.lastText = self.text; } ```