123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- //
- // MIT License
- //
- // Copyright (c) 2017-2020 MessageKit
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in all
- // copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- // SOFTWARE.
- import MessageKit
- import UIKit
- class TSChatViewController: MessagesViewController, MessagesDataSource {
- var deleteBlock:(()->Void)?
- //数据
- var viewModel:TSAIChatVM = TSAIChatVM()
- lazy var messageList: [TSChatMessage] = []
-
- //导航栏
- // lazy var vipBtn: UIButton = creatVipBtn
- lazy var navBarView: TSBaseNavContentBarView = creatNavBarView
- lazy var navBarContentView: UIView = creatNavBarContentView
- lazy var normalNavBarView: TSNormalNavigationBarView = creatNormalNavBarView
- //collectionView 布局
- lazy var textMessageSizeCalculator = TSTextLayoutSizeCalculator(layout:self.messagesCollectionView.messagesCollectionViewFlowLayout)
-
- //键盘
- lazy var inputBarVC: TSChatInputBarVC = creatInputBarVC
- lazy var inputBarBgView:UIView = creatInputBarBgView
- let inputBarTopView:UIView = UIView()
- lazy var scrollToBottomButton: UIButton = creatScrollToBottomButton
- // vip 相关
- lazy var freeText: UILabel = creatFreeText
- lazy var upgradeVipBg: UIView = creatUpgradeVipBg
- let formatter: DateFormatter = {
- let formatter = DateFormatter()
- formatter.dateStyle = .medium
- return formatter
- }()
-
- override func viewDidLoad() {
- //在父类前先设置好inputBarType,否则会先加载默认白色,再加载自定义黑色,会一闪而过白色默认的
- setUpInputBarType()
-
- super.viewDidLoad()
- configureNaviBarView()
- configureMessageCollectionView()
- configureMessageInputBar()
- loadFirstMessages()
- // updateVipView()
- dealThings()
- }
-
-
- func dealThings(){
-
- // vipBtn.isHidden = PurchaseManager.default.isVip
- // NotificationCenter.default.addObserver(self, selector: #selector(vipInfoChanged), name: .kPurchaseDidChanged, object: nil)
-
- if viewModel.uiStyle == .chat {
- // 注册通知监听,App死的时候,保存本次聊天记录到本地
- NotificationCenter.default.addObserver(self, selector: #selector(saveChatList), name: .kApplicationWillTerminate, object: nil)
- }
- }
-
- // @objc func vipInfoChanged() {
- // kExecuteOnMainThread {
- // self.vipBtn.isHidden = PurchaseManager.default.isVip
- // self.updateVipView()
- // }
- // }
- @objc func saveChatList() {
- messageList.removeFirst()
- if messageList.count > 0 {
- //保存本次聊天记录
- viewModel.updateMessages(msgModels: messageList)
- }
- }
-
- func loadFirstMessages() {
- self.messageList = viewModel.getHistoryChatMessage()
- self.messagesCollectionView.reloadData()
- self.messagesCollectionView.scrollToLastItem(animated: false)
- }
- func configureMessageCollectionView() {
- clearAndResetConstraints()
- view.backgroundColor = .mainBg
- //设置自定义FlowLayout,itemsize等,都在这里控制
- let flowLayout = CustomMessagesFlowLayout()
- flowLayout.sectionInset = UIEdgeInsets(top: 4, left: 0, bottom: 4, right: 0)
- messagesCollectionView.collectionViewLayout = flowLayout
- messagesCollectionView.backgroundColor = .clear
- messagesCollectionView.register(TSTextMessageContentCell.self)
- messagesCollectionView.messagesLayoutDelegate = self
- messagesCollectionView.messagesDisplayDelegate = self
- messagesCollectionView.messagesDataSource = self
- messagesCollectionView.messageCellDelegate = self
- messagesCollectionView.clipsToBounds = true
- scrollsToLastItemOnKeyboardBeginsEditing = true // default false
- maintainPositionOnInputBarHeightChanged = true // default false
- showMessageTimestampOnSwipeLeft = false // default false
- // messagesCollectionView.refreshControl = refreshControl
- messagesCollectionView.reloadData()
- }
-
-
- func clearAndResetConstraints() {
- // 筛选出与 messagesCollectionView 相关的约束
- let constraintsToRemove = view.constraints.filter { constraint in
- return (constraint.firstItem as? UIView == messagesCollectionView) || (constraint.secondItem as? UIView == messagesCollectionView)
- }
- // 停用并移除这些约束
- NSLayoutConstraint.deactivate(constraintsToRemove)
- for constraint in constraintsToRemove {
- view.removeConstraint(constraint)
- }
- messagesCollectionView.snp.remakeConstraints { make in
- make.leading.trailing.bottom.equalTo(0)
- make.top.equalTo(k_Nav_Height)
- }
- }
- // MARK: - Helpers
- var lastIndexPath:IndexPath{
- let section = messagesCollectionView.numberOfSections - 1
- if messagesCollectionView.numberOfItems(inSection: section) > 0 {
- let item = messagesCollectionView.numberOfItems(inSection: section) - 1
- return IndexPath(item: item, section: section)
- }
- return IndexPath(item: 0, section: 0)
- }
-
- func insertMessage(_ message: TSChatMessage,indexPath:IndexPath? = nil) {
- // messageList.append(message)
- let isReplace = replaceOrAppend(message, indexPath: indexPath)
- var cellIndexPaht = lastIndexPath
- if let indexPath = indexPath{
- cellIndexPaht = indexPath
- }
- messagesCollectionView.performBatchUpdates({
- if isReplace == false {
- messagesCollectionView.insertItems(at: [cellIndexPaht])
- }
-
- if messageList.count >= 2 {
- messagesCollectionView.reloadItems(at: [cellIndexPaht])
- }else{
- messagesCollectionView.reloadData()
- }
-
- }, completion: { [weak self] _ in
- if self?.isLastSectionVisible() == true {
- self?.messagesCollectionView.scrollToLastItem(animated: true)
- }
- })
- }
-
- /// 返回值,代表是否替换
- func replaceOrAppend(_ message: TSChatMessage,indexPath:IndexPath?) ->Bool {
- if let indexPath = indexPath {
- let index = indexPath.item
- if index >= 0 && index < messageList.count {
- messageList[index] = message// 下标存在,替换该位置的元素
- return true
- }
- }
- messageList.append(message)// 插入新元素
- return false
- }
-
-
- func isLastSectionVisible() -> Bool {
- guard !messageList.isEmpty else { return false }
- return messagesCollectionView.indexPathsForVisibleItems.contains(lastIndexPath)
- }
-
-
- override func viewWillAppear(_ animated: Bool) {
-
- }
- }
|