BGBaseChatController.m 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793
  1. //
  2. // BGBaseChatController.m
  3. // BuguLive
  4. //
  5. // Created by 朱庆彬 on 2017/8/18.
  6. // Copyright © 2017年 xfg. All rights reserved.
  7. //
  8. #import "BGBaseChatController.h"
  9. #import "ChatAudioRecordNoticeView.h"
  10. #import "ChatEmojiView.h"
  11. #import "ConversationModel.h"
  12. #import "EmojiObj.h"
  13. #import "M80AttributedLabel.h"
  14. #import "MJPhoto.h"
  15. #import "MJPhotoBrowser.h"
  16. #import "MsgCellLeft.h"
  17. #import "MsgCellRight.h"
  18. #import "MsgGiftCellLeft.h"
  19. #import "MsgGiftCellRight.h"
  20. #import "MsgPicCellLeft.h"
  21. #import "MsgPicCellRight.h"
  22. #import "MsgTimeCell.h"
  23. #import "MsgVoiceCellLeft.h"
  24. #import "MsgVoiceCellRight.h"
  25. #import "UIImageView+WebCache.h"
  26. #import <AVFoundation/AVFoundation.h>
  27. @interface BGBaseChatController () <UITextViewDelegate, UITableViewDataSource, UITableViewDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, AVAudioRecorderDelegate, AVAudioPlayerDelegate, UIGestureRecognizerDelegate, ChatBottomBarDelegate, ChatEmojiViewDelegate, ChatMoreViewDelegate>
  28. //@property(nonatomic, strong) ChatEmojiView *emojiView;
  29. @end
  30. @implementation BGBaseChatController
  31. {
  32. BOOL _cgfok;
  33. BOOL _doing;
  34. CGFloat _moreXpoint;
  35. CGFloat _giftXpoint;
  36. CGFloat _lastInputH;
  37. ChatAudioRecordNoticeView *_recshowing;
  38. AVAudioRecorder *_recorder;
  39. BOOL _brecwillsend;
  40. NSTimer *_timer;
  41. NSTimeInterval _recduration;
  42. AVAudioPlayer *_player;
  43. ConversationModel *_nowplayingmsg;
  44. }
  45. - (void)releaseAll
  46. {
  47. [[NSNotificationCenter defaultCenter] removeObserver:self];
  48. }
  49. - (void)dealloc
  50. {
  51. [self releaseAll];
  52. }
  53. - (void)viewDidAppear:(BOOL)animated
  54. {
  55. [super viewDidAppear:animated];
  56. [IQKeyboardManager sharedManager].enable = NO;
  57. [IQKeyboardManager sharedManager].enableAutoToolbar = NO;
  58. }
  59. - (void)viewWillDisappear:(BOOL)animated
  60. {
  61. [self releaseAll];
  62. }
  63. - (void)viewDidDisappear:(BOOL)animated
  64. {
  65. [super viewDidDisappear:animated];
  66. [IQKeyboardManager sharedManager].enable = NO;
  67. [IQKeyboardManager sharedManager].enableAutoToolbar = NO;
  68. }
  69. - (void)backclicked:(id)sender
  70. {
  71. if ([self.navigationController topViewController] == self)
  72. { //如果有导航控制器,,并且顶部就是自己,,那么应该 返回
  73. if (self.navigationController.viewControllers.count == 1)
  74. { //如果只有一个,,,那么
  75. if (self.presentingViewController)
  76. { //如果有,,那么就dismiss
  77. [self dismissViewControllerAnimated:YES
  78. completion:^{
  79. }];
  80. return;
  81. }
  82. else
  83. {
  84. }
  85. }
  86. else
  87. {
  88. [self.navigationController popViewControllerAnimated:YES];
  89. }
  90. }
  91. else //其他情况,就再判断是否有 presentingViewController
  92. if (self.presentingViewController)
  93. { //如果有,,那么就dismiss
  94. [self dismissViewControllerAnimated:YES
  95. completion:^{
  96. }];
  97. return;
  98. }
  99. else
  100. {
  101. }
  102. }
  103. - (void)viewDidLoad
  104. {
  105. [super viewDidLoad];
  106. self.BuguLive = [GlobalVariables sharedInstance];
  107. //判断当前是否有直播
  108. if ([[GlobalVariables sharedInstance].liveState.roomId intValue])
  109. {
  110. _haveLiveExist = YES;
  111. }
  112. else
  113. {
  114. _haveLiveExist = NO;
  115. }
  116. UITapGestureRecognizer* tapgusest = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(taprootview:)];
  117. tapgusest.delegate = self;
  118. [self.view addGestureRecognizer:tapgusest];
  119. self.mtopview.backgroundColor = [UIColor whiteColor];
  120. self.mtableview.backgroundColor = RGBA(233, 233, 233, 1);
  121. self.mmsgdata = NSMutableArray.new;
  122. if (!self.mCannotLoadHistoryMsg)
  123. {
  124. [BGMJRefreshManager refresh:self.mtableview target:self headerRereshAction:@selector(headerStartRefresh) footerRereshAction:nil];
  125. }
  126. if (!self.mCannotLoadNewestMsg)
  127. self.mtableview.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(footerStartRefresh)];
  128. UINib *nib = [UINib nibWithNibName:@"MsgCellLeft" bundle:nil];
  129. [self.mtableview registerNib:nib forCellReuseIdentifier:@"leftcell"];
  130. nib = [UINib nibWithNibName:@"MsgCellRight" bundle:nil];
  131. [self.mtableview registerNib:nib forCellReuseIdentifier:@"rightcell"];
  132. nib = [UINib nibWithNibName:@"MsgTimeCell" bundle:nil];
  133. [self.mtableview registerNib:nib forCellReuseIdentifier:@"timecell"];
  134. nib = [UINib nibWithNibName:@"MsgVoiceCellRight" bundle:nil];
  135. [self.mtableview registerNib:nib forCellReuseIdentifier:@"voicerightcell"];
  136. nib = [UINib nibWithNibName:@"MsgVoiceCellLeft" bundle:nil];
  137. [self.mtableview registerNib:nib forCellReuseIdentifier:@"voiceleftcell"];
  138. nib = [UINib nibWithNibName:@"MsgPicCellLeft" bundle:nil];
  139. [self.mtableview registerNib:nib forCellReuseIdentifier:@"picleftcell"];
  140. nib = [UINib nibWithNibName:@"MsgPicCellRight" bundle:nil];
  141. [self.mtableview registerNib:nib forCellReuseIdentifier:@"picrightcell"];
  142. nib = [UINib nibWithNibName:@"MsgGiftCellRight" bundle:nil];
  143. [self.mtableview registerNib:nib forCellReuseIdentifier:@"gifrightcell"];
  144. nib = [UINib nibWithNibName:@"MsgGiftCellLeft" bundle:nil];
  145. [self.mtableview registerNib:nib forCellReuseIdentifier:@"gifleftcell"];
  146. nib = [UINib nibWithNibName:@"MsgAudioCellLeft" bundle:nil];
  147. [self.mtableview registerNib:nib forCellReuseIdentifier:@"audioleftcell"];
  148. self.mtableview.delegate = self;
  149. self.mtableview.dataSource = self;
  150. self.mtableview.separatorStyle = UITableViewCellSeparatorStyleNone;
  151. if (!self.mDontAutoLoadFrist)
  152. {
  153. if (!self.mCannotLoadHistoryMsg)
  154. [self.mtableview.mj_header beginRefreshing];
  155. else if (!self.mCannotLoadNewestMsg)
  156. [self.mtableview.mj_footer beginRefreshing];
  157. }
  158. self.userMsgArray = NSMutableArray.new;
  159. [self.chatBar mas_makeConstraints:^(MASConstraintMaker *make) {
  160. make.left.and.right.and.bottom.equalTo(self.view);
  161. // mtableview
  162. // make.bottom.equalTo(self.view).offset(-MG_BOTTOM_MARGIN);
  163. //
  164. make.height.mas_greaterThanOrEqualTo(@(kChatBarMinHeight));
  165. }];
  166. [self.mtableview mas_makeConstraints:^(MASConstraintMaker *make) {
  167. make.left.and.right.equalTo(self.view);
  168. make.top.equalTo(self.mtopview).with.offset(self.mtopview.height);
  169. make.bottom.equalTo(self.chatBar).with.offset(-kChatBarMinHeight - MG_BOTTOM_MARGIN);
  170. }];
  171. }
  172. - (UITableView *)mtableview
  173. {
  174. if (!_mtableview)
  175. {
  176. UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
  177. tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
  178. [self.view addSubview:_mtableview = tableView];
  179. }
  180. return _mtableview;
  181. }
  182. - (UIView *)mtopview
  183. {
  184. if (!_mtopview)
  185. {
  186. CGFloat navHeight;
  187. if (_mbhalf)
  188. {
  189. navHeight = 44;
  190. }
  191. else
  192. {
  193. navHeight = kNavigationBarHeight+kStatusBarHeight;
  194. }
  195. UIView *mtopView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenW, navHeight)];
  196. mtopView.backgroundColor = [UIColor whiteColor];
  197. UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, navHeight - 0.5, kScreenW, 0.5f)];
  198. lineView.backgroundColor = RGBA(201, 202, 205, 1);
  199. [mtopView addSubview:lineView];
  200. UIButton *backBtn = [[UIButton alloc] initWithFrame:CGRectMake(10, navHeight - 44, 22, 44)];
  201. [backBtn setImage:[UIImage imageNamed:@"com_arrow_vc_back"] forState:UIControlStateNormal];
  202. [backBtn addTarget:self action:@selector(backclicked:) forControlEvents:UIControlEventTouchUpInside];
  203. [mtopView addSubview:backBtn];
  204. _mtoptitle = [[UILabel alloc] initWithFrame:CGRectMake(80, navHeight - 29.5, kScreenW - 160, 15)];
  205. _mtoptitle.font = [UIFont systemFontOfSize:15];
  206. _mtoptitle.textColor = [BGUtils colorWithHexString:@"333333"];
  207. _mtoptitle.textAlignment = NSTextAlignmentCenter;
  208. [mtopView addSubview:_mtoptitle];
  209. UIButton *rightBtn = [[UIButton alloc] initWithFrame:CGRectMake(kScreenW - 40, navHeight - 33, 20, 20)];
  210. [rightBtn setImage:[UIImage imageNamed:@"ic_chattophead"] forState:UIControlStateNormal];
  211. [rightBtn addTarget:self action:@selector(clickedtophead:) forControlEvents:UIControlEventTouchUpInside];
  212. [mtopView addSubview:rightBtn];
  213. [self.view addSubview:_mtopview = mtopView];
  214. UITapGestureRecognizer *doubleTapGestureRecognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(doubleTapScrollToTop:)];
  215. [doubleTapGestureRecognizer setNumberOfTapsRequired:2];
  216. [_mtopview addGestureRecognizer:doubleTapGestureRecognizer];
  217. }
  218. return _mtopview;
  219. }
  220. - (ChatBottomBarView *)chatBar
  221. {
  222. if (!_chatBar)
  223. {
  224. NSMutableArray *allmore = [@[
  225. @[ASLocalizedString(@"照片"), @"ic_private_chat_more_photo"],
  226. @[ASLocalizedString(@"拍摄"), @"ic_private_chat_more_camera"],
  227. @[ASLocalizedString(@"礼物"), @"ic_private_chat_more_gift"],
  228. @[ASLocalizedString(@"语音"), @"chatmsgaudio"],
  229. @[ASLocalizedString(@"视频"), @"chatmsgVideo"],
  230. ] mutableCopy];
  231. if (self.BuguLive.appModel.open_send_coins_module == 1)
  232. {
  233. [allmore addObject:@[ASLocalizedString(@"赠送游戏币"), @"ic_private_chat_more_money"]];
  234. }
  235. if (self.BuguLive.appModel.open_send_diamonds_module == 1)
  236. {
  237. NSString *diamondsStr = [NSString stringWithFormat:ASLocalizedString(@"赠送%@"),self.BuguLive.appModel.diamond_name];
  238. [allmore addObject:@[diamondsStr, @"ic_private_chat_more_diamonds"]];
  239. }
  240. // 修改 pic 数组 去掉相机2
  241. if (_haveLiveExist)
  242. {
  243. [allmore removeObjectAtIndex:1]; // 去掉 相机
  244. }
  245. ChatBottomBarView *chatBar = [[ChatBottomBarView alloc] init];
  246. chatBar.delegate = self;
  247. [self.view addSubview:(_chatBar = chatBar)];
  248. [self.view bringSubviewToFront:_chatBar];
  249. chatBar.textView.delegate = self;
  250. self.chatBar.emojiView.delegate = self;
  251. self.chatBar.moreView.delegate = self;
  252. [self.chatBar.voiceRecordButton addTarget:self action:@selector(onTouchRecordBtnDown:) forControlEvents:UIControlEventTouchDown];
  253. [self.chatBar.voiceRecordButton addTarget:self action:@selector(onTouchRecordBtnDragInside:) forControlEvents:UIControlEventTouchDragInside];
  254. [self.chatBar.voiceRecordButton addTarget:self action:@selector(onTouchRecordBtnDragOutside:) forControlEvents:UIControlEventTouchDragOutside];
  255. [self.chatBar.voiceRecordButton addTarget:self action:@selector(onTouchRecordBtnUpInside:) forControlEvents:UIControlEventTouchUpInside];
  256. [self.chatBar.voiceRecordButton addTarget:self action:@selector(onTouchRecordBtnUpOutside:) forControlEvents:UIControlEventTouchUpOutside];
  257. [self.chatBar.moreView initWithBtnArray:allmore];
  258. self.chatBar.moreListArr = allmore;
  259. self.chatBar.moreView.delegate = self;
  260. self.chatBar.mbhalf = _mbhalf;
  261. if (self.BuguLive.appModel.has_private_chat == 1)
  262. {
  263. if (self.BuguLive.appModel.private_letter_lv)
  264. {
  265. if ([[IMAPlatform sharedInstance].host getUserRank] >= self.BuguLive.appModel.private_letter_lv)
  266. {
  267. //允许
  268. self.chatBar.maskView.hidden = YES;
  269. }
  270. else
  271. {
  272. self.chatBar.maskView.hidden = NO;
  273. }
  274. }
  275. else
  276. {
  277. //允许
  278. self.chatBar.maskView.hidden = YES;
  279. }
  280. }
  281. else
  282. {
  283. self.chatBar.maskView.hidden = NO;
  284. }
  285. }
  286. return _chatBar;
  287. }
  288. #pragma mark 消息数据获取主要修改这里开始
  289. //获取消息,修改这里
  290. - (void)headerStartRefresh
  291. {
  292. ConversationModel *fmsg = nil;
  293. for (ConversationModel *one in self.mmsgdata)
  294. {
  295. if (one.mMsgType != 0)
  296. {
  297. fmsg = one;
  298. break;
  299. }
  300. }
  301. FWWeakify(self)
  302. [self getMsgBefor:fmsg
  303. block:^(NSArray *all) {
  304. FWStrongify(self)
  305. //如果用户头像更新。则更新所有消息里 头像的
  306. [self upDataForMsgHeaderImg:all];
  307. [BGMJRefreshManager endRefresh:self.mtableview];
  308. if (all.count)
  309. {
  310. int timecellcount = 0;
  311. NSUInteger msgCount = self.mmsgdata.count;
  312. for (NSInteger j = all.count - 1; j >= 0; j--)
  313. {
  314. // ConversationModel* one = all[ j ];
  315. SIMMsgObj *one = all[j];
  316. // 子类有用户ID
  317. for (SIMMsgObj *j in _userMsgArray)
  318. {
  319. if (one.mHeadImgUrl == nil || [one.mHeadImgUrl isEqual:[NSNull null]])
  320. {
  321. one.mHeadImgUrl = @" ";
  322. }
  323. if (j.mSenderId == one.mSenderId && ![one.mHeadImgUrl isEqualToString:j.mHeadImgUrl])
  324. {
  325. one.mHeadImgUrl = j.mHeadImgUrl;
  326. }
  327. }
  328. [self.mmsgdata insertObject:one atIndex:0];
  329. if ((self.mmsgdata.count % 8) == 0)
  330. { //每5个就显示一个时间..
  331. ConversationModel *timemsg = [self makeTimeMsgObj:one];
  332. [self.mmsgdata insertObject:timemsg atIndex:1];
  333. timecellcount++;
  334. }
  335. }
  336. [self.mtableview reloadData];
  337. if (msgCount == 0)
  338. {
  339. [self.mtableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:all.count - 1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO];
  340. [self scrollTableToFoot:YES];
  341. }
  342. else
  343. {
  344. NSInteger index = all.count + timecellcount + 1;
  345. index = index >= self.mmsgdata.count ? (self.mmsgdata.count - 1) : index;
  346. [self.mtableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO];
  347. [self scrollTableToFoot:YES];
  348. }
  349. }
  350. }];
  351. }
  352. #pragma mark - 滑到最底部
  353. - (void)scrollTableToFoot:(BOOL)animated
  354. {
  355. NSInteger s = [self.mtableview numberOfSections]; //有多少组
  356. if (s<1) return; //无数据时不执行 要不会crash
  357. NSInteger r = [self.mtableview numberOfRowsInSection:s-1]; //最后一组有多少行
  358. if (r<1) return;
  359. NSIndexPath *ip = [NSIndexPath indexPathForRow:r-1 inSection:s-1]; //取最后一行数据
  360. [self.mtableview scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionBottom animated:animated]; //滚动到最后一行
  361. }
  362. - (void)upDataForMsgHeaderImg:(NSArray *)all
  363. {
  364. if (all.count > 0)
  365. {
  366. SIMMsgObj *last = [all firstObject];
  367. for (NSInteger j = 0; j < all.count; j++)
  368. {
  369. SIMMsgObj *one = all[j];
  370. BOOL isNew = YES;
  371. for (int i = 0; i < _userMsgArray.count; i++)
  372. {
  373. SIMMsgObj *b = _userMsgArray[i];
  374. if (b.mSenderId == one.mSenderId)
  375. {
  376. isNew = NO;
  377. if ([b.mMsgDate compare:one.mMsgDate] == -1)
  378. {
  379. [_userMsgArray replaceObjectAtIndex:i withObject:one];
  380. }
  381. break;
  382. }
  383. }
  384. if (isNew)
  385. {
  386. [_userMsgArray addObject:one];
  387. }
  388. last = one;
  389. }
  390. }
  391. for (SIMMsgObj *a in _userMsgArray)
  392. {
  393. NSInteger mUser_id = 0;
  394. NSString *mHead_image = @"";
  395. if (self.dic)
  396. {
  397. mUser_id = [[self.dic objectForKey:@"mUser_id"] integerValue];
  398. mHead_image = [self.dic objectForKey:@"mHead_image"];
  399. }
  400. //yue
  401. if (a.mHeadImgUrl == nil || [a.mHeadImgUrl isEqual:[NSNull null]])
  402. {
  403. a.mHeadImgUrl = @" ";
  404. }
  405. if (a.mSenderId == [[IMAPlatform sharedInstance].host.imUserId intValue] && ![a.mHeadImgUrl isEqualToString:[[IMAPlatform sharedInstance].host.customInfoDict objectForKey:@"head_image"]])
  406. {
  407. a.mHeadImgUrl = [[IMAPlatform sharedInstance].host.customInfoDict objectForKey:@"head_image"];
  408. }
  409. else if (a.mSenderId == mUser_id && ![a.mHeadImgUrl isEqualToString:mHead_image])
  410. {
  411. a.mHeadImgUrl = mHead_image;
  412. }
  413. }
  414. }
  415. - (void)footerStartRefresh
  416. {
  417. ConversationModel *findlast = nil;
  418. for (NSInteger j = self.mmsgdata.count - 1; j >= 0; j--)
  419. {
  420. ConversationModel *one = self.mmsgdata[j];
  421. if (one.mMsgType != 0)
  422. {
  423. findlast = one;
  424. break;
  425. }
  426. }
  427. FWWeakify(self)
  428. [self getMsgAfter:findlast
  429. block:^(NSArray *all) {
  430. FWStrongify(self)
  431. [BGMJRefreshManager endRefresh:self.mtableview];
  432. if (all.count)
  433. {
  434. int timecellcount = 0;
  435. NSUInteger msgCount = self.mmsgdata.count;
  436. for (NSInteger j = 0; j < all.count; j++)
  437. {
  438. ConversationModel *one = all[j];
  439. [self.mmsgdata addObject:one];
  440. if ((self.mmsgdata.count % 8) == 0)
  441. { //每5个就显示一个时间..
  442. ConversationModel *timemsg = [self makeTimeMsgObj:one];
  443. [self.mmsgdata addObject:timemsg];
  444. timecellcount++;
  445. }
  446. }
  447. [self.mtableview reloadData];
  448. if (msgCount == 0)
  449. {
  450. [self.mtableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.mmsgdata.count - 1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO];
  451. }
  452. }
  453. }];
  454. }
  455. //获取 msg 之前的消息,,,
  456. - (void)getMsgBefor:(ConversationModel *)msg block:(void (^)(NSArray *all))block
  457. {
  458. }
  459. //获取 msg 之后的消息
  460. - (void)getMsgAfter:(ConversationModel *)msg block:(void (^)(NSArray *all))block
  461. {
  462. }
  463. - (ConversationModel *)makeTimeMsgObj:(ConversationModel *)msg
  464. {
  465. ConversationModel *tt = ConversationModel.new;
  466. tt.mMsgDate = msg.mMsgDate;
  467. return tt;
  468. }
  469. - (void)willSendThisText:(NSString *)txt
  470. {
  471. self.chatBar.textView.text = @"";
  472. if (![self.chatBar.textView isFirstResponder]) {
  473. [self.chatBar.textView resignFirstResponder];
  474. }
  475. [self.chatBar updateChatBarConstraintsIfNeededShouldCacheText:YES];
  476. }
  477. - (void)willSendThisImg:(UIImage *)img
  478. {
  479. }
  480. - (void)willSendThisVoice:(NSURL *)voicepath duration:(NSTimeInterval)duration
  481. {
  482. }
  483. //发送完成,,当异步发送完成之后,调用该函数
  484. - (void)didSendThisMsg:(ConversationModel *)msg
  485. {
  486. if (msg == nil)
  487. return;
  488. if (![self.mmsgdata containsObject:msg])
  489. { //如果还没有,就添加...
  490. [self addOneMsg:msg];
  491. return;
  492. }
  493. //就是更新下状态
  494. [self updateOneMsg:msg];
  495. }
  496. //需要重新发送
  497. - (void)willReSendThisMsg:(ConversationModel *)msg
  498. {
  499. //开始发送
  500. msg.mMsgStatus = 1;
  501. [self updateOneMsg:msg];
  502. //for testcode
  503. if ([NSStringFromClass([self class]) isEqualToString:NSStringFromClass([BGBaseChatController class])])
  504. {
  505. }
  506. }
  507. - (void)wantFetchMsg:(ConversationModel *)msg block:(void (^)(NSString *errmsg, ConversationModel *msg))block
  508. {
  509. [msg fetchMsgData:^(NSString *errmsg) {
  510. block(errmsg, msg);
  511. }];
  512. }
  513. - (void)addOneMsg:(ConversationModel *)sendMsg
  514. {
  515. if ([self.mmsgdata containsObject:sendMsg])
  516. return;
  517. [self.mmsgdata addObject:sendMsg];
  518. [self.mtableview beginUpdates];
  519. [self.mtableview insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:self.mmsgdata.count - 1 inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
  520. [self.mtableview endUpdates];
  521. [self updateOnSendMessage:self.mmsgdata];
  522. }
  523. - (void)updateOnSendMessage:(NSArray *)msglist
  524. {
  525. if (msglist.count)
  526. {
  527. NSInteger index = [_mmsgdata indexOfObject:msglist.lastObject];
  528. [_mtableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO];
  529. }
  530. }
  531. //删除一条消息
  532. - (void)delOneMsg:(ConversationModel *)delMsg
  533. {
  534. NSUInteger index = [self.mmsgdata indexOfObject:delMsg];
  535. if (index == NSNotFound)
  536. return;
  537. [self.mmsgdata removeObjectAtIndex:index];
  538. [self.mtableview beginUpdates];
  539. [self.mtableview deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
  540. [self.mtableview endUpdates];
  541. }
  542. //更新一条消息
  543. - (void)updateOneMsg:(ConversationModel *)updMsg
  544. {
  545. NSUInteger index = [self.mmsgdata indexOfObject:updMsg];
  546. if (index == NSNotFound)
  547. return;
  548. [self.mtableview reloadData];
  549. return;
  550. [self.mmsgdata replaceObjectAtIndex:index withObject:updMsg];
  551. CGPoint point = self.mtableview.contentOffset;
  552. [self.mtableview beginUpdates];
  553. [self.mtableview reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
  554. [self.mtableview endUpdates];
  555. [self.mtableview setContentOffset:point];
  556. }
  557. #pragma mark 消息数据获取主要修改这里结束
  558. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  559. {
  560. return self.mmsgdata.count;
  561. }
  562. - (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
  563. {
  564. return UITableViewAutomaticDimension;
  565. }
  566. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
  567. {
  568. return UITableViewAutomaticDimension;
  569. }
  570. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  571. {
  572. ConversationModel *msgobj = self.mmsgdata[indexPath.row];
  573. MsgCellRight *retcell = nil;
  574. if (msgobj.mMsgType == 1)
  575. { //文字消息
  576. ConversationModel *textobj = msgobj;
  577. if (textobj.mIsSendOut)
  578. {
  579. retcell = [tableView dequeueReusableCellWithIdentifier:@"rightcell"];
  580. if (msgobj.mMsgStatus == 1)
  581. {
  582. [retcell.msv startAnimating];
  583. }
  584. else
  585. {
  586. [retcell.msv stopAnimating];
  587. }
  588. retcell.mfailedicon.hidden = !(msgobj.mMsgStatus == 2);
  589. }
  590. else
  591. {
  592. retcell = [tableView dequeueReusableCellWithIdentifier:@"leftcell"];
  593. }
  594. [retcell.mmsglabel dealFace:textobj.mTextMsg];
  595. CGSize ss = [retcell.mmsglabel sizeThatFits:CGSizeMake(tableView.bounds.size.width - 73 - 50, CGFLOAT_MAX)];
  596. retcell.mlabelconstH.constant = ss.height;
  597. retcell.mlabelconstW.constant = ss.width;
  598. }
  599. else if (msgobj.mMsgType == 2)
  600. { //图片
  601. ConversationModel *picobj = msgobj;
  602. MsgPicCellRight *piccell = nil;
  603. if (picobj.mIsSendOut)
  604. {
  605. piccell = [tableView dequeueReusableCellWithIdentifier:@"picrightcell"];
  606. if (msgobj.mMsgStatus == 1)
  607. {
  608. [piccell.msv startAnimating];
  609. }
  610. else
  611. {
  612. [piccell.msv stopAnimating];
  613. }
  614. piccell.mfailedicon.hidden = !(msgobj.mMsgStatus == 2);
  615. }
  616. else
  617. {
  618. piccell = [tableView dequeueReusableCellWithIdentifier:@"picleftcell"];
  619. }
  620. #pragma mark 图片最宽
  621. CGFloat picShowW = tableView.bounds.size.width - 280.0f; //这是最大的
  622. CGFloat screenW = picobj.mPicW / [UIScreen mainScreen].scale; //真正屏幕宽度
  623. picShowW = screenW > picShowW ? picShowW : screenW;
  624. picShowW = picShowW == 0.0f ? (100.0f) : picShowW;
  625. CGFloat picShowH = (picobj.mPicH / picobj.mPicW) * picShowW;
  626. picShowH = picShowH == 0.0f ? (100.0f) : picShowH;
  627. if (picobj.mImgObj)
  628. {
  629. piccell.mtagimg.image = picobj.mImgObj;
  630. }
  631. else
  632. {
  633. [piccell.mtagimg sd_setImageWithURL:[NSURL URLWithString:picobj.mPicURL] placeholderImage:[UIImage imageNamed:@"DefaultImg"]];
  634. }
  635. piccell.mimgconstH.constant = picShowH;
  636. piccell.mimgconstW.constant = picShowW;
  637. retcell = piccell;
  638. }
  639. else if (msgobj.mMsgType == 3)
  640. { //语音
  641. ConversationModel *voiceobj = msgobj;
  642. MsgVoiceCellRight *vcell = nil;
  643. if (voiceobj.mIsSendOut)
  644. {
  645. vcell = [tableView dequeueReusableCellWithIdentifier:@"voicerightcell"];
  646. if (voiceobj.mIsPlaying)
  647. {
  648. vcell.mvoiceicon.image = nil;
  649. vcell.mvoiceicon.image =
  650. [UIImage animatedImageWithImages:@[
  651. [UIImage imageNamed:@"ic_play_voice_right0"],
  652. [UIImage imageNamed:@"ic_play_voice_right1"],
  653. [UIImage imageNamed:@"ic_play_voice_right2"],
  654. [UIImage imageNamed:@"ic_play_voice_right3"],
  655. [UIImage imageNamed:@"ic_play_voice_right4"],
  656. [UIImage imageNamed:@"ic_play_voice_right5"],
  657. ]
  658. duration:1.8f];
  659. }
  660. else
  661. {
  662. vcell.mvoiceicon.image = [UIImage imageNamed:@"ic_play_voice_right0"];
  663. }
  664. }
  665. else
  666. {
  667. vcell = [tableView dequeueReusableCellWithIdentifier:@"voiceleftcell"];
  668. if (voiceobj.mIsPlaying)
  669. {
  670. vcell.mvoiceicon.image = nil;
  671. vcell.mvoiceicon.image =
  672. [UIImage animatedImageWithImages:@[
  673. [UIImage imageNamed:@"ic_play_voice_left0"],
  674. [UIImage imageNamed:@"ic_play_voice_left1"],
  675. [UIImage imageNamed:@"ic_play_voice_left2"],
  676. [UIImage imageNamed:@"ic_play_voice_left3"],
  677. [UIImage imageNamed:@"ic_play_voice_left4"],
  678. [UIImage imageNamed:@"ic_play_voice_left5"],
  679. ]
  680. duration:1.8f];
  681. }
  682. else
  683. {
  684. vcell.mvoiceicon.image = [UIImage imageNamed:@"ic_play_voice_left0"];
  685. }
  686. }
  687. vcell.mlonglabel.text = [NSString stringWithFormat:@"%.1f''", voiceobj.mDurlong];
  688. CGFloat ff = (voiceobj.mDurlong / 60.0f) * 150.0f;
  689. #pragma mark 声音cell最宽,最窄
  690. ff = ff < 50 ? 50.0f : ff;
  691. ff = ff > 150.0f ? 150.0f : ff;
  692. vcell.mlongrateconstW.constant = ff;
  693. retcell = vcell;
  694. }
  695. else if (msgobj.mMsgType == 4)
  696. {
  697. ConversationModel *gifobj = msgobj;
  698. MsgGiftCellRight *giftcell = nil;
  699. if (gifobj.mIsSendOut)
  700. {
  701. giftcell = [tableView dequeueReusableCellWithIdentifier:@"gifrightcell"];
  702. giftcell.mjy.text = gifobj.mJyStr;
  703. if (msgobj.mMsgStatus == 1)
  704. {
  705. [giftcell.msv startAnimating];
  706. }
  707. else
  708. {
  709. [giftcell.msv stopAnimating];
  710. }
  711. giftcell.mfailedicon.hidden = !(msgobj.mMsgStatus == 2);
  712. }
  713. else
  714. {
  715. giftcell = [tableView dequeueReusableCellWithIdentifier:@"gifleftcell"];
  716. }
  717. //刷新直播间的游戏币
  718. if (_mbhalf)
  719. {
  720. [[NSNotificationCenter defaultCenter] postNotificationName:@"updateCoin" object:nil];
  721. }
  722. [giftcell.mgificon sd_setImageWithURL:[NSURL URLWithString:gifobj.mGiftIconURL] placeholderImage:nil];
  723. NSString *originalString = gifobj.mGiftDesc;
  724. NSString *pattern = @"收到一个";
  725. NSError *error = nil;
  726. NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
  727. NSString *modifiedString = [regex stringByReplacingMatchesInString:originalString options:0 range:NSMakeRange(0, originalString.length) withTemplate:ASLocalizedString(@"收到一个")];
  728. NSRegularExpression *regex1 = [NSRegularExpression regularExpressionWithPattern:@"获得" options:0 error:&error];
  729. NSString *modifiedString1 = [regex1 stringByReplacingMatchesInString:modifiedString options:0 range:NSMakeRange(0, modifiedString.length) withTemplate:ASLocalizedString(@"获得")];
  730. NSRegularExpression *regex2 = [NSRegularExpression regularExpressionWithPattern:@"可以去个人主页>我的收益 查看哦" options:0 error:&error];
  731. NSString *modifiedString2 = [regex2 stringByReplacingMatchesInString:modifiedString1 options:0 range:NSMakeRange(0, modifiedString1.length) withTemplate:ASLocalizedString(@"可以去个人主页>我的收益 查看哦")];
  732. NSLog(@"%@", modifiedString2);
  733. giftcell.mgifdesc.text = modifiedString2;
  734. retcell = giftcell;
  735. }else if(msgobj.mMsgType == 666 || msgobj.mMsgType == 667){
  736. ConversationModel *timeobj = msgobj;
  737. MsgTimeCell *timecell = [tableView dequeueReusableCellWithIdentifier:@"timecell"];
  738. timecell.mtimelabel.text = [timeobj getTimeStr];
  739. timecell.selectionStyle = UITableViewCellSelectionStyleNone;
  740. timecell.hidden = YES;
  741. return timecell;
  742. }
  743. else
  744. { //其他什么鬼...其他所有消息都当真时间消息处理了....
  745. ConversationModel *timeobj = msgobj;
  746. MsgTimeCell *timecell = [tableView dequeueReusableCellWithIdentifier:@"timecell"];
  747. timecell.mtimelabel.text = [timeobj getTimeStr];
  748. timecell.selectionStyle = UITableViewCellSelectionStyleNone;
  749. timecell.hidden = YES;
  750. return timecell;
  751. }
  752. //yue
  753. if (msgobj.mHeadImgUrl == nil || [msgobj.mHeadImgUrl isEqual:[NSNull null]])
  754. {
  755. msgobj.mHeadImgUrl = @" ";
  756. }
  757. [retcell.mheadimg sd_setImageWithURL:[NSURL URLWithString:msgobj.mHeadImgUrl] placeholderImage:kDefaultPreloadHeadImg];
  758. retcell.selectionStyle = UITableViewCellSelectionStyleNone;
  759. retcell.backgroundColor = [UIColor clearColor];
  760. return retcell;
  761. }
  762. - (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath
  763. {
  764. ConversationModel *msgobj = self.mmsgdata[indexPath.row];
  765. if (msgobj.mMsgType == 1)
  766. {
  767. return YES;
  768. }
  769. return NO;
  770. }
  771. //每个cell都会点击出现Menu菜单
  772. - (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
  773. {
  774. if (action == @selector(copy:))
  775. {
  776. return YES;
  777. }
  778. return NO;
  779. }
  780. - (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender
  781. {
  782. if (action == @selector(copy:))
  783. {
  784. ConversationModel *msgobj = self.mmsgdata[indexPath.row];
  785. [UIPasteboard generalPasteboard].string = msgobj.mTextMsg;
  786. }
  787. }
  788. - (void)failedIconTouched:(NSIndexPath *)indexPath iconhiden:(BOOL)iconhiden
  789. {
  790. if (iconhiden)
  791. return;
  792. ConversationModel *msgobj = self.mmsgdata[indexPath.row];
  793. if (msgobj.mMsgStatus == 2)
  794. {
  795. [self willReSendThisMsg:msgobj];
  796. return;
  797. }
  798. }
  799. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  800. {
  801. [tableView deselectRowAtIndexPath:indexPath animated:YES];
  802. ConversationModel *msgobj = self.mmsgdata[indexPath.row];
  803. [self msgClicked:msgobj];
  804. }
  805. - (void)msgClicked:(ConversationModel *)msgobj
  806. {
  807. if (msgobj.mMsgType == 3)
  808. { //播放语音消息
  809. [self playVoiceMsg:(ConversationModel *) msgobj
  810. block:^(BOOL playing) {
  811. if (playing)
  812. [self.mtableview reloadData];
  813. }];
  814. }
  815. else if (msgobj.mMsgType == 2)
  816. { //查看大图
  817. MJPhoto *pp = MJPhoto.new;
  818. pp.url = [NSURL URLWithString:msgobj.mPicURL];
  819. pp.srcImageView = nil;
  820. MJPhotoBrowser *browser = [[MJPhotoBrowser alloc] init];
  821. browser.currentPhotoIndex = 0;
  822. browser.photos = @[pp];
  823. [browser show];
  824. }
  825. }
  826. - (void)playVoiceMsg:(ConversationModel *)msg block:(void (^)(BOOL playing))block
  827. {
  828. [_player stop];
  829. _player = nil;
  830. if (msg == _nowplayingmsg)
  831. {
  832. [self stopPlayVoice:msg];
  833. _nowplayingmsg = nil;
  834. return; //这种就是停止的意思
  835. }
  836. if (msg.mVoiceData == nil)
  837. {
  838. //数据没有就填充下,,,具体是用URL下载,还是怎么的,自己处理
  839. [self wantFetchMsg:msg
  840. block:^(NSString *errmsg, ConversationModel *msg) {
  841. if (errmsg)
  842. {
  843. [SVProgressHUD showErrorWithStatus:errmsg];
  844. }
  845. else
  846. {
  847. block([self realPlayVoice:msg]);
  848. }
  849. }];
  850. return;
  851. }
  852. block([self realPlayVoice:msg]);
  853. }
  854. - (BOOL)realPlayVoice:(ConversationModel *)msg
  855. {
  856. AVAudioSession *audioSession = [AVAudioSession sharedInstance];
  857. //默认情况下扬声器播放
  858. [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
  859. [audioSession setActive:YES error:nil];
  860. NSError *error = nil;
  861. _player = [[AVAudioPlayer alloc] initWithData:msg.mVoiceData error:&error];
  862. _player.delegate = self;
  863. _nowplayingmsg = msg;
  864. _nowplayingmsg.mIsPlaying = YES;
  865. [self handleNotification:YES];
  866. if (_player == nil || ![_player prepareToPlay] || ![_player play])
  867. {
  868. [SVProgressHUD showErrorWithStatus:ASLocalizedString(@"播放该消息失败")];
  869. [self stopPlayVoice:msg];
  870. _nowplayingmsg = nil;
  871. return NO;
  872. }
  873. return YES;
  874. }
  875. - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
  876. {
  877. [self stopPlayVoice:_nowplayingmsg];
  878. _nowplayingmsg = nil;
  879. [self handleNotification:NO];
  880. }
  881. #pragma mark - 监听听筒or扬声器
  882. - (void) handleNotification:(BOOL)state
  883. {
  884. [[UIDevice currentDevice] setProximityMonitoringEnabled:state]; //建议在播放之前设置yes,播放结束设置NO,这个功能是开启红外感应
  885. if(state)//添加监听
  886. [[NSNotificationCenter defaultCenter] addObserver:self
  887. selector:@selector(sensorStateChange:) name:@"UIDeviceProximityStateDidChangeNotification"
  888. object:nil];
  889. else//移除监听
  890. [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UIDeviceProximityStateDidChangeNotification" object:nil];
  891. }
  892. //处理监听触发事件
  893. -(void)sensorStateChange:(NSNotificationCenter *)notification;
  894. {
  895. //如果此时手机靠近面部放在耳朵旁,那么声音将通过听筒输出,并将屏幕变暗(省电啊)
  896. if ([[UIDevice currentDevice] proximityState] == YES)
  897. {
  898. NSLog(@"Device is close to user");
  899. [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
  900. }
  901. else
  902. {
  903. NSLog(@"Device is not close to user");
  904. [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
  905. }
  906. }
  907. /* if an error occurs while decoding it will be reported to the delegate. */
  908. - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *__nullable)error
  909. {
  910. [self stopPlayVoice:_nowplayingmsg];
  911. _nowplayingmsg = nil;
  912. }
  913. - (void)stopPlayVoice:(ConversationModel *)msg
  914. {
  915. msg.mIsPlaying = NO;
  916. NSUInteger ii = [self.mmsgdata indexOfObject:msg];
  917. if (ii == NSNotFound)
  918. {
  919. }
  920. else
  921. {
  922. [self.mtableview reloadData];
  923. return;
  924. NSIndexPath *iiii = [NSIndexPath indexPathForRow:ii inSection:0];
  925. [self.mtableview reloadRowsAtIndexPaths:@[iiii] withRowAnimation:UITableViewRowAnimationAutomatic];
  926. }
  927. }
  928. - (void)showGiftView
  929. {
  930. FWWeakify(self)
  931. [[IMAPlatform sharedInstance].host getMyInfo:^(AppBlockModel *blockModel) {
  932. FWStrongify(self)
  933. [(GiftView *) self.mGiftView setDiamondsLabelTxt:[NSString stringWithFormat:@"%ld", [[IMAPlatform sharedInstance].host getDiamonds]]];
  934. }];
  935. //隐藏背景的view
  936. // self.chatBar.moreView.hidden = YES;
  937. [self.chatBar.moreView hide];
  938. [self.chatBar.moreView setGiftView:NO];
  939. if (self.mGiftView == nil)
  940. return;
  941. if (!self.mGiftView.hidden)
  942. return;
  943. if (_doing)
  944. return;
  945. _doing = YES;
  946. CGRect ff = self.mGiftView.frame;
  947. ff.origin.y = ff.size.height * 1;
  948. self.mGiftView.frame = ff;
  949. if (self.mGiftView.superview == nil) [self.view addSubview:self.mGiftView];
  950. // [self.chatBar.moreView addSubview:self.mGiftView];
  951. self.mGiftView.hidden = NO;
  952. [UIView animateWithDuration:0.1f
  953. animations:^{
  954. CGRect fff = self.mGiftView.frame;
  955. fff.origin.y = kScreenH - KGiftViewHeight - MG_BOTTOM_MARGIN * 2;
  956. // 0;
  957. self.mGiftView.frame = fff;
  958. }
  959. completion:^(BOOL finished) {
  960. _doing = NO;
  961. }];
  962. }
  963. - (void)hidenGiftView
  964. {
  965. [self.chatBar.moreView setGiftView:YES];
  966. if (self.mGiftView == nil)
  967. return;
  968. if (self.mGiftView.hidden)
  969. return;
  970. if (_doing)
  971. return;
  972. _doing = YES;
  973. [UIView animateWithDuration:0.1f
  974. animations:^{
  975. CGRect fff = self.mGiftView.frame;
  976. fff.origin.y = kScreenH;
  977. // fff.size.height * 1;
  978. self.mGiftView.frame = fff;
  979. }
  980. completion:^(BOOL finished) {
  981. self.mGiftView.hidden = YES;
  982. _doing = NO;
  983. }];
  984. }
  985. - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *, id> *)info
  986. {
  987. [picker dismissViewControllerAnimated:YES completion:nil];
  988. UIImage *tagimg = [info objectForKey:UIImagePickerControllerOriginalImage];
  989. CGSize imagesize = tagimg.size;
  990. if (tagimg.size.width>2000) {
  991. //设置image的尺寸
  992. imagesize.height = imagesize.height/4;
  993. imagesize.width = imagesize.width/4;
  994. }
  995. //对图片大小进行压缩--
  996. tagimg = [self imageWithImage:tagimg scaledToSize:imagesize];
  997. UIImageOrientation *imageOrientation = tagimg.imageOrientation;
  998. if (imageOrientation != UIImageOrientationUp) {
  999. // 原始图片可以根据照相时的角度来显示,但UIImage无法判定,于是出现获取的图片会向左转90度的现象。
  1000. // 以下为调整图片角度的部分
  1001. UIGraphicsBeginImageContext(tagimg.size);
  1002. [tagimg drawInRect:CGRectMake(0, 0, tagimg.size.width, tagimg.size.height)];
  1003. tagimg = UIGraphicsGetImageFromCurrentImageContext();
  1004. UIGraphicsEndImageContext();
  1005. // 调整图片角度完毕
  1006. }
  1007. NSData *data;
  1008. data = UIImageJPEGRepresentation(tagimg, 0.5);//压缩图片的比例
  1009. UIImage *newImg = [UIImage imageWithData:data];
  1010. if (newImg == nil)
  1011. {
  1012. [SVProgressHUD showErrorWithStatus:ASLocalizedString(@"图片无效!请重新选择")];
  1013. return;
  1014. }
  1015. [self willSendThisImg:newImg];
  1016. }
  1017. //对图片尺寸进行压缩
  1018. -(UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize
  1019. {
  1020. // Create a graphics image context
  1021. UIGraphicsBeginImageContext(newSize);
  1022. // Tell the old image to draw in this new context, with the desired
  1023. // new size
  1024. [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
  1025. // Get the new image from the context
  1026. UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
  1027. // End the context
  1028. UIGraphicsEndImageContext();
  1029. // Return the new image.
  1030. return newImage;
  1031. }
  1032. - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
  1033. {
  1034. [picker dismissViewControllerAnimated:YES completion:nil];
  1035. }
  1036. - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
  1037. {
  1038. if (textView == self.chatBar.textView)
  1039. {
  1040. if ([text isEqualToString:@"\n"])
  1041. {
  1042. if (textView.text.length == 0)
  1043. {
  1044. [SVProgressHUD showErrorWithStatus:ASLocalizedString(@"请先输入发送内容")];
  1045. return NO;
  1046. }
  1047. [self willSendThisText:[self.chatBar.textView getSendTextStr]];
  1048. return NO;
  1049. }
  1050. }
  1051. return YES;
  1052. }
  1053. #pragma mark 录音操作开始
  1054. - (void)onTouchRecordBtnDown:(id)sender
  1055. {
  1056. [self showRecSV:1];
  1057. [self startRecordeAudio];
  1058. }
  1059. - (void)onTouchRecordBtnUpInside:(id)sender
  1060. {
  1061. // finish Recording
  1062. //self.recordPhase = AudioRecordPhaseEnd;
  1063. [self showRecSV:4];
  1064. _brecwillsend = YES;
  1065. [self stopRecordeAudio];
  1066. }
  1067. - (void)onTouchRecordBtnUpOutside:(id)sender
  1068. {
  1069. //TODO cancel Recording
  1070. //self.recordPhase = AudioRecordPhaseEnd;
  1071. [self showRecSV:4];
  1072. _brecwillsend = NO;
  1073. [self stopRecordeAudio];
  1074. }
  1075. - (void)onTouchRecordBtnDragInside:(id)sender
  1076. {
  1077. //TODO ASLocalizedString(@"手指上滑,取消发送")//self.recordPhase = AudioRecordPhaseRecording;
  1078. [self showRecSV:3];
  1079. }
  1080. - (void)onTouchRecordBtnDragOutside:(id)sender
  1081. {
  1082. //TODO ASLocalizedString(@"松开手指,取消发送")//self.recordPhase = AudioRecordPhaseCancelling;
  1083. [self showRecSV:2];
  1084. }
  1085. //status 1 开始了,,2 显示上滑什么,,,3 显示取消 4 移除..
  1086. - (void)showRecSV:(int)status
  1087. {
  1088. if (status == 4)
  1089. {
  1090. [_recshowing removeFromSuperview];
  1091. _recshowing = nil;
  1092. return;
  1093. }
  1094. if (_recshowing == nil)
  1095. {
  1096. _recshowing = [[ChatAudioRecordNoticeView alloc] init];
  1097. [self.view addSubview:_recshowing];
  1098. if (_mbhalf == YES)
  1099. {
  1100. [_recshowing mas_makeConstraints:^(MASConstraintMaker *make) {
  1101. make.top.equalTo(self.view).with.offset(70);
  1102. make.left.equalTo(self.view).with.offset(kScreenW / 2 - 80);
  1103. }];
  1104. }
  1105. else
  1106. {
  1107. _recshowing.center = self.view.center;
  1108. }
  1109. }
  1110. _recshowing.mstatus = status;
  1111. }
  1112. #pragma mark 录音API操作这里可能会影响APP
  1113. - (void)startRecordeAudio
  1114. {
  1115. if (_recorder.recording)
  1116. return;
  1117. if (![self canRecord])
  1118. {
  1119. [SVProgressHUD showErrorWithStatus:ASLocalizedString(@"获取麦克风权限失败")];
  1120. return;
  1121. }
  1122. AVAudioSession *session = [AVAudioSession sharedInstance];
  1123. if (![session.category isEqualToString:AVAudioSessionCategoryPlayAndRecord] ||
  1124. ![session.category isEqualToString:AVAudioSessionCategoryRecord])
  1125. {
  1126. if (![session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil])
  1127. {
  1128. [SVProgressHUD showErrorWithStatus:ASLocalizedString(@"录音失败")];
  1129. return;
  1130. }
  1131. if (![session setActive:YES error:nil])
  1132. {
  1133. [SVProgressHUD showErrorWithStatus:ASLocalizedString(@"录音失败")];
  1134. return;
  1135. }
  1136. }
  1137. NSMutableDictionary *recordSetting = NSMutableDictionary.new;
  1138. //设置录音格式 AVFormatIDKey==kAudioFormatLinearPCM
  1139. [recordSetting setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
  1140. //设置录音采样率(Hz) 如:AVSampleRateKey==8000/44100/96000(影响音频的质量)
  1141. [recordSetting setValue:[NSNumber numberWithFloat:44100] forKey:AVSampleRateKey];
  1142. //录音通道数 1 或 2
  1143. [recordSetting setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];
  1144. //线性采样位数 8、16、24、32
  1145. [recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
  1146. //录音的质量
  1147. [recordSetting setValue:[NSNumber numberWithInt:AVAudioQualityHigh] forKey:AVEncoderAudioQualityKey];
  1148. NSError *error = nil;
  1149. _recorder = [[AVAudioRecorder alloc] initWithURL:[self makerecfilepath] settings:recordSetting error:&error];
  1150. _recorder.delegate = self;
  1151. if (_recorder == nil || ![_recorder prepareToRecord])
  1152. {
  1153. [SVProgressHUD showErrorWithStatus:ASLocalizedString(@"录音失败")];
  1154. return;
  1155. }
  1156. if (![_recorder recordForDuration:60.0f])
  1157. {
  1158. [SVProgressHUD showErrorWithStatus:ASLocalizedString(@"录音失败")];
  1159. return;
  1160. }
  1161. [_timer invalidate];
  1162. _timer = nil;
  1163. _timer = [NSTimer scheduledTimerWithTimeInterval:0.5f target:self selector:@selector(timersel) userInfo:nil repeats:YES];
  1164. _recduration = 0.0f;
  1165. }
  1166. - (void)timersel
  1167. {
  1168. _recshowing.recordTime = _recorder.currentTime;
  1169. _recduration += _timer.timeInterval;
  1170. }
  1171. - (BOOL)canRecord
  1172. {
  1173. __block BOOL bCanRecord = YES;
  1174. AVAudioSession *audioSession = [AVAudioSession sharedInstance];
  1175. if ([audioSession respondsToSelector:@selector(requestRecordPermission:)])
  1176. {
  1177. [audioSession performSelector:@selector(requestRecordPermission:)
  1178. withObject:^(BOOL granted) {
  1179. if (granted)
  1180. {
  1181. bCanRecord = YES;
  1182. }
  1183. else
  1184. {
  1185. bCanRecord = NO;
  1186. }
  1187. }];
  1188. }
  1189. return bCanRecord;
  1190. }
  1191. - (void)stopRecordeAudio
  1192. {
  1193. [_recorder stop];
  1194. }
  1195. - (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag
  1196. {
  1197. if (_brecwillsend)
  1198. {
  1199. [self willSendThisVoice:recorder.url duration:_recduration];
  1200. }
  1201. [_timer invalidate];
  1202. _timer = nil;
  1203. }
  1204. - (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *__nullable)error
  1205. {
  1206. [SVProgressHUD showErrorWithStatus:ASLocalizedString(@"录音失败")];
  1207. [_timer invalidate];
  1208. _timer = nil;
  1209. }
  1210. - (NSURL *)makerecfilepath
  1211. {
  1212. NSString *urlStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
  1213. urlStr = [urlStr stringByAppendingPathComponent:[NSString stringWithFormat:@"recfile_%ld.acc", (NSInteger)[[NSDate date] timeIntervalSince1970]]];
  1214. NSURL *url = [NSURL fileURLWithPath:urlStr];
  1215. return url;
  1216. }
  1217. #pragma mark 录音操作结束
  1218. #pragma mark chatBarDelegate
  1219. - (void)chatBarFrameDidChange:(ChatBottomBarView *)chatBar shouldScrollToBottom:(CGFloat)keyBoardHeight showType:(FWChatBarShowType)showType showAnimationTime:(CGFloat)showAnimationTime
  1220. {
  1221. if (_haveLiveExist == NO)
  1222. {
  1223. if (showType == FWChatBarShowTypeMore) {
  1224. UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, 234, 0);
  1225. _mtableview.scrollEnabled = YES;
  1226. _mtableview.contentInset = contentInsets;
  1227. _mtableview.scrollIndicatorInsets = contentInsets;
  1228. [self scrollToBottomAnimated:YES animatedTime:showAnimationTime];
  1229. // [_chatBar mas_updateConstraints:^(MASConstraintMaker *make) {
  1230. // make.bottom.mas_equalTo(-self.chatBar.moreView.height);
  1231. // }];
  1232. }
  1233. if (showType == FWChatBarShowTypeFace )
  1234. {
  1235. UIEdgeInsets contentInsets = UIEdgeInsetsZero;
  1236. // UIEdgeInsetsMake(0.0, 0.0, 234, 0.0);
  1237. _mtableview.scrollEnabled = YES;
  1238. _mtableview.contentInset = contentInsets;
  1239. _mtableview.scrollIndicatorInsets = contentInsets;
  1240. [self scrollToBottomAnimated:YES animatedTime:showAnimationTime];
  1241. }
  1242. else if (showType == FWChatBarShowTypeNothing)
  1243. {
  1244. UIEdgeInsets contentInsets = UIEdgeInsetsZero;
  1245. _mtableview.contentInset = contentInsets;
  1246. _mtableview.scrollIndicatorInsets = contentInsets;
  1247. // [_chatBar.inputBarBackgroundView mas_updateConstraints:^(MASConstraintMaker *make) {
  1248. // make.bottom.mas_equalTo(-MG_BOTTOM_MARGIN - 10);
  1249. // }];
  1250. }
  1251. else if (showType == FWChatBarShowTypeKeyboard)
  1252. {
  1253. // UIEdgeInsets contentInsets = UIEdgeInsetsZero;
  1254. UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, 20, 0);
  1255. _mtableview.contentInset = contentInsets;
  1256. _mtableview.scrollIndicatorInsets = contentInsets;
  1257. [self scrollToBottomAnimated:YES animatedTime:showAnimationTime];
  1258. [_chatBar.inputBarBackgroundView mas_updateConstraints:^(MASConstraintMaker *make) {
  1259. make.bottom.mas_equalTo(-MG_BOTTOM_MARGIN - 10);
  1260. }];
  1261. }
  1262. else if (showType == FWChatBarShowTypeVoice)
  1263. {
  1264. UIEdgeInsets contentInsets = UIEdgeInsetsZero;
  1265. _mtableview.contentInset = contentInsets;
  1266. _mtableview.scrollIndicatorInsets = contentInsets;
  1267. }
  1268. }
  1269. else
  1270. {
  1271. if (showType == FWChatBarShowTypeFace || showType == FWChatBarShowTypeMore)
  1272. {
  1273. UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, 234, 0.0);
  1274. _mtableview.scrollEnabled = YES;
  1275. _mtableview.contentInset = contentInsets;
  1276. _mtableview.scrollIndicatorInsets = contentInsets;
  1277. [_chatBar.textView resignFirstResponder];
  1278. [self scrollToBottomAnimated:YES animatedTime:0.5];
  1279. [self faceAndMoreKeyboardBtnClickWith:YES isNotHaveBothKeyboard:NO keyBoardHeight:234];
  1280. }
  1281. else if (showType == FWChatBarShowTypeNothing)
  1282. {
  1283. UIEdgeInsets contentInsets = UIEdgeInsetsZero;
  1284. _mtableview.contentInset = contentInsets;
  1285. _mtableview.scrollIndicatorInsets = contentInsets;
  1286. [_chatBar.textView resignFirstResponder];
  1287. [self faceAndMoreKeyboardBtnClickWith:NO isNotHaveBothKeyboard:NO keyBoardHeight:keyBoardHeight];
  1288. }
  1289. else if (showType == FWChatBarShowTypeKeyboard)
  1290. {
  1291. UIEdgeInsets contentInsets = UIEdgeInsetsZero;
  1292. _mtableview.contentInset = contentInsets;
  1293. _mtableview.scrollIndicatorInsets = contentInsets;
  1294. [self scrollToBottomAnimated:YES animatedTime:showAnimationTime];
  1295. [self faceAndMoreKeyboardBtnClickWith:NO isNotHaveBothKeyboard:YES keyBoardHeight:keyBoardHeight];
  1296. }
  1297. else if (showType == FWChatBarShowTypeVoice)
  1298. {
  1299. UIEdgeInsets contentInsets = UIEdgeInsetsZero;
  1300. _mtableview.contentInset = contentInsets;
  1301. _mtableview.scrollIndicatorInsets = contentInsets;
  1302. [self faceAndMoreKeyboardBtnClickWith:NO isNotHaveBothKeyboard:NO keyBoardHeight:keyBoardHeight];
  1303. }
  1304. }
  1305. [self.chatBar updateChatBarConstraintsIfNeededShouldCacheText:YES];
  1306. [self hidenGiftView];
  1307. }
  1308. - (void)scrollToBottomAnimated:(BOOL)animated animatedTime:(CGFloat)animatedTime
  1309. {
  1310. NSInteger rows = [self.mtableview numberOfRowsInSection:0];
  1311. if (rows > 0)
  1312. {
  1313. dispatch_block_t scrollBottomBlock = ^{
  1314. [self.mtableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:rows - 1 inSection:0]
  1315. atScrollPosition:UITableViewScrollPositionBottom
  1316. animated:animated];
  1317. };
  1318. if (animated)
  1319. {
  1320. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(animatedTime/30 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  1321. scrollBottomBlock();
  1322. });
  1323. }
  1324. else
  1325. {
  1326. scrollBottomBlock();
  1327. }
  1328. }
  1329. }
  1330. #pragma mark - chat Emoji View Delegate
  1331. - (void)chatEmojiViewSelectEmojiIcon:(EmojiObj *)objIcon
  1332. {
  1333. NSCharacterSet *nonDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
  1334. int emojiID = [[objIcon.emojiName stringByTrimmingCharactersInSet:nonDigits] intValue];
  1335. [self.chatBar.textView appendFace:emojiID];
  1336. [self.chatBar updateChatBarConstraintsIfNeededShouldCacheText:YES];
  1337. }
  1338. - (void)chatEmojiViewTouchUpinsideDeleteButton
  1339. {
  1340. //点击了删除表情
  1341. if (self.chatBar.textView.text.length > 0)
  1342. {
  1343. NSRange range = self.chatBar.textView.selectedRange;
  1344. NSInteger location = (NSInteger) range.location;
  1345. if (location == 0)
  1346. {
  1347. return;
  1348. }
  1349. range.location = location - 1;
  1350. range.length = 1;
  1351. NSMutableAttributedString *attStr = [self.chatBar.textView.attributedText mutableCopy];
  1352. [attStr deleteCharactersInRange:range];
  1353. self.chatBar.textView.attributedText = attStr;
  1354. self.chatBar.textView.selectedRange = range;
  1355. }
  1356. }
  1357. - (void)chatEmojiViewTouchDownDeleteButton
  1358. {
  1359. self.chatBar.textView.text = nil;
  1360. [self.chatBar updateChatBarConstraintsIfNeededShouldCacheText:YES];
  1361. }
  1362. - (void)chatEmojiViewTouchUpinsideSendButton
  1363. {
  1364. //表情键盘:点击发送表情
  1365. if (self.chatBar.textView.text.length == 0)
  1366. {
  1367. [SVProgressHUD showErrorWithStatus:ASLocalizedString(@"请先输入发送内容")];
  1368. }
  1369. else
  1370. {
  1371. [self willSendThisText:[self.chatBar.textView getSendTextStr]];
  1372. }
  1373. }
  1374. -(void)clickHide{
  1375. self.chatBar.showType = FWChatBarShowTypeNothing;
  1376. }
  1377. #pragma mark - chat More View Delegate
  1378. - (void)chatMoreViewButton:(NSInteger)btnIndex
  1379. {
  1380. NSInteger index;
  1381. if (_haveLiveExist)
  1382. {
  1383. if (btnIndex != 1000)
  1384. {
  1385. index = btnIndex + 1;
  1386. }
  1387. else
  1388. {
  1389. index = btnIndex;
  1390. }
  1391. }
  1392. else
  1393. {
  1394. index = btnIndex;
  1395. }
  1396. if (index == 1000)
  1397. {
  1398. UIImagePickerController *picker = [[UIImagePickerController alloc] init];
  1399. if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum])
  1400. {
  1401. picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
  1402. picker.delegate = self;
  1403. picker.modalPresentationStyle = UIModalPresentationOverCurrentContext;
  1404. }
  1405. [self presentViewController:picker animated:YES completion:nil];
  1406. }
  1407. else if (index == 1001)
  1408. {
  1409. UIImagePickerController *picker = [[UIImagePickerController alloc] init];
  1410. if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
  1411. {
  1412. picker.sourceType = UIImagePickerControllerSourceTypeCamera;
  1413. picker.delegate = self;
  1414. picker.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
  1415. }
  1416. [self presentViewController:picker animated:YES completion:nil];
  1417. }
  1418. else if (index == 1002)
  1419. {
  1420. [self showGiftView];
  1421. }
  1422. else if (index == 1003)
  1423. {
  1424. [self applyAudioMethod];
  1425. }
  1426. else if (index == 1004)
  1427. {
  1428. [self applyVideoMethod];
  1429. } else if (index == 1005) {
  1430. if (self.BuguLive.appModel.open_send_coins_module == 1)
  1431. {
  1432. [self sendCoin];
  1433. }
  1434. else if (self.BuguLive.appModel.open_send_diamonds_module == 1)
  1435. {
  1436. [self sendDiamonds];
  1437. }
  1438. } else if (index == 1006) {
  1439. [self sendDiamonds];
  1440. }
  1441. }
  1442. #pragma mark - ********** 语音 ***********
  1443. - (void)applyAudioMethod {
  1444. }
  1445. #pragma mark - ********** 视频 ***********
  1446. - (void)applyVideoMethod {
  1447. }
  1448. //ykk825 face 代理方法
  1449. - (void)faceAndMoreKeyboardBtnClickWith:(BOOL)isFace isNotHaveBothKeyboard:(BOOL)isHave keyBoardHeight:(CGFloat)height
  1450. {
  1451. if (self.mbhalf == YES)
  1452. {
  1453. if ([self.delegate respondsToSelector:@selector(faceAndMoreKeyboardBtnClickWith:isNotHaveBothKeyboard:keyBoardHeight:)])
  1454. {
  1455. [self.delegate faceAndMoreKeyboardBtnClickWith:isFace isNotHaveBothKeyboard:isHave keyBoardHeight:height];
  1456. }
  1457. }
  1458. }
  1459. - (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldReceiveTouch:(UITouch*)touch
  1460. {
  1461. CGPoint point = [touch locationInView:self.view];
  1462. if ([touch.view isKindOfClass:[UIButton class]]) {
  1463. return YES;
  1464. }
  1465. if( point.y > self.chatBar.frame.origin.y )
  1466. {//只要点击了在输入框的下面...这种就放过...
  1467. return NO;
  1468. }
  1469. // if ([touch.view isKindOfClass:[UIButton class]] || [touch.view isKindOfClass:[RechargeWayView class]] || [touch.view isKindOfClass:[RechargeView class]]) {//充值界面出来时,不隐藏giftview
  1470. // return NO;
  1471. // }
  1472. if ([touch.view isKindOfClass:[UIButton class]] || [touch.view isKindOfClass:[ChatBarTextView class]]) {
  1473. return NO;
  1474. }
  1475. if (self.mrechargeView.hidden == NO && self.mrechargeView) {
  1476. self.mGiftView.hidden = NO;
  1477. return NO;
  1478. }
  1479. if (!self.mGiftView.hidden && [touch.view isKindOfClass:NSClassFromString(@"UITableViewCellContentView")]) {
  1480. [self hidenGiftView];
  1481. return YES;
  1482. }
  1483. if ([touch.view isKindOfClass:[ChatEmojiView class]]) {
  1484. return NO;
  1485. }
  1486. if (self.chatBar.showType == FWChatBarShowTypeMore || self.chatBar.showType == FWChatBarShowTypeFace) {
  1487. [self hideChatBar];
  1488. return YES;
  1489. }
  1490. //下面的点击 都是在 输入框的上面,,,就是点击了tablewview的范围
  1491. if( self.chatBar.textView.isFirstResponder )
  1492. {//键盘开启的,就关闭键盘,,,
  1493. [self.chatBar.textView resignFirstResponder];
  1494. return YES;
  1495. }
  1496. //下面是判断 CELL的点击位置..
  1497. point = [touch locationInView:self.mtableview];
  1498. NSIndexPath * indexpath = [self.mtableview indexPathForRowAtPoint:point];
  1499. UITableViewCell* cell = [self.mtableview cellForRowAtIndexPath:indexpath];
  1500. UIView* msgbodyrect = [cell viewWithTag:99];
  1501. point = [touch locationInView:cell];
  1502. if( CGRectContainsPoint(msgbodyrect.frame,point) )
  1503. {//在消息体的范围,就允许响应tableview的 didselectrow...
  1504. return NO;
  1505. }
  1506. UIView* failedicon = [cell viewWithTag:98];
  1507. if( CGRectContainsPoint(failedicon.frame,point) )
  1508. {
  1509. [self failedIconTouched:indexpath iconhiden:failedicon.hidden];
  1510. }
  1511. return YES;
  1512. }
  1513. - (void)taprootview:(UITapGestureRecognizer*)sender
  1514. {
  1515. if (self.clickBGBlock) {
  1516. self.clickBGBlock(YES);
  1517. }
  1518. }
  1519. - (void)hideChatBar
  1520. {
  1521. [_chatBar hideChatBottomBar];
  1522. }
  1523. - (void)doubleTapScrollToTop:(UIGestureRecognizer*)gestureRecognizer
  1524. {
  1525. if (_mmsgdata.count)
  1526. {
  1527. [self.mtableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
  1528. atScrollPosition:UITableViewScrollPositionTop
  1529. animated:YES];
  1530. }
  1531. }
  1532. //
  1533. //- (ChatEmojiView *)emojiView
  1534. //{
  1535. // if (!_emojiView)
  1536. // {
  1537. // ChatEmojiView *emojiView = [[ChatEmojiView alloc] init];
  1538. // emojiView.hidden = YES;
  1539. // emojiView.backgroundColor = [UIColor whiteColor];
  1540. //// [self addSubview:(_emojiView = emojiView)];
  1541. // }
  1542. // return _emojiView;
  1543. //}
  1544. @end