UISearchController searchbar animation very slow first time
Asked Answered
L

2

12

In iOS 9 I am using UISearchController and displaying its search bar within a UIViewController, I am experiencing a lot of lag the first time I click on the search bar and have tried everything i can think of to no avail...below is my code along with a link to a video of the lag happening - the lag happens on both the simulator and my device.

func setupUI() {
    self.view.backgroundColor = UIColor.whiteColor()

    // Required to properly display searchbar within nav & tabbar controllers
    self.extendedLayoutIncludesOpaqueBars = true // have tried setting this to false as well
    self.definesPresentationContext = true

    self.searchResultsController = AppDelegate.getViewController(ScheduleStoryboard.name, controllerName: ScheduleStoryboard.Identifiers.foodSearchResults) as? SearchResultsController

    self.searchController = UISearchController(searchResultsController: searchResultsController)
    self.searchController.searchResultsUpdater = self
    self.searchController.delegate = self
    self.searchController.dimsBackgroundDuringPresentation = true

    self.searchController.searchBar.delegate = self
    self.searchController.searchBar.placeholder = "Search foods..."
    self.searchController.searchBar.setBackgroundImage(UIImage(named: "background-searchbar")?.resizableImageWithCapInsets(UIEdgeInsetsMake(0, 0, 0, 0)), forBarPosition: .Any, barMetrics: .Default)
    self.searchController.searchBar.tintColor = UIColor.whiteColor()
    self.searchController.searchBar.sizeToFit()

    // this headerView does NOT belong to the tableView, its anchored on top of the tableView so that the searchbar remains fixed when scrolling
    self.headerView.addSubview(searchController.searchBar)

    self.tableView.delegate = self
    self.tableView.dataSource = self
    self.tableView.tableHeaderView?.backgroundColor = UIColor.clearColor()
    self.tableView.tableHeaderView?.addBorder(.Bottom, color: UIColor.groupTableViewBackgroundColor(), width: 0.25)

    self.segmentedControl.tintColor = UIColor.genioBlue()
}

Here is a link to the video showing whats happening: http://sendvid.com/xgq81stx

Thanks!

Leucopoiesis answered 18/12, 2015 at 1:8 Comment(9)
Have you been able to find a workaround for this? I'm facing the exact same issueOntina
same issue for me as well. I haven't found a solution either.Bedroll
are you testing it on the simulator? or on your iPhone or iPad? The simulator is usually buggy so maybe connect an actual device to try it out. Hope that helps! Let me know if it does.Spitball
@Spitball I've tried on both device (iPhone 6) & simulator - same experience for bothLeucopoiesis
still the same issue? I'm having the exact same problem. After the first time, things go smooth.Hannigan
I don't know what is the real cause of this bug, but in my case it because I added a UIRefreshControl to searchResultsController tableView. Remove it and no more slow animation.Savdeep
I think this line of code causes problems: "self.searchResultsController = AppDelegate.getViewController(ScheduleStoryboard.name, controllerName: ScheduleStoryboard.Identifiers.foodSearchResults) as? SearchResultsController" I think there you are iterating all the viewcontrollers and who knows how effective that search is.Levator
Hey you got the answer because I am facing same thing :(Courtesy
@Savdeep same here, managed to get it work commenting out adding refresh control. working with UIKit sometimes is fun.Mana
A
0

I've only ever created a search controller once, but I used a UITableViewController as my base class. Here is my implementation:

class SearchController: UITableViewController {
    let searchController = UISearchController(searchResultsController: nil)
    var items:[ArrayOfYourType]
    var filteredItems:[ArrayOfYourType]
    var scopeTitles:[String]?

override func viewDidLoad() {
    super.viewDidLoad()

    searchController.searchResultsUpdater = self
    searchController.dimsBackgroundDuringPresentation = false
    definesPresentationContext = true
    tableView.tableHeaderView = searchController.searchBar

    searchController.searchBar.scopeButtonTitles = scopeTitles
    searchController.searchBar.delegate = self
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if searchController.active {
        return filteredItems.count
    }
    return items.count
}

func filterContentForSearchText(searchText: String, scope: String = "All") {
    filteredItems = items.filter { item in
        //return true or false depending on your filter
        return true
    }
    dispatch_async(dispatch_get_main_queue(), { () -> Void in
        self.tableView.reloadData()
    })
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = UITableViewCell(style: UITableViewCellStyle.Subtitle,
        reuseIdentifier: nil)
    let item: String
    let category: String
    if searchController.active {
        item = filteredItems[indexPath.row].getTitle()
        category = filteredItems[indexPath.row].getCategory()
    }
    else {
        item = items[indexPath.row].getTitle()
        category = items[indexPath.row].getCategory()
    }
    cell.textLabel?.text = item
    cell.detailTextLabel?.text = category
    return cell
}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    //your code here
}
}

//MARK: UISearchResultsUpdating
extension SearchController: UISearchResultsUpdating {
    func updateSearchResultsForSearchController(searchController: UISearchController) {
        if let _ = scopeTitles {
            let searchBar = searchController.searchBar
            let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
            filterContentForSearchText(searchController.searchBar.text!,scope:scope)
        }
        else {
            filterContentForSearchText(searchController.searchBar.text!)
        }
    }
}

//MARK: UISearchBarDelegate
extension SearchController: UISearchBarDelegate {
    func searchBar(searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
        filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
    }
}

I hope this helps :)

Aurlie answered 7/7, 2016 at 20:31 Comment(0)
P
0

Could it be possible that the image you are using for the background search bar is too large?

It might be quicker to create a gradient. Here is a good tutorial

Pectize answered 11/9, 2019 at 18:42 Comment(1)
Please include the solution in your answer, if the link breaks your answer is gone.Distorted

© 2022 - 2024 — McMap. All rights reserved.