UISearchController's UISearchBar's cursor shows first use, not subsequent
Asked Answered
H

6

10

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.

Hyperacidity answered 9/11, 2015 at 20:40 Comment(1)
It would help if you could post a link to a gist of this whole ViewController's code. Primarily I want to if you have any block syntax anywhere in this class. If so I want to see what code gets executed in them. I also want to see what this class is a delegate of, and if any of the callback methods from classes it's a delegate of, are firing completion blocks to do the callback. (Like as in an NSURLSessionDataTask.)Amidst
H
4

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.

Hymeneal answered 4/1, 2016 at 22:2 Comment(4)
BTW, to make it work, you want to do - (void)didPresentSearchController:(UISearchController *)searchController { searchController.searchBar.showsCancelButton = NO; } Hymeneal
Thanks for suggesting it. I was so hopeful, but it made no change for me. I've spent so much time trying to track this down with various combinations of things, I just cannot see straight any more. BTW: I changed the line you said, I have the didPresent and I have the same code in willPresent (to try to stop the cancel button flashing in/out.)Hyperacidity
Well.. at least I helped you in some way :)Hymeneal
This was the issue for me. The fix was to set the tint color immediately after searchController.searchBar.showsCancelButton = NOAglimmer
T
3

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
}
Transistorize answered 9/3, 2016 at 21:51 Comment(1)
I am sorry but I completely re-wrote this UI (in large part 'cos of this, and for a third time.) As such I am no longer able to test your fix. If other users upvote this answer (or the other answer) I'll eventually mark one of the two as the correct answer. Thanks for your help.Hyperacidity
B
2

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://mcmap.net/q/770551/-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

Belemnite answered 25/6, 2017 at 6:5 Comment(1)
Thank you for this!Macbeth
S
1

I had this same issue, if you set dimsBackgroundDuringPresentation = NO and obscuresBackgroundDuringPresentation = NO you will see the cursor again even if you have the cancel button hidden.

Sift answered 26/2, 2016 at 23:52 Comment(1)
I am sorry but I completely re-wrote this UI (in large part 'cos of this, and for a third time.) As such I am no longer able to test your fix. If other users upvote this answer (or the other answer) I'll eventually mark one of the two as the correct answer. Thanks for your help.Hyperacidity
T
0

Set the search view tint color from storyboard to any color you would like to have as a cursor.

Be careful to

set the tint color in the view section

instead of searchBar section, in attribute inspector in storyboard.

Twoedged answered 5/10, 2017 at 19:2 Comment(0)
D
0

For me the fix that worked was:

searchBar.setShowsCancelButton(false, animated: false)
searchBar.becomeFirstResponder()

in func searchBarTextDidBeginEditing(_ searchBar: UISearchBar)

Desk answered 28/11, 2017 at 15:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.