0

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)
    }
BiggRojo
  • 31
  • 5

2 Answers2

1

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.

tanmoy
  • 1,276
  • 1
  • 10
  • 28
  • I thought this was the case as well considering every tutorial I've watched using MessageKit, they've never added this as a subview. However, my messageInputBar never shows! The only way I can get it to show is by adding the subview. I am also not seeing the source code you posted in the link you provided – BiggRojo Feb 08 '23 at 21:24
  • Really weird, whatever version of MessageKit I have does not include the setupInputBar code. – BiggRojo Feb 08 '23 at 21:25
  • 1
    I am installing MessageKit via pods. I was on the latest 3.8.0 and it does not contain the setupInputBar code. I tried downgrading and can't figure out why I am unable to find where this code is. So confused... – BiggRojo Feb 08 '23 at 21:41
  • Just read the release notes and realized they've dropped Cocoapods support! HA! This has got to be the last time I use open source stuff – BiggRojo Feb 08 '23 at 21:49
1

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!

BiggRojo
  • 31
  • 5