| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908 |
- /************************************************************
- * * 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 imageNamed:@"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 imageNamed:@"EaseUIResource.bundle/chatBar_record"] forState:UIControlStateNormal];
- [styleChangeButton setImage:[UIImage imageNamed:@"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 imageNamed:@"EaseUIResource.bundle/chatBar_recordBg"] stretchableImageWithLeftCapWidth:10 topCapHeight:10] forState:UIControlStateNormal];
- [self.recordButton setBackgroundImage:[[UIImage imageNamed:@"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 imageNamed:@"EaseUIResource.bundle/chatBar_face"] forState:UIControlStateNormal];
- [self.faceButton setImage:[UIImage imageNamed:@"EaseUIResource.bundle/chatBar_faceSelected"] forState:UIControlStateHighlighted];
- [self.faceButton setImage:[UIImage imageNamed:@"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 imageNamed:@"EaseUIResource.bundle/chatBar_more"] forState:UIControlStateNormal];
- [self.moreButton setImage:[UIImage imageNamed:@"EaseUIResource.bundle/chatBar_moreSelected"] forState:UIControlStateHighlighted];
- [self.moreButton setImage:[UIImage imageNamed:@"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];
- 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];
- }
- }
- #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
|