nhyne
nhyne

Reputation: 445

UISearchController search bar width not changing

Ran through a quick tutorial with search bars and figured that I could use searchBar.sizeToFit() to autosize the search bar, however the right end of the search bar still extends off of the screen.

class MainViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating, UISearchBarDelegate {

     var searchController = UISearchController(searchResultsController: nil)
     override func viewDidLoad() {
         super.viewDidLoad()
         searchController.searchBar.delegate = self
         searchController.searchResultsUpdater = self
         searchController.dimsBackgroundDuringPresentation = false
         searchController.searchBar.sizeToFit()
         tableView.tableHeaderView = searchController.searchBar
         definesPresentationContext = true
    }}

I've tried to manually set the frame with something like searchController.searchBar.frame = CGRectMake(0, 0, 200, 200) but the width remained off of the screen. The search bar does not exist in the storyboard, however the tableView does.

Upvotes: 5

Views: 4975

Answers (5)

Rebeloper
Rebeloper

Reputation: 792

Swift 4, works for all types of ViewControllers

After countless hours of trial and error here's what I came up for those who want to use it in code:

  1. Set delegate

    class SearchDatasourceController: UIViewController , UISearchBarDelegate { }

  2. Set a customTitleView and the searchBar

IMPORTANT: set their frame

lazy var customTitleView: UIView = {
    var view = UIView()
    let frame = CGRect(x: 0, y: 0, width: 300, height: 44)
    view.frame = frame
    return view
  }()

  lazy var searchBar: UISearchBar = {
    let searchBar = UISearchBar()
    searchBar.placeholder = "Search"
    searchBar.autocapitalizationType = .none
    searchBar.backgroundImage = UIImage()
    (searchBar.value(forKey: "searchField") as? UITextField)?.backgroundColor = UIColor(r: 230, g: 230, b: 230)
    searchBar.delegate = self
    searchBar.becomeFirstResponder()
    let frame = CGRect(x: 0, y: 0, width: 300, height: 44)
    searchBar.frame = frame
    return searchBar
  }()
  1. in viewDidLoad add the customTitleView that holds the searchBar

    override func viewDidLoad() { super.viewDidLoad()

    customTitleView.addSubview(searchBar)
    navigationItem.titleView = customTitleView
    searchBar.becomeFirstResponder()
    

    }

  2. add delegate method to listen for searches

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { print(searchText) }

  3. make sure you present your view controller on the navigation stack

    func handleSearchBarButtonItemTapped() { let controller = SearchDatasourceController() navigationController?.pushViewController(controller, animated: true) }

Upvotes: 0

engineeric
engineeric

Reputation: 21

If setting up auto layout constraints doesn't fix the problem, try calling searchController.searchBar.sizeToFit() in viewWillLayoutSubviews() rather than viewDidLoad(). This may help if the search bar is contained in a view other than the table header view.

Upvotes: 0

nhyne
nhyne

Reputation: 445

Needed to set autolayout constraints for the tableView that the search bar was a part of. Setting these fixed the sizing issues.

Upvotes: 2

simardeep singh
simardeep singh

Reputation: 220

Just click on Pin option given below and select top,leading(left) and trailing(right) constraints, then click on Add 3 constraints. Make sure "Constraint to margin" checkbox is unchecked. If the constraints satisfy, There will be no warning. Try changing the background color of your search bar to see its position on the screen.

Upvotes: 0

simardeep singh
simardeep singh

Reputation: 220

If you're using Auto layout, then use leading and trailing edges instead of width constraints.

Upvotes: 1

Related Questions