swiftmemory-managementuisearchcontrollerpresentmodalviewcontrollerdealloc

Swift: deallocate modally presented view controller


I have a modally presented SearchviewController that contains a UISearchController. When swiping down it gets deallocated, but only if the searchControllers searchBar is not in editing mode. Only if I press its cancel button in advance, it gets deallocated. How can I make sure it gets deallocated, even when in editing mode? There are definitely no strong self references within any closures...

Presenting ViewController:

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    addButton()
}

func addButton() {
    let mediumConfiguration = UIImage.SymbolConfiguration(scale: .large)
    var checkButtonImage = UIImage(systemName: "plus", withConfiguration: mediumConfiguration)
    checkButtonImage = checkButtonImage?.withTintColor(.label)
    
    let button = UIButton(type: .contactAdd)
    button.addTarget(self, action: #selector(onAddViewControllerButtonClicked(sender:)), for: .touchUpInside)
    
    view.addSubview(button)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
    button.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
}
@objc func onAddViewControllerButtonClicked(sender: UIButton) {
    
    let viewController = SearchViewController()
    viewController.view.backgroundColor = .secondarySystemBackground
    
    let navigationController = UINavigationController()
    navigationController.viewControllers = [viewController]
    
    self.present(navigationController, animated: true)
}

}

Presented ViewController:

class SearchViewController: UIViewController, UISearchBarDelegate, UISearchResultsUpdating {

override func viewDidLoad() {
    super.viewDidLoad()
    configureSearchController()
}

var searchController: UISearchController?
func configureSearchController() {
    //search
    searchController = UISearchController(searchResultsController: nil)
    searchController?.searchResultsUpdater = self
    searchController?.searchBar.delegate = self
    searchController?.hidesNavigationBarDuringPresentation = false
    searchController?.searchBar.searchBarStyle = .minimal
    searchController?.searchBar.keyboardType = .webSearch
    self.navigationItem.searchController?.searchBar.backgroundColor = .clear
    self.navigationItem.searchController = searchController
    self.navigationItem.hidesSearchBarWhenScrolling = false
    self.definesPresentationContext = true
    self.navigationItem.searchController = searchController
}
func updateSearchResults(for searchController: UISearchController) {
    return
}

//check deallocation
deinit { print("\(NSStringFromClass(type(of: self))): deallocated") }

}

Can you help with that?

Thank you in advance!


Solution

  • Adding

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
    
        self.navigationItem.searchController = nil
    }
    

    to SearchViewController fixes the problem for me, but admittedly I have no idea as to why this is necessary.