Ugly Code for an Attractive UISearchBar

22 Feb 2015

Getting an iOS view to look exactly how you want it can be super frustrating. Take, for example, the simple requirement of hosting a UISearchBar inside a UITableViewCell. Here’s some code as a starting point:

namespaceUISearchBarExample{usingSystem;usingFoundation;usingUIKit;publicclassView:UITableViewController{publicoverridevoidViewDidLoad(){base.ViewDidLoad();this.TableView.Source=newSource();}privateclassSource:UITableViewSource{publicoverridenintRowsInSection(UITableViewtableview,nintsection){return2;}publicoverrideUITableViewCellGetCell(UITableViewtableView,NSIndexPathindexPath){varcell=newUITableViewCell();UIViewchild=null;if(indexPath.Row==0){child=newUILabel{Text="Some existing thing"};}else{child=newUISearchBar{Placeholder="Search for another thing"};}cell.AddSubview(child);cell.ConstrainLayout(()=>child.Left()==cell.Left()+Layout.StandardSuperviewSpacing&&child.Right()==cell.Right()-Layout.StandardSuperviewSpacing&&child.Top()==cell.Top()+Layout.StandardSiblingViewSpacing&&child.Bottom()==cell.Bottom()-Layout.StandardSiblingViewSpacing);returncell;}}}}

Obviously I’m not advocating this specific approach in a real app - I’m just getting to the crux of this post. Here is what this looks like when run (iPhone 4):

Clearly, that’s pretty ugly. We really need to lose the dark rectangle behind the search bar. You’d be forgiven for thinking it a simple matter of changing a property or two on UISearchBar. Perhaps BackgroundColor? Or maybe SearchBarStyle?

Turns out, changing the color properties (BackgroundColor, BarTintColor, TintColor) to UIColor.Clear actually makes matters worse because the background becomes solid black rather than gray. However, changing SearchBarStyle to Minimal gets us a small step forward:

This is slightly more attractive, though still not ideal. I’d like for the search bar to be even less conspicuous. I want to remove the gray rectangle with rounded corners.

Despite all the advice I could find to the contrary, this is simply not possible in iOS 8 (probably not in 7 either). I had to resort to some ugly code to make this happen…by digging through the visual tree to find the UITextField inside the UISearchBar, we can then make the necessary adjustments.

I started with an extension method to make it easier to traverse the visual tree and find a particular view:

With that, I could then find the UITextField and make the necessary adjustments:

child=newUISearchBar{SearchBarStyle=UISearchBarStyle.Minimal,Placeholder="Search for a new thing"};vartextField=child.FindChildRecursively<UITextField>(_=>true);textField.BorderStyle=UITextBorderStyle.None;