The search bar resets one line each time the cancel button is pressed.

I implemented a UISearchBar to search a catalog of items from an external API. The search function works as expected, but the problem is that every time I click the cancel button, which is to the right of the text field of the search bar, the entire search bar moves down one line, and it looks like it pushes the whole view tables down also.

Therefore, if I enter a letter in the text field of the search bar, then click "Cancel", the text field of the search bar will move down 44 pixels, which is the height of the line, and the table itself will also be shifted by the same amount. If I constantly click on the type of something, then click "Cancel", the search bar will move further and further down. Any advice would be helpful! Here is my code:

import Foundation import UIKit import ItemLogger private extension Selector { static let dismiss = #selector(SearchVC.dismissView) } extension SearchVC: UISearchResultsUpdating { func updateSearchResultsForSearchController(searchController: UISearchController) { let searchBar = searchController.searchBar let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex] filterContentForSearchText(searchController.searchBar.text!, scope: scope) } } extension SearchVC: UISearchBarDelegate { func searchBar(searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) { filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope]) } } class SearchVC: UITableViewController { let searchController = UISearchController(searchResultsController: nil) var searchedItems = [ItemLog]() var searchedImages = [UIImage]() override func viewDidLoad() { super.viewDidLoad() let leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "Back_Button"), style: UIBarButtonItemStyle.Plain, target: self, action: .dismiss) self.navigationItem.leftBarButtonItem = leftBarButtonItem } override func viewWillAppear(animated: Bool) { configureSearchController() } override func prefersStatusBarHidden() -> Bool { return true } func configureSearchController() { guard !searchController.active else { return } searchController.searchResultsUpdater = self searchController.dimsBackgroundDuringPresentation = false searchController.searchBar.placeholder = "Type to Search" definesPresentationContext = true searchController.searchBar.scopeButtonTitles = ["All"] searchController.searchBar.delegate = self searchController.searchBar.sizeToFit() tableView.tableHeaderView = searchController.searchBar let view: UIView = self.searchController.searchBar.subviews[0] as UIView for subView: UIView in view.subviews { if let textView = subView as? UITextField { textView.tintColor = UIColor.orangeColor() textView.textColor = UIColor.blackColor() textView.backgroundColor = UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 0.05) } } searchController.searchBar.barTintColor = UIColor.whiteColor() let cancelButtonAttributes: NSDictionary = [NSForegroundColorAttributeName: UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 0.33)] UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes as? [String : AnyObject], forState: UIControlState.Normal) } func searchBarTextDidBeginEditing(searchBar: UISearchBar) { tableView.reloadData() } override func tableView(tableView:UITableView, numberOfRowsInSection section: Int) -> Int { if searchController.active && searchController.searchBar.text != "" { return searchedItems.count } return 0 } override func tableView(tableView:UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = self.tableView.dequeueReusableCellWithIdentifier("items", forIndexPath: indexPath) let label = cell.viewWithTag(111) as! UILabel let nameLabel = cell.viewWithTag(222) as! UILabel let art = cell.viewWithTag(333) as! UIImageView if searchController.active && searchController.searchBar.text != "" && searchController.searchBar.text != NSCharacterSet.whitespaceCharacterSet(){ label.text = searchedItems[indexPath.row].title nameLabel.text = searchedItems[indexPath.row].name art.image = searchedImages[indexPath.row] } return cell } override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { print(searchedItems[indexPath.row]) self.tableView.deselectRowAtIndexPath(indexPath, animated: true) } func filterContentForSearchText(searchText: String, scope: String = "All") { if searchController.active && searchController.searchBar.text != "" && searchController.searchBar.text != NSCharacterSet.whitespaceCharacterSet() { let queries: [SearchQueryOptions] = [ .QueryString(searchController.searchBar.text!)] ItemLog.search(queries, completion: { (result) in if let itms = result.response.result where itms.count > 0 { self.searchedItems.removeAll() self.searchedImages.removeAll() for i in 0...itms.count - 1 { self.searchedItems.append(itms[i]) self.searchedImages.append(itms[i].img) } } self.tableView.reloadData() }) } } func dismissView(){ self.navigationController?.popToRootViewControllerAnimated(true) } } 
+8
ios swift uisearchbar uisearchcontroller
source share
3 answers

Code verified in Swift 3.

Note. When I try your code. I ran into the same problem. Somehow I managed to get around ...

 class SearchVC: UITableViewController,UISearchBarDelegate,UISearchResultUpdating { var resultSearchController = UISearchController() override func viewDidLoad() { super.viewDidLoad() configureSearchController() } override var prefersStatusBarHidden: Bool { return true } func configureSearchController() { self.resultSearchController = ({ let controller = UISearchController(searchResultsController: nil) controller.searchResultsUpdater = self controller.dimsBackgroundDuringPresentation = false controller.hidesNavigationBarDuringPresentation = false controller.searchBar.searchBarStyle = .default controller.searchBar.sizeToFit() controller.searchBar.setShowsCancelButton(false, animated: true) controller.searchBar.keyboardAppearance = .default self.tableView.tableHeaderView = controller.searchBar //controller.searchBar.tintColor = UIColor(patternImage: UIImage(named: "xxxx")!) // controller.searchBar.setBackgroundImage(UIImage(named: "xxxx"), forBarPosition: UIBarPosition.Top, barMetrics: UIBarMetrics.Default) // controller.searchBar.backgroundImage = UIImage(named: "xxxx") // controller.searchBar.setImage(UIImage(named: "search-icon.png"), forSearchBarIcon: UISearchBarIcon.Search, state: UIControlState.Normal) return controller })() for subView in self.resultSearchController.searchBar.subviews { for subsubView in subView.subviews { if let textField = subsubView as? UITextField { textField.attributedPlaceholder = NSAttributedString(string: NSLocalizedString("Search Text", comment: ""), attributes: [NSForegroundColorAttributeName: UIColor.red]) textField.adjustsFontSizeToFitWidth = true textField.allowsEditingTextAttributes = true textField.textColor = UIColor.red textField.layer.borderColor = UIColor.gray.cgColor textField.layer.cornerRadius = 5 textField.layer.masksToBounds = true textField.layer.borderWidth = 0.215 } } } } } 

Updated:

  func updateSearchResults(for searchController: UISearchController) {} 

The code output is above. Hope my answer fix your problem .... enter image description here

+7
source share

Try calling configureSearchController() in viewDidLoad . And don't forget to call super.viewWillAppear(animated:) in viewWillAppear .

0
source share

I created an open source project SearchTableView

 self.searchController.searchBar.sizeToFit() self.tableHeaderView = self.searchController.searchBar searchTableView.layoutMargins = UIEdgeInsets.zero definesPresentationContext = true extendedLayoutIncludesOpaqueBars = true 
0
source share

All Articles