/************************************************************
|
* * Hyphenate CONFIDENTIAL
|
* __________________
|
* Copyright (C) 2016 Hyphenate Inc. All rights reserved.
|
*
|
* NOTICE: All information contained herein is, and remains
|
* the property of Hyphenate Inc.
|
* Dissemination of this information or reproduction of this material
|
* is strictly forbidden unless prior written permission is obtained
|
* from Hyphenate Inc.
|
*/
|
|
#import "EaseChatToolbar.h"
|
|
#import "EaseFaceView.h"
|
#import "EaseEmoji.h"
|
#import "EaseEmotionEscape.h"
|
#import "EaseEmotionManager.h"
|
#import "EaseLocalDefine.h"
|
|
@interface EaseChatToolbar()<UITextViewDelegate, EMFaceDelegate>
|
|
@property (nonatomic) CGFloat version;
|
@property (strong, nonatomic) NSMutableArray *leftItems;
|
@property (strong, nonatomic) NSMutableArray *rightItems;
|
@property (strong, nonatomic) UIImageView *toolbarBackgroundImageView;
|
@property (strong, nonatomic) UIImageView *backgroundImageView;
|
@property (nonatomic) BOOL isShowButtomView;
|
@property (strong, nonatomic) UIView *activityButtomView;
|
@property (strong, nonatomic) UIView *toolbarView;
|
@property (strong, nonatomic) UIButton *recordButton;
|
@property (strong, nonatomic) UIButton *moreButton;
|
@property (strong, nonatomic) UIButton *faceButton;
|
@property (nonatomic) CGFloat previousTextViewContentHeight;//上一次inputTextView的contentSize.height
|
@property (nonatomic) NSLayoutConstraint *inputViewWidthItemsLeftConstraint;
|
@property (nonatomic) NSLayoutConstraint *inputViewWidthoutItemsLeftConstraint;
|
|
@end
|
|
@implementation EaseChatToolbar
|
|
@synthesize faceView = _faceView;
|
@synthesize moreView = _moreView;
|
@synthesize recordView = _recordView;
|
|
- (instancetype)initWithFrame:(CGRect)frame
|
{
|
self = [self initWithFrame:frame horizontalPadding:8 verticalPadding:5 inputViewMinHeight:36 inputViewMaxHeight:150 type:EMChatToolbarTypeGroup];
|
if (self) {
|
|
}
|
|
return self;
|
}
|
|
- (instancetype)initWithFrame:(CGRect)frame
|
type:(EMChatToolbarType)type
|
{
|
self = [self initWithFrame:frame horizontalPadding:8 verticalPadding:5 inputViewMinHeight:36 inputViewMaxHeight:150 type:type];
|
if (self) {
|
|
}
|
|
return self;
|
}
|
|
- (instancetype)initWithFrame:(CGRect)frame
|
horizontalPadding:(CGFloat)horizontalPadding
|
verticalPadding:(CGFloat)verticalPadding
|
inputViewMinHeight:(CGFloat)inputViewMinHeight
|
inputViewMaxHeight:(CGFloat)inputViewMaxHeight
|
type:(EMChatToolbarType)type
|
{
|
if (frame.size.height < (verticalPadding * 2 + inputViewMinHeight)) {
|
frame.size.height = verticalPadding * 2 + inputViewMinHeight;
|
}
|
self = [super initWithFrame:frame];
|
if (self) {
|
self.accessibilityIdentifier = @"chatbar";
|
|
_horizontalPadding = horizontalPadding;
|
_verticalPadding = verticalPadding;
|
_inputViewMinHeight = inputViewMinHeight;
|
_inputViewMaxHeight = inputViewMaxHeight;
|
_chatBarType = type;
|
|
_leftItems = [NSMutableArray array];
|
_rightItems = [NSMutableArray array];
|
_version = [[[UIDevice currentDevice] systemVersion] floatValue];
|
_activityButtomView = nil;
|
_isShowButtomView = NO;
|
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(chatKeyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
|
|
[self _setupSubviews];
|
}
|
return self;
|
}
|
|
#pragma mark - setup subviews
|
|
/*!
|
@method
|
@brief 加载视图
|
@discussion
|
@result
|
*/
|
- (void)_setupSubviews
|
{
|
//backgroundImageView
|
_backgroundImageView = [[UIImageView alloc] initWithFrame:self.bounds];
|
_backgroundImageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
|
_backgroundImageView.backgroundColor = [UIColor clearColor];
|
_backgroundImageView.image = [[UIImage easeImageNamed:@"EaseUIResource.bundle/messageToolbarBg"] stretchableImageWithLeftCapWidth:0.5 topCapHeight:10];
|
[self addSubview:_backgroundImageView];
|
|
//toolbar
|
_toolbarView = [[UIView alloc] initWithFrame:self.bounds];
|
_toolbarView.backgroundColor = [UIColor clearColor];
|
[self addSubview:_toolbarView];
|
|
_toolbarBackgroundImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, _toolbarView.frame.size.width, _toolbarView.frame.size.height)];
|
_toolbarBackgroundImageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
|
_toolbarBackgroundImageView.backgroundColor = [UIColor clearColor];
|
[_toolbarView addSubview:_toolbarBackgroundImageView];
|
|
//input textview
|
_inputTextView = [[EaseTextView alloc] initWithFrame:CGRectMake(self.horizontalPadding, self.verticalPadding, self.frame.size.width - self.verticalPadding * 2, self.frame.size.height - self.verticalPadding * 2)];
|
_inputTextView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
|
_inputTextView.scrollEnabled = YES;
|
_inputTextView.returnKeyType = UIReturnKeySend;
|
_inputTextView.enablesReturnKeyAutomatically = YES; // UITextView内部判断send按钮是否可以用
|
_inputTextView.placeHolder = NSEaseLocalizedString(@"message.toolBar.inputPlaceHolder", @"input a new message");
|
_inputTextView.delegate = self;
|
_inputTextView.backgroundColor = [UIColor clearColor];
|
_inputTextView.layer.borderColor = [UIColor colorWithWhite:0.8f alpha:1.0f].CGColor;
|
_inputTextView.layer.borderWidth = 0.65f;
|
_inputTextView.layer.cornerRadius = 6.0f;
|
_previousTextViewContentHeight = [self _getTextViewContentH:_inputTextView];
|
[_toolbarView addSubview:_inputTextView];
|
|
//change input type
|
UIButton *styleChangeButton = [[UIButton alloc] init];
|
styleChangeButton.accessibilityIdentifier = @"style";
|
styleChangeButton.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
|
[styleChangeButton setImage:[UIImage easeImageNamed:@"EaseUIResource.bundle/chatBar_record"] forState:UIControlStateNormal];
|
[styleChangeButton setImage:[UIImage easeImageNamed:@"EaseUIResource.bundle/chatBar_keyboard"] forState:UIControlStateSelected];
|
[styleChangeButton addTarget:self action:@selector(styleButtonAction:) forControlEvents:UIControlEventTouchUpInside];
|
|
EaseChatToolbarItem *styleItem = [[EaseChatToolbarItem alloc] initWithButton:styleChangeButton withView:nil];
|
[self setInputViewLeftItems:@[styleItem]];
|
|
//record
|
self.recordButton = [[UIButton alloc] initWithFrame:self.inputTextView.frame];
|
self.recordButton.accessibilityIdentifier = @"record";
|
self.recordButton.titleLabel.font = [UIFont systemFontOfSize:15.0];
|
[self.recordButton setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal];
|
[self.recordButton setBackgroundImage:[[UIImage easeImageNamed:@"EaseUIResource.bundle/chatBar_recordBg"] stretchableImageWithLeftCapWidth:10 topCapHeight:10] forState:UIControlStateNormal];
|
[self.recordButton setBackgroundImage:[[UIImage easeImageNamed:@"EaseUIResource.bundle/chatBar_recordSelectedBg"] stretchableImageWithLeftCapWidth:10 topCapHeight:10] forState:UIControlStateHighlighted];
|
[self.recordButton setTitle:kTouchToRecord forState:UIControlStateNormal];
|
[self.recordButton setTitle:kTouchToFinish forState:UIControlStateHighlighted];
|
self.recordButton.hidden = YES;
|
[self.recordButton addTarget:self action:@selector(recordButtonTouchDown) forControlEvents:UIControlEventTouchDown];
|
[self.recordButton addTarget:self action:@selector(recordButtonTouchUpOutside) forControlEvents:UIControlEventTouchUpOutside];
|
[self.recordButton addTarget:self action:@selector(recordButtonTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
|
[self.recordButton addTarget:self action:@selector(recordDragOutside) forControlEvents:UIControlEventTouchDragExit];
|
[self.recordButton addTarget:self action:@selector(recordDragInside) forControlEvents:UIControlEventTouchDragEnter];
|
self.recordButton.hidden = YES;
|
[self.toolbarView addSubview:self.recordButton];
|
|
//emoji
|
self.faceButton = [[UIButton alloc] init];
|
self.faceButton.accessibilityIdentifier = @"face";
|
self.faceButton.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
|
[self.faceButton setImage:[UIImage easeImageNamed:@"EaseUIResource.bundle/chatBar_face"] forState:UIControlStateNormal];
|
[self.faceButton setImage:[UIImage easeImageNamed:@"EaseUIResource.bundle/chatBar_faceSelected"] forState:UIControlStateHighlighted];
|
[self.faceButton setImage:[UIImage easeImageNamed:@"EaseUIResource.bundle/chatBar_keyboard"] forState:UIControlStateSelected];
|
[self.faceButton addTarget:self action:@selector(faceButtonAction:) forControlEvents:UIControlEventTouchUpInside];
|
EaseChatToolbarItem *faceItem = [[EaseChatToolbarItem alloc] initWithButton:self.faceButton withView:self.faceView];
|
|
//more
|
self.moreButton = [[UIButton alloc] init];
|
self.moreButton.accessibilityIdentifier = @"more";
|
self.moreButton.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
|
[self.moreButton setImage:[UIImage easeImageNamed:@"EaseUIResource.bundle/chatBar_more"] forState:UIControlStateNormal];
|
[self.moreButton setImage:[UIImage easeImageNamed:@"EaseUIResource.bundle/chatBar_moreSelected"] forState:UIControlStateHighlighted];
|
[self.moreButton setImage:[UIImage easeImageNamed:@"EaseUIResource.bundle/chatBar_keyboard"] forState:UIControlStateSelected];
|
[self.moreButton addTarget:self action:@selector(moreButtonAction:) forControlEvents:UIControlEventTouchUpInside];
|
EaseChatToolbarItem *moreItem = [[EaseChatToolbarItem alloc] initWithButton:self.moreButton withView:self.moreView];
|
|
[self setInputViewRightItems:@[faceItem, moreItem]];
|
}
|
|
- (void)dealloc
|
{
|
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil];
|
|
_delegate = nil;
|
_inputTextView.delegate = nil;
|
_inputTextView = nil;
|
}
|
|
#pragma mark - getter
|
|
- (UIView *)recordView
|
{
|
if (_recordView == nil) {
|
_recordView = [[EaseRecordView alloc] initWithFrame:CGRectMake(90, 130, 140, 140)];
|
}
|
|
return _recordView;
|
}
|
|
- (UIView *)faceView
|
{
|
if (_faceView == nil) {
|
_faceView = [[EaseFaceView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(_toolbarView.frame), self.frame.size.width, 180)];
|
[(EaseFaceView *)_faceView setDelegate:self];
|
_faceView.backgroundColor = [UIColor colorWithRed:240 / 255.0 green:242 / 255.0 blue:247 / 255.0 alpha:1.0];
|
_faceView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
|
}
|
|
return _faceView;
|
}
|
|
- (UIView *)moreView
|
{
|
if (_moreView == nil) {
|
_moreView = [[EaseChatBarMoreView alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(_toolbarView.frame), self.frame.size.width, 80) type:self.chatBarType];
|
_moreView.backgroundColor = [UIColor colorWithRed:240 / 255.0 green:242 / 255.0 blue:247 / 255.0 alpha:1.0];
|
_moreView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
|
}
|
|
return _moreView;
|
}
|
|
#pragma mark - setter
|
|
- (void)setDelegate:(id)delegate
|
{
|
_delegate = delegate;
|
if ([_moreView isKindOfClass:[EaseChatBarMoreView class]]) {
|
[(EaseChatBarMoreView *)_moreView setDelegate:delegate];
|
}
|
}
|
|
- (void)setRecordView:(UIView *)recordView
|
{
|
if(_recordView != recordView){
|
_recordView = recordView;
|
}
|
}
|
|
- (void)setMoreView:(UIView *)moreView
|
{
|
if (_moreView != moreView) {
|
_moreView = moreView;
|
|
for (EaseChatToolbarItem *item in self.rightItems) {
|
if (item.button == self.moreButton) {
|
item.button2View = _moreView;
|
break;
|
}
|
}
|
}
|
}
|
|
- (void)setFaceView:(UIView *)faceView
|
{
|
if (_faceView != faceView) {
|
_faceView = faceView;
|
|
for (EaseChatToolbarItem *item in self.rightItems) {
|
if (item.button == self.faceButton) {
|
item.button2View = _faceView;
|
break;
|
}
|
}
|
}
|
}
|
|
- (NSArray*)inputViewLeftItems
|
{
|
return self.leftItems;
|
}
|
|
/*!
|
@method
|
@brief 设置toolBar左侧菜单选项
|
@discussion
|
@param inputViewLeftItems 左侧选项
|
@result
|
*/
|
- (void)setInputViewLeftItems:(NSArray *)inputViewLeftItems
|
{
|
for (EaseChatToolbarItem *item in self.leftItems) {
|
[item.button removeFromSuperview];
|
[item.button2View removeFromSuperview];
|
}
|
[self.leftItems removeAllObjects];
|
|
CGFloat oX = self.horizontalPadding;
|
CGFloat itemHeight = self.toolbarView.frame.size.height - self.verticalPadding * 2;
|
for (id item in inputViewLeftItems) {
|
if ([item isKindOfClass:[EaseChatToolbarItem class]]) {
|
EaseChatToolbarItem *chatItem = (EaseChatToolbarItem *)item;
|
if (chatItem.button) {
|
CGRect itemFrame = chatItem.button.frame;
|
if (itemFrame.size.height == 0) {
|
itemFrame.size.height = itemHeight;
|
}
|
|
if (itemFrame.size.width == 0) {
|
itemFrame.size.width = itemFrame.size.height;
|
}
|
|
itemFrame.origin.x = oX;
|
itemFrame.origin.y = (self.toolbarView.frame.size.height - itemFrame.size.height) / 2;
|
chatItem.button.frame = itemFrame;
|
oX += (itemFrame.size.width + self.horizontalPadding);
|
|
[self.toolbarView addSubview:chatItem.button];
|
[self.leftItems addObject:chatItem];
|
}
|
}
|
}
|
|
CGRect inputFrame = self.inputTextView.frame;
|
CGFloat value = inputFrame.origin.x - oX;
|
inputFrame.origin.x = oX;
|
inputFrame.size.width += value;
|
self.inputTextView.frame = inputFrame;
|
|
CGRect recordFrame = self.recordButton.frame;
|
recordFrame.origin.x = inputFrame.origin.x;
|
recordFrame.size.width = inputFrame.size.width;
|
self.recordButton.frame = recordFrame;
|
}
|
|
- (NSArray*)inputViewRightItems
|
{
|
return self.rightItems;
|
}
|
|
/*!
|
@method
|
@brief 设置toolBar右侧菜单选项
|
@discussion
|
@param inputViewLeftItems 右侧选项
|
@result
|
*/
|
- (void)setInputViewRightItems:(NSArray *)inputViewRightItems
|
{
|
for (EaseChatToolbarItem *item in self.rightItems) {
|
[item.button removeFromSuperview];
|
[item.button2View removeFromSuperview];
|
}
|
[self.rightItems removeAllObjects];
|
|
CGFloat oMaxX = self.toolbarView.frame.size.width - self.horizontalPadding;
|
CGFloat itemHeight = self.toolbarView.frame.size.height - self.verticalPadding * 2;
|
if ([inputViewRightItems count] > 0) {
|
for (NSInteger i = (inputViewRightItems.count - 1); i >= 0; i--) {
|
id item = [inputViewRightItems objectAtIndex:i];
|
if ([item isKindOfClass:[EaseChatToolbarItem class]]) {
|
EaseChatToolbarItem *chatItem = (EaseChatToolbarItem *)item;
|
if (chatItem.button) {
|
CGRect itemFrame = chatItem.button.frame;
|
if (itemFrame.size.height == 0) {
|
itemFrame.size.height = itemHeight;
|
}
|
|
if (itemFrame.size.width == 0) {
|
itemFrame.size.width = itemFrame.size.height;
|
}
|
|
oMaxX -= itemFrame.size.width;
|
itemFrame.origin.x = oMaxX;
|
itemFrame.origin.y = (self.toolbarView.frame.size.height - itemFrame.size.height) / 2;
|
chatItem.button.frame = itemFrame;
|
oMaxX -= self.horizontalPadding;
|
|
[self.toolbarView addSubview:chatItem.button];
|
[self.rightItems addObject:item];
|
}
|
}
|
}
|
}
|
|
CGRect inputFrame = self.inputTextView.frame;
|
CGFloat value = oMaxX - CGRectGetMaxX(inputFrame);
|
inputFrame.size.width += value;
|
self.inputTextView.frame = inputFrame;
|
|
CGRect recordFrame = self.recordButton.frame;
|
recordFrame.origin.x = inputFrame.origin.x;
|
recordFrame.size.width = inputFrame.size.width;
|
self.recordButton.frame = recordFrame;
|
}
|
|
#pragma mark - private input view
|
|
/*!
|
@method
|
@brief 获取textView的高度(实际为textView的contentSize的高度)
|
@discussion
|
@param textView 文本框
|
@result
|
*/
|
- (CGFloat)_getTextViewContentH:(UITextView *)textView
|
{
|
if (self.version >= 7.0)
|
{
|
return ceilf([textView sizeThatFits:textView.frame.size].height);
|
} else {
|
return textView.contentSize.height;
|
}
|
}
|
|
/*!
|
@method
|
@brief 通过传入的toHeight,跳转toolBar的高度
|
@discussion
|
@param toHeight
|
@result
|
*/
|
- (void)_willShowInputTextViewToHeight:(CGFloat)toHeight
|
{
|
if (toHeight < self.inputViewMinHeight) {
|
toHeight = self.inputViewMinHeight;
|
}
|
if (toHeight > self.inputViewMaxHeight) {
|
toHeight = self.inputViewMaxHeight;
|
}
|
|
if (toHeight == _previousTextViewContentHeight)
|
{
|
return;
|
}
|
else{
|
CGFloat changeHeight = toHeight - _previousTextViewContentHeight;
|
|
CGRect rect = self.frame;
|
rect.size.height += changeHeight;
|
rect.origin.y -= changeHeight;
|
self.frame = rect;
|
|
rect = self.toolbarView.frame;
|
rect.size.height += changeHeight;
|
self.toolbarView.frame = rect;
|
|
if (self.version < 7.0) {
|
[self.inputTextView setContentOffset:CGPointMake(0.0f, (self.inputTextView.contentSize.height - self.inputTextView.frame.size.height) / 2) animated:YES];
|
}
|
_previousTextViewContentHeight = toHeight;
|
|
if (_delegate && [_delegate respondsToSelector:@selector(chatToolbarDidChangeFrameToHeight:)]) {
|
[_delegate chatToolbarDidChangeFrameToHeight:self.frame.size.height];
|
}
|
}
|
}
|
|
#pragma mark - private bottom view
|
|
/*!
|
@method
|
@brief 调整toolBar的高度
|
@discussion
|
@param bottomHeight 底部菜单的高度
|
@result
|
*/
|
- (void)_willShowBottomHeight:(CGFloat)bottomHeight
|
{
|
CGRect fromFrame = self.frame;
|
CGFloat toHeight = self.toolbarView.frame.size.height + bottomHeight;
|
CGRect toFrame = CGRectMake(fromFrame.origin.x, fromFrame.origin.y + (fromFrame.size.height - toHeight), fromFrame.size.width, toHeight);
|
|
if(bottomHeight == 0 && self.frame.size.height == self.toolbarView.frame.size.height)
|
{
|
return;
|
}
|
|
if (bottomHeight == 0) {
|
self.isShowButtomView = NO;
|
}
|
else{
|
self.isShowButtomView = YES;
|
}
|
|
self.frame = toFrame;
|
|
if (_delegate && [_delegate respondsToSelector:@selector(chatToolbarDidChangeFrameToHeight:)]) {
|
[_delegate chatToolbarDidChangeFrameToHeight:toHeight];
|
}
|
}
|
|
/*!
|
@method
|
@brief 切换菜单视图
|
@discussion
|
@param bottomView 菜单视图
|
@result
|
*/
|
- (void)_willShowBottomView:(UIView *)bottomView
|
{
|
if (![self.activityButtomView isEqual:bottomView]) {
|
CGFloat bottomHeight = bottomView ? bottomView.frame.size.height : 0;
|
[self _willShowBottomHeight:bottomHeight];
|
|
if (bottomView) {
|
CGRect rect = bottomView.frame;
|
rect.origin.y = CGRectGetMaxY(self.toolbarView.frame);
|
bottomView.frame = rect;
|
[self addSubview:bottomView];
|
}
|
|
if (self.activityButtomView) {
|
[self.activityButtomView removeFromSuperview];
|
}
|
self.activityButtomView = bottomView;
|
}
|
}
|
|
- (void)_willShowKeyboardFromFrame:(CGRect)beginFrame toFrame:(CGRect)toFrame
|
{
|
if (beginFrame.origin.y == [[UIScreen mainScreen] bounds].size.height)
|
{
|
[self _willShowBottomHeight:toFrame.size.height - iPhoneX_BOTTOM_HEIGHT];
|
if (self.activityButtomView) {
|
[self.activityButtomView removeFromSuperview];
|
}
|
self.activityButtomView = nil;
|
}
|
else if (toFrame.origin.y == [[UIScreen mainScreen] bounds].size.height)
|
{
|
[self _willShowBottomHeight:0];
|
}
|
else{
|
[self _willShowBottomHeight:toFrame.size.height - iPhoneX_BOTTOM_HEIGHT];
|
}
|
}
|
|
#pragma mark - UITextViewDelegate
|
|
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
|
{
|
if ([self.delegate respondsToSelector:@selector(inputTextViewWillBeginEditing:)]) {
|
[self.delegate inputTextViewWillBeginEditing:self.inputTextView];
|
}
|
|
for (EaseChatToolbarItem *item in self.leftItems) {
|
item.button.selected = NO;
|
}
|
|
for (EaseChatToolbarItem *item in self.rightItems) {
|
item.button.selected = NO;
|
}
|
|
return YES;
|
}
|
|
- (void)textViewDidBeginEditing:(UITextView *)textView
|
{
|
[textView becomeFirstResponder];
|
|
if ([self.delegate respondsToSelector:@selector(inputTextViewDidBeginEditing:)]) {
|
[self.delegate inputTextViewDidBeginEditing:self.inputTextView];
|
}
|
}
|
|
- (void)textViewDidEndEditing:(UITextView *)textView
|
{
|
[textView resignFirstResponder];
|
}
|
|
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
|
{
|
if ([text isEqualToString:@"\n"]) {
|
if ([self.delegate respondsToSelector:@selector(didSendText:)]) {
|
[self.delegate didSendText:textView.text];
|
self.inputTextView.text = @"";
|
[self _willShowInputTextViewToHeight:[self _getTextViewContentH:self.inputTextView]];
|
}
|
|
return NO;
|
}
|
else if ([text isEqualToString:@"@"]) {
|
if ([self.delegate respondsToSelector:@selector(didInputAtInLocation:)]) {
|
if ([self.delegate didInputAtInLocation:range.location]) {
|
[self _willShowInputTextViewToHeight:[self _getTextViewContentH:self.inputTextView]];
|
return NO;
|
}
|
}
|
}
|
else if ([text length] == 0) {
|
//delete one character
|
if (range.length == 1 && [self.delegate respondsToSelector:@selector(didDeleteCharacterFromLocation:)]) {
|
return ![self.delegate didDeleteCharacterFromLocation:range.location];
|
}
|
}
|
return YES;
|
}
|
|
- (void)textViewDidChange:(UITextView *)textView
|
{
|
[self _willShowInputTextViewToHeight:[self _getTextViewContentH:textView]];
|
}
|
|
#pragma mark - DXFaceDelegate
|
|
- (void)selectedFacialView:(NSString *)str isDelete:(BOOL)isDelete
|
{
|
NSString *chatText = self.inputTextView.text;
|
|
NSMutableAttributedString *attr = [[NSMutableAttributedString alloc] initWithAttributedString:self.inputTextView.attributedText];
|
|
if (!isDelete && str.length > 0) {
|
if (self.version >= 7.0) {
|
NSRange range = [self.inputTextView selectedRange];
|
[attr insertAttributedString:[[EaseEmotionEscape sharedInstance] attStringFromTextForInputView:str textFont:self.inputTextView.font] atIndex:range.location];
|
self.inputTextView.attributedText = attr;
|
} else {
|
self.inputTextView.text = @"";
|
self.inputTextView.text = [NSString stringWithFormat:@"%@%@",chatText,str];
|
}
|
}
|
else {
|
if (self.version >= 7.0) {
|
if (chatText.length > 0) {
|
NSInteger length = 1;
|
if (chatText.length >= 2) {
|
NSString *subStr = [chatText substringFromIndex:chatText.length-2];
|
if ([EaseEmoji stringContainsEmoji:subStr]) {
|
length = 2;
|
}
|
}
|
self.inputTextView.attributedText = [self backspaceText:attr length:length];
|
}
|
} else {
|
if (chatText.length >= 2)
|
{
|
NSString *subStr = [chatText substringFromIndex:chatText.length-2];
|
if ([(EaseFaceView *)self.faceView stringIsFace:subStr]) {
|
self.inputTextView.text = [chatText substringToIndex:chatText.length-2];
|
[self textViewDidChange:self.inputTextView];
|
return;
|
}
|
}
|
|
if (chatText.length > 0) {
|
self.inputTextView.text = [chatText substringToIndex:chatText.length-1];
|
}
|
}
|
}
|
|
[self textViewDidChange:self.inputTextView];
|
}
|
|
/*!
|
@method
|
@brief 删除文本光标前长度为length的字符串
|
@discussion
|
@param attr 待修改的富文本
|
@param length 字符串长度
|
@result 修改后的富文本
|
*/
|
-(NSMutableAttributedString*)backspaceText:(NSMutableAttributedString*) attr length:(NSInteger)length
|
{
|
NSRange range = [self.inputTextView selectedRange];
|
if (range.location == 0) {
|
return attr;
|
}
|
[attr deleteCharactersInRange:NSMakeRange(range.location - length, length)];
|
return attr;
|
}
|
|
- (void)sendFace
|
{
|
NSString *chatText = self.inputTextView.text;
|
if (chatText.length > 0) {
|
if ([self.delegate respondsToSelector:@selector(didSendText:)]) {
|
|
if (![_inputTextView.text isEqualToString:@""]) {
|
|
//转义回来
|
NSMutableString *attStr = [[NSMutableString alloc] initWithString:self.inputTextView.attributedText.string];
|
[_inputTextView.attributedText enumerateAttribute:NSAttachmentAttributeName
|
inRange:NSMakeRange(0, self.inputTextView.attributedText.length)
|
options:NSAttributedStringEnumerationReverse
|
usingBlock:^(id value, NSRange range, BOOL *stop)
|
{
|
if (value) {
|
EMTextAttachment* attachment = (EMTextAttachment*)value;
|
NSString *str = [NSString stringWithFormat:@"%@",attachment.imageName];
|
[attStr replaceCharactersInRange:range withString:str];
|
}
|
}];
|
[self.delegate didSendText:attStr];
|
self.inputTextView.text = @"";
|
[self _willShowInputTextViewToHeight:[self _getTextViewContentH:self.inputTextView]];;
|
}
|
}
|
}
|
}
|
|
- (void)sendFaceWithEmotion:(EaseEmotion *)emotion
|
{
|
if (emotion) {
|
if ([self.delegate respondsToSelector:@selector(didSendText:withExt:)]) {
|
[self.delegate didSendText:emotion.emotionTitle withExt:@{EASEUI_EMOTION_DEFAULT_EXT:emotion}];
|
[self _willShowInputTextViewToHeight:[self _getTextViewContentH:self.inputTextView]];;
|
}
|
}
|
}
|
|
#pragma mark - UIKeyboardNotification
|
|
- (void)chatKeyboardWillChangeFrame:(NSNotification *)notification
|
{
|
NSDictionary *userInfo = notification.userInfo;
|
CGRect endFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
|
CGRect beginFrame = [userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
|
CGFloat duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
|
UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
|
|
void(^animations)() = ^{
|
[self _willShowKeyboardFromFrame:beginFrame toFrame:endFrame];
|
};
|
|
[UIView animateWithDuration:duration delay:0.0f options:(curve << 16 | UIViewAnimationOptionBeginFromCurrentState) animations:animations completion:nil];
|
}
|
|
#pragma mark - action
|
|
- (void)styleButtonAction:(id)sender
|
{
|
UIButton *button = (UIButton *)sender;
|
button.selected = !button.selected;
|
if (button.selected) {
|
for (EaseChatToolbarItem *item in self.rightItems) {
|
item.button.selected = NO;
|
}
|
|
for (EaseChatToolbarItem *item in self.leftItems) {
|
if (item.button != button) {
|
item.button.selected = NO;
|
}
|
}
|
|
[self _willShowBottomView:nil];
|
|
self.inputTextView.text = @"";
|
[self textViewDidChange:self.inputTextView];
|
[self.inputTextView resignFirstResponder];
|
}
|
else{
|
[self.inputTextView becomeFirstResponder];
|
}
|
|
[UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
self.recordButton.hidden = !button.selected;
|
self.inputTextView.hidden = button.selected;
|
} completion:nil];
|
}
|
|
- (void)faceButtonAction:(id)sender
|
{
|
UIButton *button = (UIButton *)sender;
|
button.selected = !button.selected;
|
|
EaseChatToolbarItem *faceItem = nil;
|
for (EaseChatToolbarItem *item in self.rightItems) {
|
if (item.button == button){
|
faceItem = item;
|
continue;
|
}
|
|
item.button.selected = NO;
|
}
|
|
for (EaseChatToolbarItem *item in self.leftItems) {
|
item.button.selected = NO;
|
}
|
|
if (button.selected) {
|
[self.inputTextView resignFirstResponder];
|
|
[self _willShowBottomView:faceItem.button2View];
|
[UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
self.recordButton.hidden = button.selected;
|
self.inputTextView.hidden = !button.selected;
|
} completion:^(BOOL finished) {
|
|
}];
|
} else {
|
[self.inputTextView becomeFirstResponder];
|
}
|
}
|
|
- (void)moreButtonAction:(id)sender
|
{
|
UIButton *button = (UIButton *)sender;
|
button.selected = !button.selected;
|
|
EaseChatToolbarItem *moreItem = nil;
|
for (EaseChatToolbarItem *item in self.rightItems) {
|
if (item.button == button){
|
moreItem = item;
|
continue;
|
}
|
|
item.button.selected = NO;
|
}
|
|
for (EaseChatToolbarItem *item in self.leftItems) {
|
item.button.selected = NO;
|
}
|
|
if (button.selected) {
|
[self.inputTextView resignFirstResponder];
|
|
[self _willShowBottomView:moreItem.button2View];
|
[UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
|
self.recordButton.hidden = button.selected;
|
self.inputTextView.hidden = !button.selected;
|
} completion:nil];
|
}
|
else
|
{
|
[self.inputTextView becomeFirstResponder];
|
}
|
}
|
|
- (void)recordButtonTouchDown
|
{
|
if (_delegate && [_delegate respondsToSelector:@selector(didStartRecordingVoiceAction:)]) {
|
[_delegate didStartRecordingVoiceAction:self.recordView];
|
}
|
}
|
|
- (void)recordButtonTouchUpOutside
|
{
|
if (_delegate && [_delegate respondsToSelector:@selector(didCancelRecordingVoiceAction:)])
|
{
|
[_delegate didCancelRecordingVoiceAction:self.recordView];
|
}
|
}
|
|
- (void)recordButtonTouchUpInside
|
{
|
self.recordButton.enabled = NO;
|
if ([self.delegate respondsToSelector:@selector(didFinishRecoingVoiceAction:)])
|
{
|
[self.delegate didFinishRecoingVoiceAction:self.recordView];
|
}
|
self.recordButton.enabled = YES;
|
}
|
|
- (void)recordDragOutside
|
{
|
if ([self.delegate respondsToSelector:@selector(didDragOutsideAction:)])
|
{
|
[self.delegate didDragOutsideAction:self.recordView];
|
}
|
}
|
|
- (void)recordDragInside
|
{
|
if ([self.delegate respondsToSelector:@selector(didDragInsideAction:)])
|
{
|
[self.delegate didDragInsideAction:self.recordView];
|
}
|
}
|
|
#pragma mark - public
|
|
+ (CGFloat)defaultHeight
|
{
|
return 5 * 2 + 36;
|
}
|
|
- (BOOL)endEditing:(BOOL)force
|
{
|
BOOL result = [super endEditing:force];
|
|
for (EaseChatToolbarItem *item in self.rightItems) {
|
item.button.selected = NO;
|
}
|
[self _willShowBottomView:nil];
|
|
return result;
|
}
|
|
- (void)cancelTouchRecord
|
{
|
if ([_recordView isKindOfClass:[EaseRecordView class]]) {
|
[(EaseRecordView *)_recordView recordButtonTouchUpInside];
|
[_recordView removeFromSuperview];
|
}
|
}
|
|
- (void)willShowBottomView:(UIView *)bottomView
|
{
|
[self _willShowBottomView:bottomView];
|
}
|
|
@end
|