No Description

DXMessageToolBar.m 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. /************************************************************
  2. * * EaseMob CONFIDENTIAL
  3. * __________________
  4. * Copyright (C) 2013-2014 EaseMob Technologies. All rights reserved.
  5. *
  6. * NOTICE: All information contained herein is, and remains
  7. * the property of EaseMob Technologies.
  8. * Dissemination of this information or reproduction of this material
  9. * is strictly forbidden unless prior written permission is obtained
  10. * from EaseMob Technologies.
  11. */
  12. #import "DXMessageToolBar.h"
  13. @interface DXMessageToolBar()<UITextViewDelegate, DXFaceDelegate, DXChatBarMoreViewDelegate>
  14. {
  15. CGFloat _previousTextViewContentHeight;//上一次inputTextView的contentSize.height
  16. }
  17. @property (nonatomic) CGFloat version;
  18. /**
  19. * 背景
  20. */
  21. @property (strong, nonatomic) UIImageView *toolbarBackgroundImageView;
  22. @property (strong, nonatomic) UIImageView *backgroundImageView;
  23. /**
  24. * 按钮、输入框、toolbarView
  25. */
  26. @property (strong, nonatomic) UIView *toolbarView;
  27. @property (strong, nonatomic) UIButton *styleChangeButton;
  28. @property (strong, nonatomic) UIButton *moreButton;
  29. @property (strong, nonatomic) UIButton *faceButton;
  30. @property (strong, nonatomic) UIButton *recordButton;
  31. @property (strong, nonatomic) UIButton *sendButton;
  32. /**
  33. * 底部扩展页面
  34. */
  35. @property (nonatomic) BOOL isShowButtomView;
  36. @property (strong, nonatomic) UIView *activityButtomView;//当前活跃的底部扩展页面
  37. @end
  38. @implementation DXMessageToolBar
  39. - (instancetype)initWithFrame:(CGRect)frame
  40. {
  41. if (frame.size.height < (kVerticalPadding * 2 + kInputTextViewMinHeight)) {
  42. frame.size.height = kVerticalPadding * 2 + kInputTextViewMinHeight;
  43. }
  44. self = [super initWithFrame:frame];
  45. if (self) {
  46. // Initialization code
  47. [self setupConfigure];
  48. }
  49. return self;
  50. }
  51. - (void)setFrame:(CGRect)frame
  52. {
  53. if (frame.size.height < (kVerticalPadding * 2 + kInputTextViewMinHeight)) {
  54. frame.size.height = kVerticalPadding * 2 + kInputTextViewMinHeight;
  55. }
  56. [super setFrame:frame];
  57. }
  58. - (void)willMoveToSuperview:(UIView *)newSuperview
  59. {
  60. // 当别的地方需要add的时候,就会调用这里
  61. if (newSuperview) {
  62. [self setupSubviews];
  63. }
  64. [super willMoveToSuperview:newSuperview];
  65. }
  66. - (void)didMoveToSuperview
  67. {
  68. [super didMoveToSuperview];
  69. }
  70. - (void)dealloc
  71. {
  72. [self removeKeyboardEvent];
  73. _delegate = nil;
  74. _inputTextView.delegate = nil;
  75. _inputTextView = nil;
  76. }
  77. #pragma mark - getter
  78. - (UIImageView *)backgroundImageView
  79. {
  80. if (_backgroundImageView == nil) {
  81. _backgroundImageView = [[UIImageView alloc] initWithFrame:self.bounds];
  82. _backgroundImageView.backgroundColor = [UIColor clearColor];
  83. _backgroundImageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
  84. }
  85. return _backgroundImageView;
  86. }
  87. - (UIImageView *)toolbarBackgroundImageView
  88. {
  89. if (_toolbarBackgroundImageView == nil) {
  90. _toolbarBackgroundImageView = [[UIImageView alloc] init];
  91. _toolbarBackgroundImageView.backgroundColor = [UIColor clearColor];
  92. _toolbarBackgroundImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  93. }
  94. return _toolbarBackgroundImageView;
  95. }
  96. - (UIView *)toolbarView
  97. {
  98. if (_toolbarView == nil) {
  99. _toolbarView = [[UIView alloc] init];
  100. _toolbarView.backgroundColor = [UIColor clearColor];
  101. }
  102. return _toolbarView;
  103. }
  104. #pragma mark - setter
  105. - (void)setBackgroundImage:(UIImage *)backgroundImage
  106. {
  107. _backgroundImage = backgroundImage;
  108. self.backgroundImageView.image = backgroundImage;
  109. }
  110. - (void)setToolbarBackgroundImage:(UIImage *)toolbarBackgroundImage
  111. {
  112. _toolbarBackgroundImage = toolbarBackgroundImage;
  113. self.toolbarBackgroundImageView.image = toolbarBackgroundImage;
  114. }
  115. - (void)setMaxTextInputViewHeight:(CGFloat)maxTextInputViewHeight
  116. {
  117. if (maxTextInputViewHeight > kInputTextViewMaxHeight) {
  118. maxTextInputViewHeight = kInputTextViewMaxHeight;
  119. }
  120. _maxTextInputViewHeight = maxTextInputViewHeight;
  121. }
  122. #pragma mark - UITextViewDelegate
  123. - (BOOL)textViewShouldBeginEditing:(UITextView *)textView
  124. {
  125. if ([self.delegate respondsToSelector:@selector(inputTextViewWillBeginEditing:)]) {
  126. [self.delegate inputTextViewWillBeginEditing:self.inputTextView];
  127. }
  128. self.faceButton.selected = NO;
  129. self.styleChangeButton.selected = NO;
  130. self.moreButton.selected = NO;
  131. return YES;
  132. }
  133. - (void)textViewDidBeginEditing:(UITextView *)textView
  134. {
  135. [textView becomeFirstResponder];
  136. if ([self.delegate respondsToSelector:@selector(inputTextViewDidBeginEditing:)]) {
  137. [self.delegate inputTextViewDidBeginEditing:self.inputTextView];
  138. }
  139. }
  140. - (void)textViewDidEndEditing:(UITextView *)textView
  141. {
  142. [textView resignFirstResponder];
  143. }
  144. - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
  145. {
  146. if ([text isEqualToString:@"\n"]) {
  147. if ([self.delegate respondsToSelector:@selector(didSendText:)]) {
  148. [self.delegate didSendText:textView.text];
  149. self.inputTextView.text = @"";
  150. [self willShowInputTextViewToHeight:[self getTextViewContentH:self.inputTextView]];;
  151. }
  152. return NO;
  153. }
  154. return YES;
  155. }
  156. - (void)textViewDidChange:(UITextView *)textView
  157. {
  158. [self willShowInputTextViewToHeight:[self getTextViewContentH:textView]];
  159. }
  160. #pragma mark - DXFaceDelegate
  161. - (void)selectedFacialView:(NSString *)str isDelete:(BOOL)isDelete
  162. {
  163. NSString *chatText = self.inputTextView.text;
  164. if (!isDelete && str.length > 0) {
  165. self.inputTextView.text = [NSString stringWithFormat:@"%@%@",chatText,str];
  166. }
  167. else {
  168. if (chatText.length >= 2)
  169. {
  170. NSString *subStr = [chatText substringFromIndex:chatText.length-2];
  171. if ([(DXFaceView *)self.faceView stringIsFace:subStr]) {
  172. self.inputTextView.text = [chatText substringToIndex:chatText.length-2];
  173. return;
  174. }
  175. }
  176. if (chatText.length > 0) {
  177. self.inputTextView.text = [chatText substringToIndex:chatText.length-1];
  178. }
  179. }
  180. [self textViewDidChange:self.inputTextView];
  181. }
  182. - (void)sendFace
  183. {
  184. NSString *chatText = self.inputTextView.text;
  185. if (chatText.length > 0) {
  186. if ([self.delegate respondsToSelector:@selector(didSendText:)]) {
  187. [self.delegate didSendText:chatText];
  188. self.inputTextView.text = @"";
  189. [self willShowInputTextViewToHeight:[self getTextViewContentH:self.inputTextView]];;
  190. }
  191. }
  192. }
  193. #pragma mark - MoreView Button Action
  194. - (void)moreViewPhotoAction:(DXChatBarMoreView *)moreView {
  195. if ([self.delegate respondsToSelector:@selector(didSelectedMorePhotoButton)]) {
  196. [self.delegate didSelectedMorePhotoButton];
  197. }
  198. }
  199. - (void)moreViewTakePicAction:(DXChatBarMoreView *)moreView {
  200. if ([self.delegate respondsToSelector:@selector(didSelectedMoreCameraButton)]) {
  201. [self.delegate didSelectedMoreCameraButton];
  202. }
  203. }
  204. #pragma mark - UIKeyboardNotification
  205. - (void)keyboardWillChangeFrame:(NSNotification *)notification
  206. {
  207. NSDictionary *userInfo = notification.userInfo;
  208. CGRect endFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
  209. CGRect beginFrame = [userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
  210. CGFloat duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
  211. UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
  212. void(^animations)() = ^{
  213. [self willShowKeyboardFromFrame:beginFrame toFrame:endFrame];
  214. };
  215. void(^completion)(BOOL) = ^(BOOL finished){
  216. };
  217. [UIView animateWithDuration:duration delay:0.0f options:(curve << 16 | UIViewAnimationOptionBeginFromCurrentState) animations:animations completion:completion];
  218. }
  219. #pragma mark - private
  220. /**
  221. * 设置初始属性
  222. */
  223. - (void)setupConfigure
  224. {
  225. self.version = [[[UIDevice currentDevice] systemVersion] floatValue];
  226. self.maxTextInputViewHeight = kInputTextViewMaxHeight;
  227. self.activityButtomView = nil;
  228. self.isShowButtomView = NO;
  229. self.backgroundImageView.image = [[UIImage imageNamed:@"messageToolbarBg"] stretchableImageWithLeftCapWidth:0.5 topCapHeight:10];
  230. [self addSubview:self.backgroundImageView];
  231. self.toolbarView.frame = CGRectMake(0, 0, self.frame.size.width, kVerticalPadding * 2 + kInputTextViewMinHeight);
  232. self.toolbarBackgroundImageView.frame = self.toolbarView.bounds;
  233. [self.toolbarView addSubview:self.toolbarBackgroundImageView];
  234. [self addSubview:self.toolbarView];
  235. self.toolBarOffsetHeight = 0;
  236. [self configKeyboardEvent];
  237. }
  238. - (void)setupSubviews
  239. {
  240. // CGFloat allButtonWidth = 0.0;
  241. // CGFloat textViewLeftMargin = 6.0;
  242. // allButtonWidth += CGRectGetMaxX(self.styleChangeButton.frame);
  243. // textViewLeftMargin += CGRectGetMaxX(self.styleChangeButton.frame);
  244. //更多
  245. self.moreButton = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.bounds) - 2 - kInputTextViewMinHeight, kVerticalPadding, kInputTextViewMinHeight, kInputTextViewMinHeight)];
  246. self.moreButton.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
  247. [self.moreButton setImage:[UIImage imageNamed:@"chatBar_more"] forState:UIControlStateNormal];
  248. [self.moreButton addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
  249. self.moreButton.tag = 2;
  250. // allButtonWidth += CGRectGetWidth(self.moreButton.frame) + kHorizontalPadding * 2.5;
  251. //表情
  252. self.faceButton = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetMinX(self.moreButton.frame) - kInputTextViewMinHeight, kVerticalPadding, kInputTextViewMinHeight, kInputTextViewMinHeight)];
  253. self.faceButton.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
  254. // self.faceButton.transform = CGAffineTransformMakeScale(1.1, 1.1);
  255. [self.faceButton setImage:[UIImage imageNamed:@"chatBar_face"] forState:UIControlStateNormal];
  256. [self.faceButton setImage:[UIImage imageNamed:@"chatBar_keyboard"] forState:UIControlStateSelected];
  257. [self.faceButton addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
  258. self.faceButton.tag = 1;
  259. // allButtonWidth += CGRectGetWidth(self.faceButton.frame) + kHorizontalPadding * 1.5;
  260. // 输入框的高度和宽度
  261. self.inputTextView = [[XHMessageTextView alloc] initWithFrame:CGRectMake(10.0, kVerticalPadding, [UIScreen mainScreen].bounds.size.width - 88, kInputTextViewMinHeight)];
  262. self.inputTextView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
  263. _inputTextView.scrollEnabled = YES;
  264. _inputTextView.returnKeyType = UIReturnKeySend;
  265. _inputTextView.enablesReturnKeyAutomatically = YES;
  266. _inputTextView.placeHolder = @"输入新消息";
  267. _inputTextView.delegate = self;
  268. _inputTextView.backgroundColor = [UIColor whiteColor];
  269. _inputTextView.layer.borderColor = [UIColor colorWithWhite:0.8f alpha:1.0f].CGColor;
  270. _inputTextView.layer.borderWidth = 0.65f;
  271. _inputTextView.layer.cornerRadius = 6.0f;
  272. _previousTextViewContentHeight = [self getTextViewContentH:_inputTextView];
  273. self.sendButton = [[UIButton alloc] initWithFrame:CGRectMake(_inputTextView.frame.origin.x + _inputTextView.frame.size.width + 10, kVerticalPadding, 70, kInputTextViewMinHeight)];
  274. self.sendButton.titleLabel.font = [UIFont systemFontOfSize:15.0];
  275. [self.sendButton setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal];
  276. [self.sendButton setTitle:@"发 送" forState:UIControlStateNormal];
  277. self.sendButton.layer.cornerRadius = 4.0;
  278. self.sendButton.layer.borderWidth = 1.0;
  279. self.sendButton.layer.borderColor = BLUETEXTCOLOR.CGColor;
  280. [self.sendButton addTarget:self
  281. action:@selector(sendMessage:)
  282. forControlEvents:UIControlEventTouchUpInside];
  283. if (!self.moreView) {
  284. self.moreView = [[DXChatBarMoreView alloc] initWithFrame:CGRectMake(0, (kVerticalPadding * 2 + kInputTextViewMinHeight), self.frame.size.width, 100) typw:ChatMoreTypeGroupChat];
  285. self.moreView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
  286. self.moreView.backgroundColor = [UIColor whiteColor];
  287. }
  288. if (!self.faceView) {
  289. self.faceView = [[DXFaceView alloc] initWithFrame:CGRectMake(0, (kVerticalPadding * 2 + kInputTextViewMinHeight), self.frame.size.width, 200)];
  290. [(DXFaceView *)self.faceView setDelegate:self];
  291. self.faceView.backgroundColor = [UIColor whiteColor];
  292. self.faceView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
  293. }
  294. if (!self.recordView) {
  295. self.recordView = [[DXRecordView alloc] initWithFrame:CGRectMake(90, 130, 140, 140)];
  296. }
  297. [self.toolbarView addSubview:self.moreButton];
  298. [self.toolbarView addSubview:self.inputTextView];
  299. [self.toolbarView addSubview:self.faceButton];
  300. [self.toolbarView addSubview:self.recordButton];
  301. }
  302. #pragma mark - change frame
  303. - (void)willShowBottomHeight:(CGFloat)bottomHeight
  304. {
  305. CGRect fromFrame = self.frame;
  306. CGFloat toHeight = self.toolbarView.frame.size.height + bottomHeight;
  307. /**
  308. * 切换到发送照片时
  309. */
  310. if (bottomHeight > 200) {
  311. toHeight -= self.toolBarOffsetHeight;
  312. }
  313. CGRect toFrame = CGRectMake(fromFrame.origin.x, fromFrame.origin.y + (fromFrame.size.height - toHeight), fromFrame.size.width, toHeight);
  314. //如果需要将所有扩展页面都隐藏,而此时已经隐藏了所有扩展页面,则不进行任何操作
  315. if(bottomHeight == 0 && self.frame.size.height == self.toolbarView.frame.size.height)
  316. {
  317. return;
  318. }
  319. if (bottomHeight == 0) {
  320. self.isShowButtomView = NO;
  321. }
  322. else{
  323. self.isShowButtomView = YES;
  324. }
  325. self.frame = toFrame;
  326. if (_delegate && [_delegate respondsToSelector:@selector(didChangeFrameToHeight:)]) {
  327. [_delegate didChangeFrameToHeight:toHeight];
  328. }
  329. }
  330. - (void)willShowBottomView:(UIView *)bottomView
  331. {
  332. if (![self.activityButtomView isEqual:bottomView]) {
  333. CGFloat bottomHeight = bottomView ? bottomView.frame.size.height : 0;
  334. [self willShowBottomHeight:bottomHeight];
  335. if (bottomView) {
  336. CGRect rect = bottomView.frame;
  337. rect.origin.y = CGRectGetMaxY(self.toolbarView.frame);
  338. bottomView.frame = rect;
  339. [self addSubview:bottomView];
  340. }
  341. if (self.activityButtomView) {
  342. [self.activityButtomView removeFromSuperview];
  343. }
  344. self.activityButtomView = bottomView;
  345. }
  346. }
  347. - (void)willShowKeyboardFromFrame:(CGRect)beginFrame toFrame:(CGRect)toFrame
  348. {
  349. if (beginFrame.origin.y == [[UIScreen mainScreen] bounds].size.height) {
  350. //一定要把self.activityButtomView置为空
  351. [self willShowBottomHeight:toFrame.size.height];
  352. if (self.activityButtomView) {
  353. [self.activityButtomView removeFromSuperview];
  354. self.activityButtomView = nil;
  355. }
  356. } else if (toFrame.origin.y == [[UIScreen mainScreen] bounds].size.height) {
  357. [self willShowBottomHeight:0];
  358. } else {
  359. [self willShowBottomHeight:toFrame.size.height];
  360. }
  361. }
  362. - (void)willShowInputTextViewToHeight:(CGFloat)toHeight
  363. {
  364. if (toHeight < kInputTextViewMinHeight) {
  365. toHeight = kInputTextViewMinHeight;
  366. }
  367. if (toHeight > self.maxTextInputViewHeight) {
  368. toHeight = self.maxTextInputViewHeight;
  369. }
  370. if (toHeight == _previousTextViewContentHeight)
  371. {
  372. return;
  373. }
  374. else{
  375. CGFloat changeHeight = toHeight - _previousTextViewContentHeight;
  376. CGRect rect = self.frame;
  377. rect.size.height += changeHeight;
  378. rect.origin.y -= changeHeight;
  379. self.frame = rect;
  380. rect = self.toolbarView.frame;
  381. rect.size.height += changeHeight;
  382. self.toolbarView.frame = rect;
  383. if (self.version < 7.0) {
  384. [self.inputTextView setContentOffset:CGPointMake(0.0f, (self.inputTextView.contentSize.height - self.inputTextView.frame.size.height) / 2) animated:YES];
  385. }
  386. _previousTextViewContentHeight = toHeight;
  387. if (_delegate && [_delegate respondsToSelector:@selector(didChangeFrameToHeight:)]) {
  388. [_delegate didChangeFrameToHeight:self.frame.size.height];
  389. }
  390. }
  391. }
  392. - (CGFloat)getTextViewContentH:(UITextView *)textView
  393. {
  394. if (self.version >= 7.0)
  395. {
  396. return ceilf([textView sizeThatFits:textView.frame.size].height);
  397. } else {
  398. return textView.contentSize.height;
  399. }
  400. }
  401. #pragma mark - action
  402. - (IBAction)sendMessage:(id)sender {
  403. if ([self.delegate respondsToSelector:@selector(didSendText:)]) {
  404. [self.delegate didSendText:self.inputTextView.text];
  405. self.inputTextView.text = @"";
  406. [self willShowInputTextViewToHeight:[self getTextViewContentH:self.inputTextView]];
  407. }
  408. }
  409. - (void)buttonAction:(id)sender
  410. {
  411. UIButton *button = (UIButton *)sender;
  412. button.selected = !button.selected;
  413. NSInteger tag = button.tag;
  414. switch (tag) {
  415. case 0://切换状态
  416. {
  417. if (button.selected) {
  418. self.faceButton.selected = NO;
  419. self.moreButton.selected = NO;
  420. //录音状态下,不显示底部扩展页面
  421. [self willShowBottomView:nil];
  422. //将inputTextView内容置空,以使toolbarView回到最小高度
  423. self.inputTextView.text = @"";
  424. [self textViewDidChange:self.inputTextView];
  425. [self.inputTextView resignFirstResponder];
  426. }
  427. else{
  428. //键盘也算一种底部扩展页面
  429. [self.inputTextView becomeFirstResponder];
  430. }
  431. [UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
  432. self.recordButton.hidden = !button.selected;
  433. self.inputTextView.hidden = button.selected;
  434. } completion:^(BOOL finished) {
  435. }];
  436. if ([self.delegate respondsToSelector:@selector(didStyleChangeToRecord:)]) {
  437. [self.delegate didStyleChangeToRecord:button.selected];
  438. }
  439. }
  440. break;
  441. case 1://表情
  442. {
  443. if (button.selected) {
  444. self.moreButton.selected = NO;
  445. //如果选择表情并且处于录音状态,切换成文字输入状态,但是不显示键盘
  446. if (self.styleChangeButton.selected) {
  447. self.styleChangeButton.selected = NO;
  448. }
  449. else{//如果处于文字输入状态,使文字输入框失去焦点
  450. [self.inputTextView resignFirstResponder];
  451. }
  452. [self willShowBottomView:self.faceView];
  453. [UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
  454. self.recordButton.hidden = button.selected;
  455. self.inputTextView.hidden = !button.selected;
  456. } completion:^(BOOL finished) {
  457. }];
  458. } else {
  459. if (!self.styleChangeButton.selected) {
  460. [self.inputTextView becomeFirstResponder];
  461. }
  462. else{
  463. [self willShowBottomView:nil];
  464. }
  465. }
  466. if ([self.delegate respondsToSelector:@selector(didSelectedFaceButton:)]) {
  467. [self.delegate didSelectedFaceButton:button.selected];
  468. }
  469. }
  470. break;
  471. case 2://更多
  472. {
  473. if (button.selected) {
  474. self.faceButton.selected = NO;
  475. //如果选择表情并且处于录音状态,切换成文字输入状态,但是不显示键盘
  476. if (self.styleChangeButton.selected) {
  477. self.styleChangeButton.selected = NO;
  478. }
  479. else {//如果处于文字输入状态,使文字输入框失去焦点
  480. [self.inputTextView resignFirstResponder];
  481. }
  482. [self willShowBottomView:self.moreView];
  483. [UIView animateWithDuration:0.2 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
  484. self.recordButton.hidden = button.selected;
  485. self.inputTextView.hidden = !button.selected;
  486. } completion:^(BOOL finished) {
  487. }];
  488. }
  489. else
  490. {
  491. self.styleChangeButton.selected = NO;
  492. [self.inputTextView becomeFirstResponder];
  493. }
  494. if ([self.delegate respondsToSelector:@selector(didSelectedMoreButton:)]) {
  495. [self.delegate didSelectedMoreButton:button.selected];
  496. }
  497. }
  498. break;
  499. default:
  500. break;
  501. }
  502. }
  503. - (void)recordButtonTouchDown
  504. {
  505. if ([self.recordView isKindOfClass:[DXRecordView class]]) {
  506. [(DXRecordView *)self.recordView recordButtonTouchDown];
  507. }
  508. if (_delegate && [_delegate respondsToSelector:@selector(didStartRecordingVoiceAction:)]) {
  509. [_delegate didStartRecordingVoiceAction:self.recordView];
  510. }
  511. }
  512. - (void)recordButtonTouchUpOutside
  513. {
  514. if (_delegate && [_delegate respondsToSelector:@selector(didCancelRecordingVoiceAction:)])
  515. {
  516. [_delegate didCancelRecordingVoiceAction:self.recordView];
  517. }
  518. if ([self.recordView isKindOfClass:[DXRecordView class]]) {
  519. [(DXRecordView *)self.recordView recordButtonTouchUpOutside];
  520. }
  521. [self.recordView removeFromSuperview];
  522. }
  523. - (void)recordButtonTouchUpInside
  524. {
  525. if ([self.recordView isKindOfClass:[DXRecordView class]]) {
  526. [(DXRecordView *)self.recordView recordButtonTouchUpInside];
  527. }
  528. if ([self.delegate respondsToSelector:@selector(didFinishRecoingVoiceAction:)])
  529. {
  530. [self.delegate didFinishRecoingVoiceAction:self.recordView];
  531. }
  532. [self.recordView removeFromSuperview];
  533. }
  534. - (void)recordDragOutside
  535. {
  536. if ([self.recordView isKindOfClass:[DXRecordView class]]) {
  537. [(DXRecordView *)self.recordView recordButtonDragOutside];
  538. }
  539. if ([self.delegate respondsToSelector:@selector(didDragOutsideAction:)])
  540. {
  541. [self.delegate didDragOutsideAction:self.recordView];
  542. }
  543. }
  544. - (void)recordDragInside
  545. {
  546. if ([self.recordView isKindOfClass:[DXRecordView class]]) {
  547. [(DXRecordView *)self.recordView recordButtonDragInside];
  548. }
  549. if ([self.delegate respondsToSelector:@selector(didDragInsideAction:)])
  550. {
  551. [self.delegate didDragInsideAction:self.recordView];
  552. }
  553. }
  554. #pragma mark - public
  555. - (void)configKeyboardEvent {
  556. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
  557. }
  558. - (void)removeKeyboardEvent {
  559. [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil];
  560. }
  561. - (void)setEnableVoice:(BOOL)enableVoice {
  562. if (enableVoice && !self.styleChangeButton) {
  563. //转变输入样式
  564. self.styleChangeButton = [[UIButton alloc] initWithFrame:CGRectMake(kHorizontalPadding, kVerticalPadding, kInputTextViewMinHeight, kInputTextViewMinHeight)];
  565. self.styleChangeButton.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
  566. [self.styleChangeButton setImage:[UIImage imageNamed:@"chatBar_record"] forState:UIControlStateNormal];
  567. [self.styleChangeButton setImage:[UIImage imageNamed:@"chatBar_keyboard"] forState:UIControlStateSelected];
  568. [self.styleChangeButton addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
  569. self.styleChangeButton.tag = 0;
  570. [self.toolbarView addSubview:self.styleChangeButton];
  571. self.inputTextView.frame = CGRectMake(52, kVerticalPadding, CGRectGetWidth(self.inputTextView.frame) - 42, kInputTextViewMinHeight);
  572. //录制
  573. self.recordButton = [[UIButton alloc] initWithFrame:self.inputTextView.frame];
  574. self.recordButton.titleLabel.font = [UIFont systemFontOfSize:15];
  575. [self.recordButton setTitleColor:UIColorFromRGB(0x999999) forState:UIControlStateNormal];
  576. [self.recordButton setTitleColor:UIColorFromRGB(0xffffff) forState:UIControlStateHighlighted];
  577. [self.recordButton setBackgroundImage:[[UIImage imageNamed:@"chatBar_recordBg"] stretchableImageWithLeftCapWidth:10 topCapHeight:10] forState:UIControlStateNormal];
  578. [self.recordButton setTitle:kTouchToRecord forState:UIControlStateNormal];
  579. [self.recordButton setTitle:kTouchToFinish forState:UIControlStateHighlighted];
  580. self.recordButton.hidden = YES;
  581. [self.recordButton addTarget:self action:@selector(recordButtonTouchDown) forControlEvents:UIControlEventTouchDown];
  582. [self.recordButton addTarget:self action:@selector(recordButtonTouchUpOutside) forControlEvents:UIControlEventTouchUpOutside];
  583. [self.recordButton addTarget:self action:@selector(recordButtonTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
  584. [self.recordButton addTarget:self action:@selector(recordDragOutside) forControlEvents:UIControlEventTouchDragExit];
  585. [self.recordButton addTarget:self action:@selector(recordDragInside) forControlEvents:UIControlEventTouchDragEnter];
  586. [self.toolbarView addSubview:self.recordButton];
  587. }
  588. }
  589. /**
  590. * 停止编辑
  591. */
  592. - (BOOL)endEditing:(BOOL)force
  593. {
  594. BOOL result = [super endEditing:force];
  595. self.faceButton.selected = NO;
  596. self.moreButton.selected = NO;
  597. [self willShowBottomView:nil];
  598. return result;
  599. }
  600. /**
  601. * 取消触摸录音键
  602. */
  603. - (void)cancelTouchRecord
  604. {
  605. // self.recordButton.selected = NO;
  606. // self.recordButton.highlighted = NO;
  607. if ([_recordView isKindOfClass:[DXRecordView class]]) {
  608. [(DXRecordView *)_recordView recordButtonTouchUpInside];
  609. [_recordView removeFromSuperview];
  610. }
  611. }
  612. + (CGFloat)defaultHeight
  613. {
  614. return kVerticalPadding * 2 + kInputTextViewMinHeight;
  615. }
  616. @end