IMChatViewController.swift 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. //
  2. // IMChatViewController.swift
  3. // O2Platform
  4. //
  5. // Created by FancyLou on 2020/6/8.
  6. // Copyright © 2020 zoneland. All rights reserved.
  7. //
  8. import UIKit
  9. import CocoaLumberjack
  10. import O2OA_Auth_SDK
  11. import BSImagePicker
  12. import Photos
  13. import Alamofire
  14. import AlamofireImage
  15. import SwiftyJSON
  16. import QuickLook
  17. class IMChatViewController: UIViewController {
  18. // MARK: - IBOutlet
  19. //消息列表
  20. @IBOutlet weak var tableView: UITableView!
  21. //消息输入框
  22. @IBOutlet weak var messageInputView: UITextField!
  23. //底部工具栏的高度约束
  24. @IBOutlet weak var bottomBarHeightConstraint: NSLayoutConstraint!
  25. //底部工具栏
  26. @IBOutlet weak var bottomBar: UIView!
  27. private let emojiBarHeight = 196
  28. //表情窗口
  29. private lazy var emojiBar: IMChatEmojiBarView = {
  30. let view = Bundle.main.loadNibNamed("IMChatEmojiBarView", owner: self, options: nil)?.first as! IMChatEmojiBarView
  31. view.frame = CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: emojiBarHeight.toCGFloat)
  32. return view
  33. }()
  34. //语音录制按钮
  35. private lazy var audioBtnView: IMChatAudioView = {
  36. let view = Bundle.main.loadNibNamed("IMChatAudioView", owner: self, options: nil)?.first as! IMChatAudioView
  37. view.frame = CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: emojiBarHeight.toCGFloat)
  38. view.delegate = self
  39. return view
  40. }()
  41. //预览文件
  42. private lazy var previewVC: CloudFilePreviewController = {
  43. return CloudFilePreviewController()
  44. }()
  45. private lazy var viewModel: IMViewModel = {
  46. return IMViewModel()
  47. }()
  48. // MARK: - properties
  49. var conversation: IMConversationInfo? = nil
  50. private var chatMessageList: [IMMessageInfo] = []
  51. private var page = 1
  52. private var isShowEmoji = false
  53. private var isShowAudioView = false
  54. private var bottomBarHeight = 64 //底部输入框 表情按钮 的高度
  55. private let bottomToolbarHeight = 46 //底部工具栏 麦克风 相册 相机等按钮的位置
  56. // MARK: - functions
  57. override func viewDidLoad() {
  58. super.viewDidLoad()
  59. self.tableView.delegate = self
  60. self.tableView.dataSource = self
  61. self.tableView.register(UINib(nibName: "IMChatMessageViewCell", bundle: nil), forCellReuseIdentifier: "IMChatMessageViewCell")
  62. self.tableView.register(UINib(nibName: "IMChatMessageSendViewCell", bundle: nil), forCellReuseIdentifier: "IMChatMessageSendViewCell")
  63. self.tableView.separatorStyle = .none
  64. self.tableView.rowHeight = UITableView.automaticDimension
  65. self.tableView.estimatedRowHeight = 144
  66. self.messageInputView.delegate = self
  67. //底部安全距离 老机型没有
  68. self.bottomBarHeight = Int(iPhoneX ? 64 + IPHONEX_BOTTOM_SAFE_HEIGHT: 64) + self.bottomToolbarHeight
  69. self.bottomBarHeightConstraint.constant = self.bottomBarHeight.toCGFloat
  70. self.bottomBar.topBorder(width: 1, borderColor: base_gray_color.alpha(0.5))
  71. self.messageInputView.backgroundColor = base_gray_color
  72. //标题
  73. if self.conversation?.type == o2_im_conversation_type_single {
  74. if let c = self.conversation {
  75. var person = ""
  76. c.personList?.forEach({ (p) in
  77. if p != O2AuthSDK.shared.myInfo()?.distinguishedName {
  78. person = p
  79. }
  80. })
  81. if !person.isEmpty {
  82. self.title = person.split("@").first ?? ""
  83. }
  84. }
  85. } else {
  86. self.title = self.conversation?.title
  87. }
  88. //获取聊天数据
  89. self.loadMsgList(page: page)
  90. //阅读
  91. self.viewModel.readConversation(conversationId: self.conversation?.id)
  92. }
  93. override func viewWillAppear(_ animated: Bool) {
  94. NotificationCenter.default.addObserver(self, selector: #selector(receiveMessageFromWs(notice:)), name: OONotification.websocket.notificationName, object: nil)
  95. }
  96. override func viewWillDisappear(_ animated: Bool) {
  97. NotificationCenter.default.removeObserver(self)
  98. }
  99. @objc private func receiveMessageFromWs(notice: Notification) {
  100. DDLogDebug("接收到websocket im 消息")
  101. if let message = notice.object as? IMMessageInfo {
  102. if message.conversationId == self.conversation?.id {
  103. self.chatMessageList.append(message)
  104. self.scrollMessageToBottom()
  105. self.viewModel.readConversation(conversationId: self.conversation?.id)
  106. }
  107. }
  108. }
  109. //获取消息
  110. private func loadMsgList(page: Int) {
  111. if let c = self.conversation, let id = c.id {
  112. self.viewModel.myMsgPageList(page: page, conversationId: id).then { (list) in
  113. self.chatMessageList = list
  114. self.scrollMessageToBottom()
  115. }
  116. } else {
  117. self.showError(title: "参数错误!!!")
  118. }
  119. }
  120. //刷新tableview 滚动到底部
  121. private func scrollMessageToBottom() {
  122. DispatchQueue.main.async {
  123. self.tableView.reloadData()
  124. if self.chatMessageList.count > 0 {
  125. self.tableView.scrollToRow(at: IndexPath(row: self.chatMessageList.count - 1, section: 0), at: .bottom, animated: true)
  126. }
  127. }
  128. }
  129. //发送文本消息
  130. private func sendTextMessage() {
  131. guard let msg = self.messageInputView.text else {
  132. return
  133. }
  134. self.messageInputView.text = ""
  135. let body = IMMessageBodyInfo()
  136. body.type = o2_im_msg_type_text
  137. body.body = msg
  138. sendMessage(body: body)
  139. }
  140. //发送表情消息
  141. private func sendEmojiMessage(emoji: String) {
  142. let body = IMMessageBodyInfo()
  143. body.type = o2_im_msg_type_emoji
  144. body.body = emoji
  145. sendMessage(body: body)
  146. }
  147. //发送地图消息消息
  148. private func sendLocationMessage(loc: O2LocationData) {
  149. let body = IMMessageBodyInfo()
  150. body.type = o2_im_msg_type_location
  151. body.body = o2_im_msg_body_location
  152. body.address = loc.address
  153. body.addressDetail = loc.addressDetail
  154. body.longitude = loc.longitude
  155. body.latitude = loc.latitude
  156. sendMessage(body: body)
  157. }
  158. //发送消息到服务器
  159. private func sendMessage(body: IMMessageBodyInfo) {
  160. let message = IMMessageInfo()
  161. message.body = body.toJSONString()
  162. message.id = UUID().uuidString
  163. message.conversationId = self.conversation?.id
  164. message.createPerson = O2AuthSDK.shared.myInfo()?.distinguishedName
  165. message.createTime = Date().formatterDate(formatter: "yyyy-MM-dd HH:mm:ss")
  166. //添加到界面
  167. self.chatMessageList.append(message)
  168. self.scrollMessageToBottom()
  169. //发送消息到服务器
  170. self.viewModel.sendMsg(msg: message)
  171. .then { (result) in
  172. DDLogDebug("发送消息成功 \(result)")
  173. self.viewModel.readConversation(conversationId: self.conversation?.id)
  174. }.catch { (error) in
  175. DDLogError(error.localizedDescription)
  176. self.showError(title: "发送消息失败!")
  177. }
  178. }
  179. //选择照片
  180. private func chooseImage() {
  181. let vc = FileBSImagePickerViewController().bsImagePicker()
  182. vc.settings.fetch.assets.supportedMediaTypes = [.image]
  183. presentImagePicker(vc, select: { (asset) in
  184. //选中一个
  185. }, deselect: { (asset) in
  186. //取消选中一个
  187. }, cancel: { (assets) in
  188. //取消
  189. }, finish: { (assets) in
  190. //结果
  191. if assets.count > 0 {
  192. switch assets[0].mediaType {
  193. case .image:
  194. let options = PHImageRequestOptions()
  195. options.isSynchronous = true
  196. options.deliveryMode = .fastFormat
  197. options.resizeMode = .none
  198. PHImageManager.default().requestImageData(for: assets[0], options: options) { (imageData, result, imageOrientation, dict) in
  199. guard let data = imageData else {
  200. return
  201. }
  202. var newData = data
  203. //处理图片旋转的问题
  204. if imageOrientation != UIImage.Orientation.up {
  205. let newImage = UIImage(data: data)?.fixOrientation()
  206. if newImage != nil {
  207. newData = newImage!.pngData()!
  208. }
  209. }
  210. var fileName = ""
  211. if dict?["PHImageFileURLKey"] != nil {
  212. let fileURL = dict?["PHImageFileURLKey"] as! URL
  213. fileName = fileURL.lastPathComponent
  214. } else {
  215. fileName = "\(UUID().uuidString).png"
  216. }
  217. let localFilePath = self.storageLocalImage(imageData: newData, fileName: fileName)
  218. let msgId = self.prepareForSendImageMsg(filePath: localFilePath)
  219. self.uploadImageAndSendMsg(messageId: msgId, imageData: newData, fileName: fileName)
  220. }
  221. break
  222. default:
  223. //
  224. DDLogError("不支持的类型")
  225. self.showError(title: "不支持的类型!")
  226. break
  227. }
  228. }
  229. }, completion: nil)
  230. }
  231. //临时存储本地
  232. private func storageLocalImage(imageData: Data, fileName: String) -> String {
  233. let fileTempPath = FileUtil.share.cacheDir().appendingPathComponent(fileName)
  234. do {
  235. try imageData.write(to: fileTempPath)
  236. return fileTempPath.path
  237. } catch {
  238. print(error.localizedDescription)
  239. return fileTempPath.path
  240. }
  241. }
  242. //发送消息前 先载入界面
  243. private func prepareForSendImageMsg(filePath: String) -> String {
  244. let body = IMMessageBodyInfo()
  245. body.type = o2_im_msg_type_image
  246. body.body = o2_im_msg_body_image
  247. body.fileTempPath = filePath
  248. let message = IMMessageInfo()
  249. let msgId = UUID().uuidString
  250. message.body = body.toJSONString()
  251. message.id = msgId
  252. message.conversationId = self.conversation?.id
  253. message.createPerson = O2AuthSDK.shared.myInfo()?.distinguishedName
  254. message.createTime = Date().formatterDate(formatter: "yyyy-MM-dd HH:mm:ss")
  255. //添加到界面
  256. self.chatMessageList.append(message)
  257. self.scrollMessageToBottom()
  258. return msgId
  259. }
  260. //发送消息前 先载入界面
  261. private func prepareForSendFileMsg(tempMessage: IMMessageBodyInfo) -> String {
  262. let message = IMMessageInfo()
  263. let msgId = UUID().uuidString
  264. message.body = tempMessage.toJSONString()
  265. message.id = msgId
  266. message.conversationId = self.conversation?.id
  267. message.createPerson = O2AuthSDK.shared.myInfo()?.distinguishedName
  268. message.createTime = Date().formatterDate(formatter: "yyyy-MM-dd HH:mm:ss")
  269. //添加到界面
  270. self.chatMessageList.append(message)
  271. self.scrollMessageToBottom()
  272. return msgId
  273. }
  274. //上传图片到服务器并发送消息
  275. private func uploadImageAndSendMsg(messageId: String, imageData: Data, fileName: String) {
  276. guard let cId = self.conversation?.id else {
  277. return
  278. }
  279. self.viewModel.uploadFile(conversationId: cId, type: o2_im_msg_type_image, fileName: fileName, file: imageData).then { attachId in
  280. DDLogDebug("上传图片成功: \(attachId)")
  281. guard let message = self.chatMessageList.first (where: { (info) -> Bool in
  282. return info.id == messageId
  283. }) else {
  284. DDLogDebug("没有找到对应的消息")
  285. return
  286. }
  287. let body = IMMessageBodyInfo.deserialize(from: message.body)
  288. body?.fileId = attachId
  289. body?.fileTempPath = nil
  290. message.body = body?.toJSONString()
  291. //发送消息到服务器
  292. self.viewModel.sendMsg(msg: message)
  293. .then { (result) in
  294. DDLogDebug("图片消息 发送成功 \(result)")
  295. self.viewModel.readConversation(conversationId: self.conversation?.id)
  296. }.catch { (error) in
  297. DDLogError(error.localizedDescription)
  298. self.showError(title: "发送消息失败!")
  299. }
  300. }.catch { err in
  301. self.showError(title: "上传错误,\(err.localizedDescription)")
  302. }
  303. }
  304. //上传图片 音频 等文件到服务器并发送消息
  305. private func uploadFileAndSendMsg(messageId: String, data: Data, fileName: String, type: String) {
  306. guard let cId = self.conversation?.id else {
  307. return
  308. }
  309. self.viewModel.uploadFile(conversationId: cId, type: type, fileName: fileName, file: data).then { attachId in
  310. DDLogDebug("上传图片成功: \(attachId)")
  311. guard let message = self.chatMessageList.first (where: { (info) -> Bool in
  312. return info.id == messageId
  313. }) else {
  314. DDLogDebug("没有找到对应的消息")
  315. return
  316. }
  317. let body = IMMessageBodyInfo.deserialize(from: message.body)
  318. body?.fileId = attachId
  319. body?.fileTempPath = nil
  320. message.body = body?.toJSONString()
  321. //发送消息到服务器
  322. self.viewModel.sendMsg(msg: message)
  323. .then { (result) in
  324. DDLogDebug("图片消息 发送成功 \(result)")
  325. self.viewModel.readConversation(conversationId: self.conversation?.id)
  326. }.catch { (error) in
  327. DDLogError(error.localizedDescription)
  328. self.showError(title: "发送消息失败!")
  329. }
  330. }.catch { err in
  331. self.showError(title: "上传错误,\(err.localizedDescription)")
  332. }
  333. }
  334. // MARK: - IBAction
  335. //点击表情按钮
  336. @IBAction func clickEmojiBtn(_ sender: UIButton) {
  337. self.isShowEmoji.toggle()
  338. self.view.endEditing(true)
  339. if self.isShowEmoji {
  340. //audio view 先关闭
  341. self.isShowAudioView = false
  342. self.audioBtnView.removeFromSuperview()
  343. //开始添加emojiBar
  344. self.bottomBarHeightConstraint.constant = self.bottomBarHeight.toCGFloat + self.emojiBarHeight.toCGFloat
  345. self.emojiBar.delegate = self
  346. self.emojiBar.translatesAutoresizingMaskIntoConstraints = false
  347. self.bottomBar.addSubview(self.emojiBar)
  348. let top = NSLayoutConstraint(item: self.emojiBar, attribute: .top, relatedBy: .equal, toItem: self.emojiBar.superview!, attribute: .top, multiplier: 1, constant: CGFloat(self.bottomBarHeight))
  349. let width = NSLayoutConstraint(item: self.emojiBar, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: SCREEN_WIDTH)
  350. let height = NSLayoutConstraint(item: self.emojiBar, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: self.emojiBarHeight.toCGFloat)
  351. NSLayoutConstraint.activate([top, width, height])
  352. } else {
  353. self.bottomBarHeightConstraint.constant = self.bottomBarHeight.toCGFloat
  354. self.emojiBar.removeFromSuperview()
  355. }
  356. self.view.layoutIfNeeded()
  357. }
  358. @IBAction func micBtnClick(_ sender: UIButton) {
  359. DDLogDebug("点击了麦克风按钮")
  360. self.isShowAudioView.toggle()
  361. self.view.endEditing(true)
  362. if self.isShowAudioView {
  363. //emoji view 先关闭
  364. self.isShowEmoji = false
  365. self.emojiBar.removeFromSuperview()
  366. //开始添加emojiBar
  367. self.bottomBarHeightConstraint.constant = self.bottomBarHeight.toCGFloat + self.emojiBarHeight.toCGFloat
  368. self.audioBtnView.translatesAutoresizingMaskIntoConstraints = false
  369. self.bottomBar.addSubview(self.audioBtnView)
  370. let top = NSLayoutConstraint(item: self.audioBtnView, attribute: .top, relatedBy: .equal, toItem: self.audioBtnView.superview!, attribute: .top, multiplier: 1, constant: CGFloat(self.bottomBarHeight))
  371. let width = NSLayoutConstraint(item: self.audioBtnView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: SCREEN_WIDTH)
  372. let height = NSLayoutConstraint(item: self.audioBtnView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: self.emojiBarHeight.toCGFloat)
  373. NSLayoutConstraint.activate([top, width, height])
  374. } else {
  375. self.bottomBarHeightConstraint.constant = self.bottomBarHeight.toCGFloat
  376. self.audioBtnView.removeFromSuperview()
  377. }
  378. self.view.layoutIfNeeded()
  379. }
  380. @IBAction func imgBtnClick(_ sender: UIButton) {
  381. DDLogDebug("点击了图片按钮")
  382. self.chooseImage()
  383. }
  384. @IBAction func cameraBtnClick(_ sender: UIButton) {
  385. DDLogDebug("点击了相机按钮")
  386. self.takePhoto(delegate: self)
  387. }
  388. @IBAction func locationBtnClick(_ sender: UIButton) {
  389. DDLogDebug("点击了位置按钮")
  390. let vc = IMLocationChooseController.openChooseLocation { (data) in
  391. self.sendLocationMessage(loc: data)
  392. }
  393. self.navigationController?.pushViewController(vc, animated: false)
  394. }
  395. }
  396. // MARK: - 录音delegate
  397. extension IMChatViewController: IMChatAudioViewDelegate {
  398. func sendVoice(path: String, voice: Data, duration: String) {
  399. let msg = IMMessageBodyInfo()
  400. msg.fileTempPath = path
  401. msg.body = o2_im_msg_body_audio
  402. msg.type = o2_im_msg_type_audio
  403. msg.audioDuration = duration
  404. let msgId = self.prepareForSendFileMsg(tempMessage: msg)
  405. let fileName = path.split("/").last ?? "MySound.ilbc"
  406. DDLogDebug("音频文件:\(fileName)")
  407. self.uploadFileAndSendMsg(messageId: msgId, data: voice, fileName: fileName, type: o2_im_msg_type_audio)
  408. }
  409. }
  410. // MARK: - 拍照delegate
  411. extension IMChatViewController: UIImagePickerControllerDelegate & UINavigationControllerDelegate {
  412. func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
  413. if let image = info[.editedImage] as? UIImage {
  414. let fileName = "\(UUID().uuidString).png"
  415. let newData = image.pngData()!
  416. let localFilePath = self.storageLocalImage(imageData: newData, fileName: fileName)
  417. let msgId = self.prepareForSendImageMsg(filePath: localFilePath)
  418. self.uploadImageAndSendMsg(messageId: msgId, imageData: newData, fileName: fileName)
  419. } else {
  420. DDLogError("没有选择到图片!")
  421. }
  422. picker.dismiss(animated: true, completion: nil)
  423. // var newData = data
  424. // //处理图片旋转的问题
  425. // if imageOrientation != UIImage.Orientation.up {
  426. // let newImage = UIImage(data: data)?.fixOrientation()
  427. // if newImage != nil {
  428. // newData = newImage!.pngData()!
  429. // }
  430. // }
  431. // var fileName = ""
  432. // if dict?["PHImageFileURLKey"] != nil {
  433. // let fileURL = dict?["PHImageFileURLKey"] as! URL
  434. // fileName = fileURL.lastPathComponent
  435. // } else {
  436. // fileName = "\(UUID().uuidString).png"
  437. // }
  438. }
  439. }
  440. // MARK: - 图片消息点击 delegate
  441. extension IMChatViewController: IMChatMessageDelegate {
  442. func openLocatinMap(info: IMMessageBodyInfo) {
  443. let map = IMShowLocationViewController()
  444. map.address = info.address
  445. map.addressDetail = info.addressDetail
  446. map.latitude = info.latitude
  447. map.longitude = info.longitude
  448. self.navigationController?.pushViewController(map, animated: false)
  449. }
  450. func clickImageMessage(fileId: String?, tempPath: String?) {
  451. if let id = fileId {
  452. self.showLoading()
  453. O2IMFileManager.shared
  454. .getFileLocalUrl(fileId: id)
  455. .always {
  456. self.hideLoading()
  457. }.then { (path) in
  458. let currentURL = NSURL(fileURLWithPath: path.path)
  459. DDLogDebug(currentURL.description)
  460. DDLogDebug(path.path)
  461. if QLPreviewController.canPreview(currentURL) {
  462. self.previewVC.currentFileURLS.removeAll()
  463. self.previewVC.currentFileURLS.append(currentURL)
  464. self.previewVC.reloadData()
  465. self.pushVC(self.previewVC)
  466. } else {
  467. self.showError(title: "当前文件类型不支持预览!")
  468. }
  469. }
  470. .catch { (error) in
  471. DDLogError(error.localizedDescription)
  472. self.showError(title: "获取文件异常!")
  473. }
  474. } else if let temp = tempPath {
  475. let currentURL = NSURL(fileURLWithPath: temp)
  476. DDLogDebug(currentURL.description)
  477. DDLogDebug(temp)
  478. if QLPreviewController.canPreview(currentURL) {
  479. self.previewVC.currentFileURLS.removeAll()
  480. self.previewVC.currentFileURLS.append(currentURL)
  481. self.previewVC.reloadData()
  482. self.pushVC(self.previewVC)
  483. } else {
  484. self.showError(title: "当前文件类型不支持预览!")
  485. }
  486. }
  487. }
  488. }
  489. // MARK: - 表情点击 delegate
  490. extension IMChatViewController: IMChatEmojiBarClickDelegate {
  491. func clickEmoji(emoji: String) {
  492. DDLogDebug("发送表情消息 \(emoji)")
  493. self.sendEmojiMessage(emoji: emoji)
  494. }
  495. }
  496. // MARK: - tableview delegate
  497. extension IMChatViewController: UITableViewDelegate, UITableViewDataSource {
  498. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  499. return self.chatMessageList.count
  500. }
  501. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  502. let msg = self.chatMessageList[indexPath.row]
  503. if msg.createPerson == O2AuthSDK.shared.myInfo()?.distinguishedName { //发送者
  504. if let cell = tableView.dequeueReusableCell(withIdentifier: "IMChatMessageSendViewCell", for: indexPath) as? IMChatMessageSendViewCell {
  505. cell.setContent(item: self.chatMessageList[indexPath.row])
  506. cell.delegate = self
  507. return cell
  508. }
  509. } else {
  510. if let cell = tableView.dequeueReusableCell(withIdentifier: "IMChatMessageViewCell", for: indexPath) as? IMChatMessageViewCell {
  511. cell.setContent(item: self.chatMessageList[indexPath.row])
  512. cell.delegate = self
  513. return cell
  514. }
  515. }
  516. return UITableViewCell()
  517. }
  518. func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  519. tableView.deselectRow(at: indexPath, animated: false)
  520. }
  521. }
  522. // MARK: - textField delegate
  523. extension IMChatViewController: UITextFieldDelegate {
  524. func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
  525. DDLogDebug("准备开始输入......")
  526. closeOtherView()
  527. return true
  528. }
  529. private func closeOtherView() {
  530. self.isShowEmoji = false
  531. self.isShowAudioView = false
  532. self.bottomBarHeightConstraint.constant = self.bottomBarHeight.toCGFloat
  533. self.view.layoutIfNeeded()
  534. }
  535. func textFieldShouldReturn(_ textField: UITextField) -> Bool {
  536. DDLogDebug("回车。。。。")
  537. self.sendTextMessage()
  538. return true
  539. }
  540. }