cdts/xdts-ios 3/TreeHole/CYHResetCode/CYH/QMUIKit/QMUIComponents/QMUIEmotionInputManager.m

143 lines
7.5 KiB
Mathematica
Raw Normal View History

2023-07-27 09:20:00 +08:00
/**
* Tencent is pleased to support the open source community by making QMUI_iOS available.
* Copyright (C) 2016-2021 THL A29 Limited, a Tencent company. All rights reserved.
* Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
* http://opensource.org/licenses/MIT
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/
//
// QMUIEmotionInputManager.m
// qmui
//
// Created by QMUI Team on 16/9/8.
//
#import "QMUIEmotionInputManager.h"
#import "QMUICore.h"
#import "NSString+QMUI.h"
#import "QMUIEmotionView.h"
@protocol QMUIEmotionInputViewProtocol <UITextInput>
@property(nonatomic, copy) NSString *text;
@property(nonatomic, assign, readonly) NSRange selectedRange;
@end
@implementation QMUIEmotionInputManager
- (instancetype)init {
self = [super init];
if (self) {
_emotionView = [[QMUIEmotionView alloc] init];
__weak QMUIEmotionInputManager *weakSelf = self;
self.emotionView.didSelectEmotionBlock = ^(NSInteger index, QMUIEmotion *emotion) {
if (!weakSelf.boundInputView) return;
NSString *inputText = weakSelf.boundInputView.text;
// selectedRangeForBoundTextInputself.selectedRangeForBoundTextInput
NSRange selectedRange = weakSelf.selectedRangeForBoundTextInput;
if (selectedRange.location <= inputText.length) {
//
NSMutableString *mutableText = [NSMutableString stringWithString:inputText ?: @""];
[mutableText insertString:emotion.displayName atIndex:selectedRange.location];
weakSelf.boundInputView.text = mutableText;// UITextView setText:textViewDidChangeSelection:delegateself.selectedRangeForBoundTextInput
selectedRange = NSMakeRange(selectedRange.location + emotion.displayName.length, 0);
} else {
//
inputText = [inputText stringByAppendingString:emotion.displayName];
weakSelf.boundInputView.text = inputText;
selectedRange = NSMakeRange(weakSelf.boundInputView.text.length, 0);// boundInputView.text setText: maximumTextLength
}
weakSelf.selectedRangeForBoundTextInput = selectedRange;
};
self.emotionView.didSelectDeleteButtonBlock = ^{
[weakSelf deleteEmotionDisplayNameAtCurrentSelectedRangeForce:YES];
};
}
return self;
}
- (UIView<QMUIEmotionInputViewProtocol> *)boundInputView {
if (self.boundTextField) {
return (UIView<QMUIEmotionInputViewProtocol> *)self.boundTextField;
} else if (self.boundTextView) {
return (UIView<QMUIEmotionInputViewProtocol> *)self.boundTextView;
}
return nil;
}
- (BOOL)deleteEmotionDisplayNameAtCurrentSelectedRangeForce:(BOOL)forceDelete {
if (!self.boundInputView) return NO;
NSRange selectedRange = self.selectedRangeForBoundTextInput;
NSString *text = self.boundInputView.text;
//
if (!text.length || NSMaxRange(selectedRange) == 0) {
return NO;
}
BOOL hasDeleteEmotionDisplayNameSuccess = NO;
NSString *exampleEmotionDisplayName = self.emotionView.emotions.firstObject.displayName;
NSString *emotionDisplayNameLeftSign = exampleEmotionDisplayName ? [exampleEmotionDisplayName substringWithRange:NSMakeRange(0, 1)] : nil;
NSString *emotionDisplayNameRightSign = exampleEmotionDisplayName ? [exampleEmotionDisplayName substringWithRange:NSMakeRange(exampleEmotionDisplayName.length - 1, 1)] : nil;
NSInteger emotionDisplayNameMinimumLength = 3;// displayName[x]
NSInteger lengthForStringBeforeSelectedRange = selectedRange.location;
NSString *lastCharacterBeforeSelectedRange = [text substringWithRange:NSMakeRange(selectedRange.location - 1, 1)];
if ([lastCharacterBeforeSelectedRange isEqualToString:emotionDisplayNameRightSign] && lengthForStringBeforeSelectedRange >= emotionDisplayNameMinimumLength) {
NSInteger beginIndex = lengthForStringBeforeSelectedRange - (emotionDisplayNameMinimumLength - 1);// "]"n
NSInteger endIndex = MAX(0, lengthForStringBeforeSelectedRange - 5);// "]"n5displayName
for (NSInteger i = beginIndex; i >= endIndex; i --) {
NSString *checkingCharacter = [text substringWithRange:NSMakeRange(i, 1)];
if ([checkingCharacter isEqualToString:emotionDisplayNameRightSign]) {
// "[""]"
break;
}
if ([checkingCharacter isEqualToString:emotionDisplayNameLeftSign]) {
NSRange deletingDisplayNameRange = NSMakeRange(i, lengthForStringBeforeSelectedRange - i);
self.boundInputView.text = [text stringByReplacingCharactersInRange:deletingDisplayNameRange withString:@""];
self.selectedRangeForBoundTextInput = NSMakeRange(deletingDisplayNameRange.location, 0);
hasDeleteEmotionDisplayNameSuccess = YES;
break;
}
}
}
if (hasDeleteEmotionDisplayNameSuccess) {
return YES;
}
if (forceDelete) {
if (NSMaxRange(selectedRange) <= text.length) {
if (selectedRange.length > 0) {
//
self.boundInputView.text = [text stringByReplacingCharactersInRange:selectedRange withString:@""];
self.selectedRangeForBoundTextInput = NSMakeRange(selectedRange.location, 0);
} else if (selectedRange.location > 0) {
//
NSString *textAfterDelete = [text qmui_stringByRemoveCharacterAtIndex:selectedRange.location - 1];
self.boundInputView.text = textAfterDelete;
self.selectedRangeForBoundTextInput = NSMakeRange(selectedRange.location - (text.length - textAfterDelete.length), 0);
}
} else {
//
self.boundInputView.text = [text qmui_stringByRemoveLastCharacter];
self.selectedRangeForBoundTextInput = NSMakeRange(self.boundInputView.text.length, 0);
}
return YES;
}
return NO;
}
- (BOOL)shouldTakeOverControlDeleteKeyWithChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
BOOL isDeleteKeyPressed = text.length == 0 && self.boundInputView.text.length - 1 == range.location;
BOOL hasMarkedText = !!self.boundInputView.markedTextRange;
return isDeleteKeyPressed && !hasMarkedText;
}
@end