UIViewController with inputAccessoryView is not deallocated

前端 未结 2 2077
-上瘾入骨i
-上瘾入骨i 2021-02-06 03:41

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

2条回答
  •  有刺的猬
    2021-02-06 04:07

    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
        }
    }
    

提交回复
热议问题