Search code examples
iosswiftuikituisearchbar

Swift - How to give shadow to UISearchBar but *not* its cancel button?


I have a search bar that I have applied a drop shadow to, and as you can see here, the cancel button casts its own shadow too. I would like for the shadow to be limited to the search text box. Here is what I'm starting with:

    let searchBar = UISearchBar()
    searchBar.placeholder = "KAT Milkshake"
    searchBar.backgroundImage = UIImage()
    searchBar.barTintColor = UIColor.white
    searchBar.compatibleSearchTextField.leftView?.tintColor = UIColor.gray
    searchBar.compatibleSearchTextField.backgroundColor = UIColor.white

    searchBar.layer.shadowColor = UIColor.black.cgColor
    searchBar.layer.shadowOpacity = 0.25
    searchBar.layer.shadowOffset = CGSize(width: 2, height: 2)
    searchBar.layer.shadowRadius = 5

What I've tried:

  1. I tried altering the cancel button's appearance via UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]), but it turns out that this object's shadow is a separate one. Notice the subtle difference around the letters after I applied another shadow by modifying the appearance shadow properties.

  2. Giving the button a white image background didn't work, which I did by accessing searchBar.value(forKey: "cancelButton") as! UIButton. The shadow is applied around the whole image and looks even worse.

  3. Adjusting the bounds of the search bar layer unfortunately did not work either ( searchBar.layer.frame = CGRect(x: searchBar.frame.minX, y: searchBar.frame.minY, width: searchBar.frame.width - cancelButton.frame.width, height: searchBar.frame.height)). I gave the search bar layer a border to observe this, and the cancel button shadow persists.

  4. I also tried unlinking the cancel button from the superview, but was only able to make it disappear entirely.

Is there any way around this? I'm on Swift 5 and iOS 14.


Solution

  • As ibrahimyilmaz suggested, adding the shadow to the UITextField instead of UISearchBar got the job done. Just had to modify my height and layout anchor constraints to handle clipping.

    I followed this example by user Joshpy in order to access the text field. For iOS >= 13, making the shadow is as simple as:

        searchBar.searchTextField.layer.shadowColor = UIColor.black.cgColor
        searchBar.searchTextField.layer.shadowOpacity = 0.25
        searchBar.searchTextField.layer.shadowOffset = CGSize(width: 2, height: 2)
        searchBar.searchTextField.layer.shadowRadius = 5