Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UISearchController's UISearchBar's cursor shows first use, not subsequent

First time this part of the application loads the search controller's search bar's cursor shows, as desired.

Search with Cursor

(The Problem) When search is dismissed and then (later) re-laoded, no cursor:

Search No Cursor

This is repeatable with just loading/dismissing, i.e. nothing that apparently could/should change the tint of things, causing a cursor to be the color of the background (as is typically the answer to missing cursor, from SO Q&As I've seen on the topic.) That said, nothing else fails to work, it is just the cursor that disappears.

Some (possibly) complicating factors:

  • This ViewController that loads/unloads the UISearchController (and embeds the UISearchBar into the UINavigationController's title) is a content VC within my custom container VC. The hierarchy is: (1) UIWindow (2) UINavigationController (3) ContainerVC (4) ContainedVC [parent is the ContainerVC, this VC is doing the UISearchController loading/unloading].
  • There are various delegate callbacks (UISearchController, UISearchBar) that attempt to customize behaviors (e.g. hide cancel button, stop closure between) that hopefully don't impact things, but FYI.
  • The "unload" (to stop / tear down) involves various efforts to make it go away, removing searchbar from title view, setting search controller active=false, and such. (Since it occurs after this, it feels likely related, so I've tried various permutations in case anything helps. No such luck.)

I have made various attempt to have the child VC create it's own SearchController, and/or use one on the root VCs, and so forth. The various permutations seem to work, but with this same flaw. (As such, I feel I'm looking in the wrong place for the source of the problem/solution.)

I cannot rule out the the cursor color has changed, I don't fully understand how it is set/inherited, especially given the VC stack I have, nor how to test it in a debugger. I think it is as simple as I set a global tint.

Note: This app is using storyboard with direct settings, and is not using appearance proxies much. That said it has:

    // Default tint for application...
    UIApplication.sharedApplication().delegate?.window??.tintColor = mainBrandColor
    UIToolbar.appearance().tintColor = mainBrandColor

... and I've tried with various permutations of UISearchBar, UINavigationBar tints via appearance proxy w/ same behavior (first works, subsequent not so much.) Looking at this, at various times, (i.e. when working and when not) it shows the same color:

(lldb) po searchController.searchBar.tintColor

Note: A separate use of UISearchController (when the calling VC is not a child of the container, but a pushed VC) does NOT demonstrate this problem. The cursor remains the correct color.

Environment: This is an iOS9.x application in Swift on XCode 7.1.

Here is some code, where homeVC is the parent/container VC:

    if nil == homeVC.searchController {
        homeVC.searchController = UISearchController(searchResultsController: nil)
        homeVC.searchController!.searchResultsUpdater = self
        homeVC.searchController!.delegate = self
        homeVC.searchController!.searchBar.delegate = self
        homeVC.searchController!.searchBar.showsCancelButton = false
        homeVC.searchController!.searchBar.returnKeyType = .Done
        homeVC.searchController!.searchBar.placeholder = "Add Item"
        homeVC.searchController!.searchBar.searchBarStyle = UISearchBarStyle.Minimal
        homeVC.searchController!.dimsBackgroundDuringPresentation = false
        homeVC.searchController!.hidesNavigationBarDuringPresentation = false
    }

    homeVC.navigationItem.titleView              = homeVC.searchController!.searchBar

I've tried with and without lazy loading, and with destroying / re-creating and not.

Any pointers/thoughts on where to look / how to troubleshoot would be be appreciated.

like image 527
Adam Jack Avatar asked Nov 09 '15 20:11

Adam Jack


3 Answers

Are you doing self.searchController.searchBar.showsCancelButton = NO;

I had exactly the same problem and it turns out that this thing is somehow related. Try to comment it out and see if the cursor is back.

like image 129
user1491604 Avatar answered Sep 19 '22 16:09

user1491604


I was having the same problem. The trick that worked for me was setting the tintColor of the UISearchBar when it becomes the firstResponder

func searchBarShouldBeginEditing(searchBar: UISearchBar) -> Bool {
    searchBar.tintColor = UIColor.redColor()
    return true
}
like image 29
JohnGrana Avatar answered Sep 21 '22 16:09

JohnGrana


I had a big headache with this same problem. user1491604 (the first answer) is correct that the cause of the problem is:

searchController.searchBar.showsCancelButton = false //Swift 3

Commenting it out completely fixed the problem but then I ran into what to do if I DIDN'T want to show the Cancel button at all like below:

enter image description here

If you don't want to show the cancel button at all then user1491604's answer won't work. I followed Vitya Shurapov's answer (which works in this situation) to implement my own SearchController:

https://stackoverflow.com/questions/29976503/uisearchcontroller-searchbar-showscancelbutton-not-being-respected/42030000#42030000

class CustomSearchBar: UISearchBar {

    override func setShowsCancelButton(_ showsCancelButton: Bool, animated: Bool) {
        super.setShowsCancelButton(false, animated: false)
    }
}


class CustomSearchController: UISearchController {

    lazy var _searchBar: CustomSearchBar = {
        [unowned self] in
        let customSearchBar = CustomSearchBar(frame: CGRect.zero)
        return customSearchBar
    }()

    override var searchBar: UISearchBar {
        get {
            return _searchBar
        }
    }
}

Then to use it in viewDidLoad I used:

let searchController = CustomSearchController(searchResultsController: nil)
//...configure the rest of the searchController...

//DELETE- searchController.searchBar.showsCancelButton -you can delete this line wherever your using it

Problem solved for me

like image 30
Lance Samaria Avatar answered Sep 18 '22 16:09

Lance Samaria