title: Odd behavior when clicking "Search" button
body: <p>I really like the new design of the UISearchBar that came with iOS 11.0. I am trying to include a search bar in my own app.
  The app consists of a navigation controller. I am trying to include the search bar on one of my UITableViewController instances.</p>
  
  <p>Here comes the tricky part. Whenever the search field is active (i.e. is the first responder), I can not navigate the table view. When I click the "Search" button on the keyboard, the keyboard disappears as expected, but the UITableView still does not respond. The regular behavior is "restored" once I tap the UItableView. But then the UISearchBar text is reset to an empty string (not by me). Am I missing something? I am pretty sure that everything is wired up properly.</p>
  
  <p>Here is the full code:</p>
  
  <pre><code>class StravaSelectionViewController : UITableViewController, 
  
  UISearchBarDelegate, MKMapViewDelegate
  {
  private let searchController = UISearchController(searchResultsController: nil)
  
  private var allActivities: [ActivitySummary] = []
  private var allRoutes: [RouteSummary] = []
  private var allSegments: [SegmentSummary] = []
  
  private var activities: [ActivitySummary] = []
  private var routes: [RouteSummary] = []
  private var segments: [SegmentSummary] = []
  
  var mode: StravaLoadMode = .none
  
  var activitySelected: ((ActivitySummary) -&gt; ())?
  var segmentSelected: ((SegmentSummary) -&gt; ())?
  var routeSelected: ((RouteSummary) -&gt; ())?
  
  override func viewDidLoad()
  {
      super.viewDidLoad()
  
      self.tableView.tableFooterView = UIView()
  
      self.initSearchBar()
  }
  
  override func viewDidAppear(_ animated: Bool)
  {
      super.viewDidAppear(animated)
  
      self.refresh()
  }
  
  override func viewDidDisappear(_ animated: Bool)
  {
      super.viewDidAppear(animated)
  
      self.allActivities.removeAll()
      self.allRoutes.removeAll()
      self.allSegments.removeAll()
  
      self.activities.removeAll()
      self.routes.removeAll()
      self.segments.removeAll()
  }
  
  fileprivate func initSearchBar()
  {
      self.definesPresentationContext = true
  
      self.searchController.searchBar.delegate = self
      self.searchController.searchBar.placeholder = Resources.SEARCH_PLACEHOLDER
      self.searchController.searchBar.showsScopeBar = false
  
      self.navigationItem.searchController = searchController
      self.navigationItem.searchController?.searchBar.tintColor = UIColor.white
  }
  
  // MARK: Refresh
  fileprivate func refresh()
  {
      switch self.mode
      {
      case .activities:
          self.loadActivities()
          break
      case .routes:
          self.loadRoutes()
          break
      case .segments:
          self.loadSegments()
          break
      default:
          break
      }
  }
  
  fileprivate func loadActivities()
  {
      Indicator.shared.present(self, Resources.LOADING_ACTIVITIES, true)
  
      let client: ActivityClient = ActivityClient()
      client.getActivities(1, 200)
      {
          activities in
          self.allActivities.append(contentsOf: activities)
          self.activities.append(contentsOf: activities)
  
          DispatchQueue.main.async
          {
              self.tableView.reloadData()
  
              Indicator.shared.dismiss(true)
          }
      }
  }
  
  fileprivate func loadRoutes()
  {
      guard let athleteId = Settings.getAthleteId() else { return }
  
      Indicator.shared.present(self, Resources.LOADING_ROUTES, true)
  
      let client = RouteClient()
      client.getRoutes(athleteId)
      {
          routes in
          self.routes.append(contentsOf: routes)
          self.allRoutes.append(contentsOf: routes)
  
          DispatchQueue.main.async
          {
              self.tableView.reloadData()
  
              Indicator.shared.dismiss(true)
          }
      }
  }
  
  fileprivate func loadSegments()
  {
      Indicator.shared.present(self, Resources.LOADING_SEGMENTS, true)
  
      let client = SegmentClient()
      client.getAllStarredSegments(page: 1)
      {
          segments, finished in
          if let segments = segments
          {
              self.segments.append(contentsOf: segments)
              self.allSegments.append(contentsOf: segments)
          }
  
          if finished == true
          {
              // Sort the segments alphabetically
              self.segments.sort{ $0.name &lt; $1.name }
              self.allSegments.sort{ $0.name &lt; $1.name }
  
              DispatchQueue.main.async
              {
                  self.tableView.reloadData()
  
                  Indicator.shared.dismiss(true)
              }
          }
      }
  }
  
  // MARK: Table View
  override func numberOfSections(in tableView: UITableView) -&gt; Int
  {
      return 1
  }
  
  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int
  {
      switch mode
      {
      case .activities:
          return self.activities.count
      case .routes:
          return self.routes.count
      case .segments:
          return self.segments.count
      default:
          return 0
      }
  }
  
  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell
  {
      switch mode
      {
      case .activities:
          return self.fillActivityCell(row: indexPath.row)
      case .routes:
          return self.fillRouteCell(row: indexPath.row)
      case .segments:
          return self.fillSegmentCell(row: indexPath.row)
      default:
          return UITableViewCell()
      }
  }
  
  fileprivate func fillActivityCell(row: Int) -&gt; ActivityCell
  {
      let cell = tableView.dequeueReusableCell(withIdentifier: "activityCell") as! ActivityCell
  
      let activity = self.activities[row]
  
      cell.activity = activity
      cell.route = nil
      cell.segment = nil
  
      cell.name.text = activity.name
  
      if let distance = activity.distance
      {
          cell.distance.text = Utilities.getUnitDistance(distance.floatValue)
      }
      if let elevation = activity.elevationGain
      {
          cell.elevation.text = Utilities.getUnitElevation(elevation.intValue)
      }
  
      // Map
      if let map = activity.map
      {
          if let summary = map.summary
          {
              var coordinates = PolylineDecoder.decode(summary)
  
              DispatchQueue.main.async
              {
                  cell.map.layer.cornerRadius = 10.0
  
                  // Clear old overlays
                  cell.map.removeOverlays(cell.map.overlays)
  
                  cell.map.delegate = self
                  let polyline = MKPolyline(coordinates: &amp;coordinates, count: coordinates.count)
                  cell.map.add(polyline)
                  cell.map.setRegion(MKCoordinateRegionForMapRect(polyline.boundingMapRect), animated: false)
              }
          }
      }
  
      return cell
  }
  
  fileprivate func fillRouteCell(row: Int) -&gt; ActivityCell
  {
      let cell = tableView.dequeueReusableCell(withIdentifier: "activityCell") as! ActivityCell
  
      let route = self.routes[row]
  
      cell.route = route
      cell.activity = nil
      cell.segment = nil
  
      cell.name.text = route.name
  
      if let distance = route.distance
      {
          cell.distance.text = Utilities.getUnitDistance(distance.floatValue)
      }
      if let elevation = route.elevationGain
      {
          cell.elevation.text = Utilities.getUnitElevation(elevation.intValue)
      }
  
      // Map
      if let map = route.map
      {
          if let summary = map.summary
          {
              var coordinates = PolylineDecoder.decode(summary)
  
              DispatchQueue.main.async
              {
                  cell.map.layer.cornerRadius = 8.0
  
                  // Clear old overlays
                  cell.map.removeOverlays(cell.map.overlays)
  
                  cell.map.delegate = self
                  let polyline = MKPolyline(coordinates: &amp;coordinates, count: coordinates.count)
                  cell.map.add(polyline)
                  cell.map.setRegion(MKCoordinateRegionForMapRect(polyline.boundingMapRect), animated: false)
              }
          }
      }
  
      return cell
  }
  
  fileprivate func fillSegmentCell(row: Int) -&gt; SegmentCell
  {
      let cell = tableView.dequeueReusableCell(withIdentifier: "segmentCell") as! SegmentCell
  
      let segment = self.segments[row]
  
      cell.name.text = segment.name
  
      if let distance = segment.distance
      {
          cell.distance.text = Utilities.getUnitDistance(distance.floatValue)
      }
      if let city = segment.city, let state = segment.state, let country = segment.country
      {
          cell.location.text = String(format: "%@, %@, %@", city, state, country)
      }
      if let grade = segment.averageGrade
      {
          cell.averageGrade.text = String(format: "%.2f %%", grade.floatValue)
      }
  
      return cell
  }
  
  override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
  {
      tableView.deselectRow(at: indexPath, animated: true)
  
      switch mode
      {
      case .activities:
          self.activitySelected?(self.activities[indexPath.row])
          break
      case .segments:
          self.segmentSelected?(self.segments[indexPath.row])
          break
      case .routes:
          self.routeSelected?(self.routes[indexPath.row])
          break
      case .none:
          break
      }
  
      DispatchQueue.main.async
      {
          self.navigationController?.popToRootViewController(animated: true)
      }
  }
  
  override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -&gt; CGFloat
  {
      if mode == .segments
      {
          return 80.0
      }
  
      return 256.0
  }
  
  // MARK: Map
  func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -&gt; MKOverlayRenderer
  {
      let polylineRenderer = MKPolylineRenderer(overlay: overlay)
      polylineRenderer.strokeColor = UIColor.red
      polylineRenderer.lineWidth = 1
      return polylineRenderer
  }
  
  // MARK: Selection Color
  override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
  {
      let selectionView = UIView()
      selectionView.backgroundColor = UIColor(r: 40.0, g: 40.0, b: 40.0, alpha: 1.0)
      cell.selectedBackgroundView = selectionView
  }
  
  // MARK: Search
  private var searchBarIsEmpty: Bool
  {
      get { return searchController.searchBar.text?.isEmpty ?? true }
  }
  
  func searchBarCancelButtonClicked(_ searchBar: UISearchBar)
  {
      self.resetSearch()
  }
  
  func searchBarSearchButtonClicked(_ searchBar: UISearchBar)
  {
      Swift.print("Search clicked")
  
      self.searchController.searchBar.endEditing(true)
  }
  
  func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String)
  {
      self.filter(searchText)
  
      self.tableView.reloadData()
  }
  
  fileprivate func filter(_ searchText: String)
  {
      if searchText.isEmpty
      {
          self.resetSearch()
      }
      else
      {
          let search = searchText.lowercased()
  
          switch self.mode
          {
          case .activities:
              self.filterActivities(search)
              break
          case .routes:
              self.filterRoutes(search)
              break
          case .segments:
              self.filterSegments(search)
              break
          default:
              break
          }
      }
  }
  
  fileprivate func filterSegments(_ search: String)
  {
      self.segments = self.allSegments.filter({ $0.name.lowercased().contains(search) })
  }
  
  fileprivate func filterRoutes(_ search: String)
  {
      self.routes = self.allRoutes.filter({ $0.name.lowercased().contains(search) })
  }
  
  fileprivate func filterActivities(_ search: String)
  {
      self.activities = self.allActivities.filter({ $0.name.lowercased().contains(search) })
  }
  
  fileprivate func resetSearch()
  {
      switch self.mode
      {
      case .activities:
          self.activities.removeAll()
          self.activities.append(contentsOf: self.allActivities)
          break
      case .routes:
          self.routes.removeAll()
          self.routes.append(contentsOf: self.allRoutes)
  
          break
      case .segments:
          self.segments.removeAll()
          self.segments.append(contentsOf: self.allSegments)
          break
      default:
          break
      }
  
      self.tableView.reloadData()
  }
  </code></pre>
  
  <p>}</p>