title: Unable to present a UISearchController
body: <p>I have the following view hierarchy:</p>
  
  <pre><code>                         UINavigationController
                                    ||
                                    \/
             LibraryTableViewController: UITableViewController
                                    ||
                                    \/
         AlbumsCollectionViewController: UICollectionViewController
                                    ||
                                    \/
               SongsTableViewController: UITableViewController
  </code></pre>
  
  <p>I want to have a search bar in <code>AlbumsCollectionViewController</code> and a different one in <code>SongsTableViewController</code> that is shown in the <code>navigationItem.titleView</code>.</p>
  
  <p>I have managed to add a working search bar in <code>AlbumsCollectionViewController</code> as follows:</p>
  
  <pre><code>class AlbumsCollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout, UISearchControllerDelegate, UISearchResultsUpdating, UISearchBarDelegate {
  
      var searchController : UISearchController!
  
      override func viewDidLoad() {
          super.viewDidLoad()
  
          initSearchBar()
          initNavigationBar()
      }
  
      private func initSearchBar() {
          self.searchController = UISearchController(searchResultsController:  nil)
  
          self.searchController.searchResultsUpdater = self
          self.searchController.delegate = self
          self.searchController.searchBar.delegate = self
  
          self.searchController.hidesNavigationBarDuringPresentation = false
          self.searchController.dimsBackgroundDuringPresentation = false
  
          searchController.searchResultsController?.view.isHidden = false
          searchController.hidesNavigationBarDuringPresentation = false
  
          self.extendedLayoutIncludesOpaqueBars = true
          self.definesPresentationContext = true
  
          searchController.searchBar.backgroundColor = UIColor.black
          UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes([NSAttributedStringKey.foregroundColor : UIColor.white], for: .normal)
  
          self.navigationItem.titleView = searchController.searchBar
  
          navigationItem.titleView?.isHidden = true
      }
  
      private func initNavigationBar() {
          searchButton.tintColor = UIColor.white
          settingsButton.tintColor = UIColor.white
          backButton.tintColor = UIColor.white
          self.navigationItem.title = "Artists"
          self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor : UIColor.white]
      }
  
  
      @IBAction func SearchButtonTapped(_ sender: Any) {
          showSearchBar()
      }
  
  
      private func showSearchBar(){
          navigationItem.titleView?.isHidden = false
          searchController.isActive = true
      }
  }
  </code></pre>
  
  <p>Note that the search bar is hidden on <code>ViewDidLoad()</code> and is presented when a button is pressed as shown in <code>SearchButtonTapped</code> method.</p>
  
  <p>Now, I am trying to do the same in <code>SongsTableViewController</code> however, the search bar is not showing when tapping the the button (i.e. calling <code>SearchButtonTapped</code>) and I am getting the following message: </p>
  
  <pre><code>Warning: Attempt to present &lt;UISearchController: 0x7f8158812b50&gt; on &lt;MyProject.AlbumsCollectionViewController: 0x7f81588023c0&gt; whose view is not in the window hierarchy!
  </code></pre>
  
  <p>If I commented the line <code>searchController.isActive = true</code> then the search bar will show, however, it wont be active even if I tapped on it.</p>
  
  <p><strong>Edit</strong></p>
  
  <p>Sorry if I haven't been clear. I have a separate <code>UISearchController</code> in <code>SongsTableViewController</code>. I meant I am using the same logic in both controllers</p>
  
  <p><strong>Also Note if I pushed <code>SongsTableViewController</code> from the navigation controller (i.e the view hierarchy only has 2 controllers (UINavigationController => SongsTableViewController) the search bar works fine</strong></p>
  
  <p><strong>This is most of the Code of  <code>SongsTableViewController</code> (omitted non relevant stuff)</strong></p>
  
  <pre><code>import UIKit
  import os.log
  import MediaPlayer
  
  class SongsTableViewController: UITableViewController, UISearchControllerDelegate, UISearchResultsUpdating, UISearchBarDelegate ,PlayerDelegate, NowPlayingDelegate, SongCellDelegate, SongsOptionsDelegate {
  
      // MARK: properties
  
      var playerManager: PlayerManager? = nil
      var dataManager: DataManager? = nil
  
      var tabVC: TabBarController?
      var selectedSong: Song?
  
      lazy var optionsTransitionDelegate = PresentationManager()
      lazy var playlistTransitionDelegate = PresentationManager()
  
      var searchController : UISearchController!
  
      @IBOutlet var backgroundView: UIView!
      @IBOutlet weak var searchButton: UIBarButtonItem!
      @IBOutlet weak var settingsButton: UIBarButtonItem!
  
      var albumID: String?
      var artistID: String?
      var playlist: Playlist?
  
      var songs = [Song]()
      var songIndexMap = [String: Int]()
      var filteredSongs = [Song]()
  
  
      override func viewDidLoad() {
          super.viewDidLoad()
          self.dataManager = DataManager.getInstance()
          self.playerManager = PlayerManager.getInstance()
  
          playlistTransitionDelegate.screenRatio = 2.0 / 3.0
  
          if(self.albumID != nil) {
              self.songs = SQLiteManager.getAlbumSongs(albumID: self.albumID!)
          } else if(self.artistID != nil) {
              self.songs = SQLiteManager.getArtistSongs(artistID: self.artistID!)
          } else if (self.playlist != nil) {
              self.songs = SQLiteManager.getPlaylistSongs(playlist: self.playlist!)
          } else {
              dataManager?.songsTableViewController = self
          }
  
          for i in 0..&lt;songs.count {
              songIndexMap[songs[i].id] = i
          }
  
          initSearchBar()
          initNavigationBar()
  
          if(songs.count == 0 &amp;&amp; (!fullListOfSongs() || fullListOfSongs() &amp;&amp; dataManager?.getFullSongsCount() == 0)){
              tableView.backgroundView = backgroundView
          }
          tableView.tableFooterView = UIView()
  
          tabVC = tabBarController as? TabBarController
          tabVC?.nowPlayingViewController?.delegate = self
  
  
      }
  
  
  
      private func shouldAutorotate() -&gt; Bool {
          return false
      }
  
      override func didReceiveMemoryWarning() {
          super.didReceiveMemoryWarning()
      }
  
      // MARK: - Table view data source
  
      override func numberOfSections(in tableView: UITableView) -&gt; Int {
          return 1
      }
  
      override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -&gt; CGFloat {
          return Util.SONG_CELL_HEIGHT
      }
  
      override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
          if(isFiltering()) {
              return self.filteredSongs.count
          } else if (fullListOfSongs()) {
              return dataManager!.getFullSongsCount()
          }
          return self.songs.count
      }
  
      override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
          let cellIdentifier = "SongTableViewCell"
          guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? SongCell  else {
              fatalError("The dequeued cell is not an instance of SongCell.")
          }
          var song: Song?
          if(fullListOfSongs()) {
              if(isFiltering()){
                  song = self.filteredSongs[indexPath.row]
              } else {
                  song = dataManager?.getSong(index: indexPath.row)
              }
          } else {
              if(isFiltering()){
                  song = self.filteredSongs[indexPath.row]
              } else {
                  song = self.songs[indexPath.row]
              }
          }
  
          cell.setAttributes(song: song!)
          cell.delegate = self
  
          cell.preservesSuperviewLayoutMargins = false
          return cell
      }
  
      override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
          self.tableView.deselectRow(at: indexPath, animated: false)
      }
  
  
  
      // MARK: - Search Bar
  
      func updateSearchResults(for searchController: UISearchController) {
          if (!searchController.isActive) {
              hideSearchBar()
              tableView.reloadData()
          }
  
          if(isSearchBarEmpty()) {
              return
          }
  
          filterSongs(filter: searchController.searchBar.text!)
          tableView.reloadData()
      }
  
      private func filterSongs(filter: String) {
          if(self.albumID != nil) {
              self.filteredSongs = SQLiteManager.getAlbumSongs(albumID: self.albumID!, filter: filter)
          } else if(self.artistID != nil) {
              self.filteredSongs = SQLiteManager.getArtistSongs(artistID: self.artistID!, filter: filter)
          } else if(self.playlist != nil) {
              self.filteredSongs = SQLiteManager.getPlaylistSongs(playlist: self.playlist!, filter: filter)
          }else {
              self.filteredSongs = SQLiteManager.getSongs(filter: filter)
          }
      }
  
      func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
          if searchText == "" {
              tableView.reloadData()
          }
      }
  
  
      private func initSearchBar() {
          self.searchController = UISearchController(searchResultsController:  nil)
  
          self.searchController.searchResultsUpdater = self
          self.searchController.delegate = self
          self.searchController.searchBar.delegate = self
  
          self.searchController.hidesNavigationBarDuringPresentation = false
          self.searchController.dimsBackgroundDuringPresentation = false
  
          searchController.searchResultsController?.view.isHidden = false
          searchController.hidesNavigationBarDuringPresentation = false
  
          self.extendedLayoutIncludesOpaqueBars = true
          self.definesPresentationContext = true
  
          searchController.searchBar.backgroundColor = UIColor.black
          UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes([NSAttributedStringKey.foregroundColor : UIColor.white], for: .normal)
  
          self.navigationItem.titleView = searchController.searchBar
  
          navigationItem.titleView?.isHidden = true
      }
  
  
      private func initNavigationBar() {
          searchButton.tintColor = UIColor.white
          if (fullListOfSongs()) {
              searchButton.isEnabled = false
              dataManager?.buttons.append(searchButton)
          }
          settingsButton.tintColor = UIColor.white
          self.navigationItem.title = "Songs"
          self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor : UIColor.white]
      }
  
  
      @IBAction func SearchButtonTapped(_ sender: Any) {
          showSearchBar()
      }
  
  
      private func showSearchBar(){
          self.navigationItem.titleView?.isHidden = false
          self.searchController.isActive = true
  
          DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
              self.searchController.searchBar.becomeFirstResponder()
          }
  
          navigationItem.rightBarButtonItems![0].isEnabled = false
          navigationItem.rightBarButtonItems![0].image = nil
          navigationItem.rightBarButtonItems![1].isEnabled = false
          navigationItem.rightBarButtonItems![1].image = nil
      }
  
      private func hideSearchBar() {
          navigationItem.titleView?.isHidden = true
  
          navigationItem.rightBarButtonItems![0].isEnabled = true
          navigationItem.rightBarButtonItems![0].image = UIImage(named: "settings")
          navigationItem.rightBarButtonItems![1].isEnabled = true
          navigationItem.rightBarButtonItems![1].image = UIImage(named: "search")
  
      }
  
      func isFiltering() -&gt; Bool {
          if(searchController == nil){
              return false
          }
          return searchController.isActive &amp;&amp; !isSearchBarEmpty()
      }
  
      private func isSearchBarEmpty() -&gt; Bool {
          return searchController.searchBar.text?.isEmpty ?? true
      }
  
      private func fullListOfSongs() -&gt; Bool {
          return self.playlist == nil &amp;&amp; self.albumID == nil &amp;&amp; self.artistID == nil
      }
  
  }
  </code></pre>