众所周知,iOS提供了非常方便的UISearchBar控件,用来开发页面上的搜索功能。但是有时候我们想要自定义,比如加个背景色,比如更改字体,比如修改样式,加个下拉菜单,并不是那么容易的,因为iOS没有提供更具体的这类的接口给开发者,那么怎么办呢,其实也是有办法的。UISearchBar本质上也是由很多我们已知的控件所构成的,比如UITextField,UIButton等,我们只要取到这些控件,就可以某种程度上为所欲为啦。
由于苹果没有提供接口,那么最笨也最简单的方法,就是遍历UISearchBar的subviews了,如下:
获取textField:
01 | UISearchBar *searchBar=[UISearchBar new ]; |
02 | UITextField *textField; |
03 | if ([[[UIDevice currentDevice] systemVersion] floatValue] > 6.1f) { |
04 | for (UIView *subv in searchBar.subviews) { |
05 | for (UIView* view in subv.subviews) { |
06 | if ([view isKindOfClass:[UITextField class ]]) { |
07 | textField = (UITextField*)view; |
13 | for (UITextField *subv in searchBar.subviews) { |
14 | if ([subv isKindOfClass:[UITextField class ]]) { |
15 | textField = (UITextField*)subv; |
获取backgroundView:
01 | NSArray *subs = searchBar.subviews; |
02 | UIView *backgroundView; |
03 | if ([[[UIDevice currentDevice] systemVersion] floatValue] > 6.1f) { |
04 | for ( int i = 0; i < [subs count]; i++) { |
05 | UIView* subv = (UIView*)[searchBar.subviews objectAtIndex:i]; |
06 | for (UIView* subview in subv.subviews) { |
07 | if ([subview isKindOfClass:NSClassFromString(@ "UISearchBarBackground" )]) |
09 | backgroundView = subv; |
16 | for ( int i = 0; i < [subs count]; i++) { |
17 | UIView* subv = (UIView*)[searchBar.subviews objectAtIndex:i]; |
18 | if ([subv isKindOfClass:NSClassFromString(@ "UISearchBarBackground" )]) |
20 | backgroundView = subv; |
UISearchBar有一个取消按钮,在搜索框失去焦点的时候,键盘会自动收起,取消按钮会变成不可点,但是某种场景下我们需要让按钮可点击,那该如何呢,比如实现如下图的效果:
点击取消可以直接关闭包含最近搜索和热门推荐内的整个搜索view。减少用户操作次数。提升用户体验。代码如下:
01 | [self enableControlsInView:searchBar]; |
03 | - ( void )enableControlsInView:(UIView *)view |
05 | for (id subview in view.subviews) { |
06 | if ([subview isKindOfClass:[UIControl class ]]) { |
07 | [subview setEnabled:YES]; |
09 | [self enableControlsInView:subview]; |
以上代码使用递归巧妙的实现了遍历所有subview,并且使得UIControll类型的控件都是enable的,如果遍历到UIButton就等于设置为可点击的。
当然以上只是简单的例子,真正使用时一般会写一个类比如TBSearchBar去继承UISearchBar,然后实现获取内部控件并且赋值给TBSearchBar的属性。通过操作修改属性来实现业务功能和searchBar的自定义。
另外我们可以发现以上代码都对iOS版本做了不同逻辑的判断,因为前面说过,UISearchBar并没有开放内部接口给开发者,我们获取内部的UIButton和UITextField都是属于非苹果认可的操作,所以会受制于iOS版本的更新,因为苹果可能在更新时调整了内部控件的逻辑,也就意味着我们获取内部控件的代码也会随着iOS升级而变化,所以为了不那么折腾,或者出现意外情况(比如iOS升级后UISearchBar内部控件获取失败导致页面或者程序逻辑出错),还是建议老老实实用苹果开放给开发者的接口吧:)