I have simple subclass of UIViewController (code below). If I attach inputAccessoryView, my viewcontroller is never deallocated. If I do not set inputAccessoryView in viewDidLo
This question is rather old, but I came across it in 2019 when trying to use an inputAccessoryView in iOS 12.
The deallocation problem still exists today and the first solution proposed in the article mentioned in dvkch's answer does not work either. The second solution in the article (involving animations) is just too much work and does not work well when the user dismisses the keyboard interactively via a UIScrollView with scrollView.keyboardDismissMode = .interactive
.
The best approach I could come up with is just setting the first responder UITextField
or UITextView
inputAccessoryView
to nil
on viewDidDisappear
. That gets rid of the memory leak entirely and does not seem to have any side-effects or downsides.
So here's a full Swift 4.2 example:
class MyViewController: UIViewController {
/// You could also add your text field or text view programmatically,
/// but let's say it's coming from a .xib for now...
@IBOutlet private weak var myTextField: UITextField!
/// This is required for the inputAccessoryView to work.
override internal var canBecomeFirstResponder: Bool {
return true
}
/// Here's a nice empty red view that will be used as an
/// input accessory.
private lazy var accessoryView: UIView = {
let accessoryView = UIView()
accessoryView.backgroundColor = UIColor.red
accessoryView.frame.size = CGSize(
width: view.frame.size.width,
height: 45
)
return accessoryView
} ()
override var inputAccessoryView: UIView? {
return accessoryView
}
/// This is required to avoid leaking the `inputAccessoryView`
/// when the keyboard is open and the `UIViewController`
/// is deallocated.
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
myTextField.inputAccessoryView = nil
}
}