原生控件USearchBar 里面包含了几个view和一个UITextField, 下面是树结构
<UISearchBar: 0x15ee06620; frame = (0 64; 320 40); text = ''; opaque = NO; gestureRecognizers = <NSArray: 0x178243150>; layer = <CALayer: 0x17822a200>>
| <UIView: 0x17817a340; frame = (0 0; 320 40); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x17822ace0>>
| | <UISearchBarBackground: 0x15ed2ab10; frame = (0 0; 320 40); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x17822aac0>>
| | <UISearchBarTextField: 0x15edd0100; frame = (8 6; 304 28); text = ''; clipsToBounds = YES; opaque = NO; gestureRecognizers = <NSArray: 0x178245c10>; layer = <CALayer: 0x170229e80>>
| | | <_UISearchBarSearchFieldBackgroundView: 0x15ee2e400; frame = (0 0; 304 28); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x17822abe0>>
| | | <UIImageView: 0x1783e1300; frame = (142 7.5; 12.5 12.5); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x17822aca0>>
我们要自定义原生控件的外观, 比如说要更改输入框背景颜色, 需要找到UITextField 并更改属性即可,
方法一:
遍历查找,
UIColor *innerColor = [UIColor redColor];
for (UIView* subview in [[self.searchBar.subviews lastObject] subviews]) {
if ([subview isKindOfClass:[UITextField class]]) {
UITextField *textField = (UITextField*)subview;
textField.backgroundColor = innerColor;
}
}
方法二:
使用 UIAppearance 协议更改
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setBackgroundColor:innerColor];
更改的时候遇到一个问题: 更改不生效, 遍历时, 发现只有当 UISearchBar所在的Viewcontroller的View 加载完后才能找到, 这时候需要在初始化UISearchBar后,
调用 layoutSubviews ,让UISeachBar 加载所有子VIew, 即: [searchBar layoutSubviews] .
个人理解为 UISearchBar 为懒加载.