messageInputBar not dismissing when I dismiss my MessagesViewController (MessageKit, begging for help!)

huangapple go评论62阅读模式
英文:

messageInputBar not dismissing when I dismiss my MessagesViewController (MessageKit, begging for help!)

问题

我正在使用MessageKit。我已经创建了一个MessagesViewController。我在viewDidLoad中将messageInputBar作为子视图添加,并包括一个带有返回按钮的导航栏。每当我在这个视图控制器中点击messageInputBar的文本字段,然后点击返回按钮,当应用程序返回到上一个UIViewController时,messageInputBar仍然保持在屏幕上。如果我在首次进入MessagesViewController时没有点击messageInputBar,然后按返回按钮,messageInputBar就会被正确地dismiss。以下是我的代码:

    override func viewDidLoad() {
        super.viewDidLoad()

        setUpNavBar()

        navigationItem.largeTitleDisplayMode = .never
        maintainPositionOnKeyboardFrameChanged = true
        scrollsToLastItemOnKeyboardBeginsEditing = true

        messageInputBar.inputTextView.tintColor = .systemBlue
        messageInputBar.sendButton.setTitleColor(.systemTeal, for: .normal)

        messageInputBar.delegate = self
        messagesCollectionView.messagesDataSource = self
        messagesCollectionView.messagesLayoutDelegate = self
        messagesCollectionView.messagesDisplayDelegate = self

        loadChat()

        self.view.addSubview(messageInputBar)

        messageInputBar.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            messageInputBar.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
            messageInputBar.widthAnchor.constraint(equalToConstant: self.view.bounds.width)
        ])

        NSLayoutConstraint.activate([
            messagesCollectionView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100)
        ])

    }

    func setUpNavBar() {
        let navBar = UINavigationBar()
        self.view.addSubview(navBar)
        navBar.items?.append(UINavigationItem(title: (selectedUser?.userFirstName)!))
        let backButton = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(backButtonTapped))
        navBar.topItem?.leftBarButtonItem = backButton

        navBar.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            navBar.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
            navBar.heightAnchor.constraint(equalToConstant: 44),
            navBar.widthAnchor.constraint(equalToConstant: self.view.bounds.width)
        ])
    }

    @IBAction func backButtonTapped(_ sender: Any) {
        let transition = CATransition()
        self.view.window!.layer.add(transition.segueLeftToRight(), forKey: kCATransition)

        self.dismiss(animated: false)
    }
英文:

I am using MessageKit. I've created a MessagesViewController. I add messageInputBar as a subview from viewDidLoad along with a navigational bar that includes a back button. Whenever I am in this view controller and I tap on the messageInputBar's text field and then tap the back button, the messageInputBar stays on the screen when the app goes back to the previous UIViewController. If I don't tap on the messageInputBar when i first enter the MessagesViewController and press the back button, the messageInputBar properly is dismissed. Below is my code

    override func viewDidLoad() {
        super.viewDidLoad()

        setUpNavBar()

        navigationItem.largeTitleDisplayMode = .never
        maintainPositionOnKeyboardFrameChanged = true
        scrollsToLastItemOnKeyboardBeginsEditing = true

        messageInputBar.inputTextView.tintColor = .systemBlue
        messageInputBar.sendButton.setTitleColor(.systemTeal, for: .normal)

        messageInputBar.delegate = self
        messagesCollectionView.messagesDataSource = self
        messagesCollectionView.messagesLayoutDelegate = self
        messagesCollectionView.messagesDisplayDelegate = self

        loadChat()

        self.view.addSubview(messageInputBar)

        messageInputBar.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            messageInputBar.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
            messageInputBar.widthAnchor.constraint(equalToConstant: self.view.bounds.width)
        ])

        NSLayoutConstraint.activate([
            messagesCollectionView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100)
        ])

    }

    func setUpNavBar() {
        let navBar = UINavigationBar()
        self.view.addSubview(navBar)
        navBar.items?.append(UINavigationItem(title: (selectedUser?.userFirstName)!))
        let backButton = UIBarButtonItem(title: "Back", style: .plain, target: self, action: #selector(backButtonTapped))
        navBar.topItem?.leftBarButtonItem = backButton

        navBar.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            navBar.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor),
            navBar.heightAnchor.constraint(equalToConstant: 44),
            navBar.widthAnchor.constraint(equalToConstant: self.view.bounds.width)
        ])
    }

    @IBAction func backButtonTapped(_ sender: Any) {
        let transition = CATransition()
        self.view.window!.layer.add(transition.segueLeftToRight(), forKey: kCATransition)

        self.dismiss(animated: false)
    }

