系统的searchBar
UISearchBar的中子控件及其布局
- UIView(直接子控件) frame 等于 searchBar的bounds,view的子控件及其布局
- UISearchBarBackground(间接子控件) frame 等于searchBar的bounds
- UISearchBarTextField(间接子控件) frame.origin等于(8.0, 6.0),即不等于searchBar的bounds
- UIView(直接子控件) frame 等于 searchBar的bounds,view的子控件及其布局
改变searchBar的frame只会影响其中搜索框的宽度,不会影响其高度,原因如下:
- 系统searchBar中的UISearchBarTextField的高度默认固定为28
- 左右边距固定为8,上下边距是父控件view的高度减去28除以2
改变UISearchBar的高度
方案
- 重写UISearchBar的子类(IDSearchBar),重新布局UISearchBar子控件的布局
- 增加成员属性contentInset,控制UISearchBarTextField距离父控件的边距
- 若用户没有设置contentInset,则计算出默认的contentInset
- 若用户设置了contentInset,则根据最新的contentInset布局UISearchBarTextField
具体实现
重写UISearchBar的子类
class IDSearchBar: UISearchBar { }
增加成员属性contentInset(可选类型),控制UISearchBarTextField距离父控件的边距,监听其值的改变,重新布局searchBar子控件的布局
var contentInset: UIEdgeInsets? {
didSet {
self.layoutSubviews()
}
}
重写layoutSubviews()布局searchBar的子控件
override func layoutSubviews() {
super.layoutSubviews() // view是searchBar中的唯一的直接子控件
for view in self.subviews {
// UISearchBarBackground与UISearchBarTextField是searchBar的简介子控件
for subview in view.subviews { // 找到UISearchBarTextField
if subview.isKindOfClass(UITextField.classForCoder()) { if let textFieldContentInset = contentInset { // 若contentInset被赋值
// 根据contentInset改变UISearchBarTextField的布局
subview.frame = CGRect(x: textFieldContentInset.left, y: textFieldContentInset.top, width: self.bounds.width - textFieldContentInset.left - textFieldContentInset.right, height: self.bounds.height - textFieldContentInset.top - textFieldContentInset.bottom)
} else { // 若contentSet未被赋值
// 设置UISearchBar中UISearchBarTextField的默认边距
let top: CGFloat = (self.bounds.height - 28.0) / 2.0
let bottom: CGFloat = top
let left: CGFloat = 8.0
let right: CGFloat = left
contentInset = UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)
}
}
}
}
}
IDSearchBar使用示例
未设置contentInset
设置searchBar的frame
searchBar.frame = CGRect(x: 80, y: 100, width: 200, height: 40)
效果如图
设置contentInset
设置searchBar的frame
searchBar.frame = CGRect(x: 80, y: 100, width: 200, height: 40)
设置searchBar的contentInset
// 设置contentInset
searchBar.contentInset = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 8)
效果如图
IDSearchBar的设计原则
- 注意
- UISearchBar默认是有自己默认的布局方式的
- 设计IDSearchBar旨在改变searBar中搜索框的高度,但是可能会有改变宽的的需求
- 设计原则
- 在没有改变searchBar中搜索框的高度的需求时,需要使用UISearchBar的默认布局
- 若需要改变searchBar中搜索框的高度的需求时,需要按照需求来改变UISearchBar的布局
- 为了增加可控性,在IDSearchBar中增加成员属性contentInset来控制IDSearchBar的内边距