答案1

得分: 1

你已经创建了 MessagesViewController,因此不需要显式将 messageInputBar 添加到视图底部。

让我们看一下 MessageKit 的源代码:

private func setupInputBar(for kind: MessageInputBarKind) {
    inputContainerView.subviews.forEach { $0.removeFromSuperview() }

    func pinViewToInputContainer(_ view: UIView) {
      view.translatesAutoresizingMaskIntoConstraints = false
      inputContainerView.addSubview(view)

      NSLayoutConstraint.activate([
        view.topAnchor.constraint(equalTo: inputContainerView.topAnchor),
        view.bottomAnchor.constraint(equalTo: inputContainerView.bottomAnchor),
        view.leadingAnchor.constraint(equalTo: inputContainerView.leadingAnchor),
        view.trailingAnchor.constraint(equalTo: inputContainerView.trailingAnchor),
      ])
    }

    switch kind {
    case .messageInputBar:
      pinViewToInputContainer(messageInputBar)
    case .custom(let view):
      pinViewToInputContainer(view)
    }
  }

以下代码部分应该从你的源代码中移除,因为 messageInputBar 已经在库中设置好了:

 self.view.addSubview(messageInputBar)

messageInputBar.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
            messageInputBar.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
            messageInputBar.widthAnchor.constraint(equalToConstant: self.view.bounds.width)
        ])

NSLayoutConstraint.activate([
            messagesCollectionView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100)
        ])

现在,你的场景是
> 每当我在这个视图控制器中点击 messageInputBar 的文本字段,然后点击返回按钮,当应用返回到前一个 UIViewController 时,messageInputBar 仍然停留在屏幕上。

每当有一个你与之交互的对象(例如 messageInputBar),并且在你关闭视图控制器后没有被释放(保持在视图中),就会出现 内存泄漏

如果你反复进入和关闭视图控制器,你会观察到应用的内存使用量增加。因此,找出哪个对象产生了这个 保留循环,应该解决这个问题。

英文:

As you have created MessagesViewController, you don't need to explicitly add messageInputBar to the bottom of the view.

Let's look at the source of MessageKit

private func setupInputBar(for kind: MessageInputBarKind) {
    inputContainerView.subviews.forEach { $0.removeFromSuperview() }

    func pinViewToInputContainer(_ view: UIView) {
      view.translatesAutoresizingMaskIntoConstraints = false
      inputContainerView.addSubviews(view)

      NSLayoutConstraint.activate([
        view.topAnchor.constraint(equalTo: inputContainerView.topAnchor),
        view.bottomAnchor.constraint(equalTo: inputContainerView.bottomAnchor),
        view.leadingAnchor.constraint(equalTo: inputContainerView.leadingAnchor),
        view.trailingAnchor.constraint(equalTo: inputContainerView.trailingAnchor),
      ])
    }

    switch kind {
    case .messageInputBar:
      pinViewToInputContainer(messageInputBar)
    case .custom(let view):
      pinViewToInputContainer(view)
    }
  }

The following code section should be removed from your source as the messageInputBar has already been set up in the library.

 self.view.addSubview(messageInputBar)

messageInputBar.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
            messageInputBar.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
            messageInputBar.widthAnchor.constraint(equalToConstant: self.view.bounds.width)
        ])

NSLayoutConstraint.activate([
            messagesCollectionView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 100)
        ])

Now, your scenario
> Whenever I am in this view controller and I tap on the messageInputBar's text field and then tap the back button, the messageInputBar stays on the screen when the app goes back to the previous UIViewController.

Whenever, there is an object that you interact with (eg. messageInputBar), and it is not deallocated (stays in view) after you dismissed the view controller, there is a memory leak.

If you repeatedly enter and dismiss the view controller, you will observe a rise in the memory usage of the app. So, finding out which object is creating this retain cycle, should solve this issue.

答案2

得分: 1

我使用 Cocoapods 安装了 MessageKit,后来发现他们不再支持 Cocoapods。所以我完全将整个项目迁移到 Swift Package Manager,以获取最新的 MessageKit,其中包括在他们的代码中设置输入栏。不知道为什么他们会发布一个最初没有这个功能的版本?不管怎样,问题解决了!

英文:

I installed MessageKit using Cocoapods later to find out they dropped support for Cocoapods. So I completely migrated my entire project over to Swift Package Manager to get the latest MessageKit which includes the setup for the inputbar in their code. No idea why they would release a version that didn't have this initially? Anyways, solved my problem!

huangapple
  • 本文由 发表于 2023年2月8日 14:50:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75382233.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定