以下內(nèi)容是在 Swift 4.0马澈,iOS 11 下的運行結果
默認樣式
初始化一個 UISearchController,并將 searchBar 設置為 tableView 的 headerView 時飞傀,如以下代碼:
let searchController = UISearchController.init(searchResultsController: nil)
tableView.tableHeaderView = searchController.searchBar
此時的樣式為:
默認樣式 | 高亮 |
---|---|
自定義
下面我們通過修改 searchController 的 searchBar 屬性來調整樣式织鲸。
1. searchBarStyle
搜索框樣式
public enum UISearchBarStyle : UInt {
case `default` // 默認樣式媚狰,和 UISearchBarStyleProminent 一樣
case prominent // 顯示背景,常用在my Mail, Messages and Contacts
case minimal // 不顯示背景诱篷,系統(tǒng)自帶的背景色無效壶唤,自定義的有效,常用在Calendar, Notes and Music
}
用例:
let searchBar = searchController.searchBar
searchBar.searchBarStyle = .default
searchBarStyle | 非活躍 | 活躍 |
---|---|---|
default | ||
prominent | ||
minimal |
2. tintColor
風格顏色棕所,可用于修改:
- 輸入框的光標顏色
- 取消按鈕字體顏色
- 選擇欄被選中時的顏色
let searchBar = searchController.searchBar
searchBar.tintColor = .red
非活躍 | 活躍 |
---|---|
3. barTintColor
搜索框背景顏色
let searchBar = searchController.searchBar
searchBar.barTintColor = .orange
非活躍 | 活躍 |
---|---|
4. backgroundImage
搜索框背景圖片
createImage(_:size:)
方法為創(chuàng)建一個指定顏色闸盔,指定 size 的圖片。
let searchBar = searchController.searchBar
searchBar.backgroundImage = self.createImage(UIColor.red, size: CGSize.init(width: 200, height: 100))
非活躍 | 活躍 |
---|---|
5. 設置(獲瘸鹊省)搜索框背景圖片
可以通過以下方式設置(獲壤倥埂)搜索框背景圖片:
// 設置
// Use UIBarMetricsDefaultPrompt to set a separate backgroundImage for a search bar with a prompt
func setBackgroundImage(_ backgroundImage: UIImage?, for barPosition: UIBarPosition, barMetrics: UIBarMetrics)
// 獲取
open func backgroundImage(for barPosition: UIBarPosition, barMetrics: UIBarMetrics) -> UIImage?
public enum UIBarMetrics : Int {
case `default`
case compact
case defaultPrompt // Applicable only in bars with the prompt property, such as UINavigationBar and UISearchBar
case compactPrompt
@available(iOS, introduced: 5.0, deprecated: 8.0, message: "Use UIBarMetricsCompact instead")
public static var landscapePhone: UIBarMetrics { get }
@available(iOS, introduced: 7.0, deprecated: 8.0, message: "Use UIBarMetricsCompactPrompt")
public static var landscapePhonePrompt: UIBarMetrics { get }
}
@available(iOS 7.0, *)
public enum UIBarPosition : Int {
case any
case bottom // The bar is at the bottom of its local context, and directional decoration draws accordingly (e.g., shadow above the bar).
case top // The bar is at the top of its local context, and directional decoration draws accordingly (e.g., shadow below the bar)
case topAttached // The bar is at the top of the screen (as well as its local context), and its background extends upward—currently only enough for the status bar.
}
用例:
let searchBar = searchController.searchBar
searchBar.setBackgroundImage(createImage(.blue, size: CGSize.init(width: 20, height: 20)), for: .any, barMetrics: .default)
默認樣式 | 高亮 |
---|---|
6. 文本框的背景圖片
open func setSearchFieldBackgroundImage(_ backgroundImage: UIImage?, for state: UIControlState)
open func searchFieldBackgroundImage(for state: UIControlState) -> UIImage?
let searchBar = searchController.searchBar
searchBar.setSearchFieldBackgroundImage(createImage(UIColor.yellow, size: CGSize.init(width: 200, height: 40)), for: .normal)
默認樣式 | 高亮 |
---|---|
7. barStyle
搜索框風格 barStyle 的類型為 UIBarStyle,定義如下:
public enum UIBarStyle : Int {
case `default`
case black
}
用例:
let searchBar = searchController.searchBar
searchBar.barStyle = .black
barStyle | 非活躍 | 活躍 |
---|---|---|
default | ||
black |
8. showsBookmarkButton
是否顯示搜索框右側的圖書按鈕岛啸。
open var showsBookmarkButton: Bool // default is NO
barStyle | 非活躍 | 活躍 |
---|---|---|
false | ||
true |
9. showsCancelButton
是否顯示搜索框右側的取消按鈕钓觉。
open var showsCancelButton: Bool // default is NO
showsCancelButton | 默認樣式 | 高亮 |
---|---|---|
false | ||
true |
10. showsSearchResultsButton
是否顯示搜索框右側的搜索結果按鈕:
open var showsSearchResultsButton: Bool // default is NO
showsSearchResultsButton | 非活躍 | 活躍 |
---|---|---|
false | ||
true |
11. isSearchResultsButtonSelected
設置搜索結果按鈕為選中狀態(tài):
open var isSearchResultsButtonSelected: Bool // default is NO
用例:
let searchBar = searchController.searchBar
searchBar.showsSearchResultsButton = true
searchBar.isSearchResultsButtonSelected = true
isSearchResultsButtonSelected | 非活躍 | 活躍 |
---|---|---|
false | ||
true |
12. searchFieldBackgroundPositionAdjustment
設置輸入框背景偏移量:
open var searchFieldBackgroundPositionAdjustment: UIOffset
用例:
let searchBar = searchController.searchBar
searchBar.searchFieldBackgroundPositionAdjustment = UIOffset.init(horizontal: 16, vertical: 16)
默認樣式 | 高亮 | |
---|---|---|
設置前 | ||
設置后 |
13. searchTextPositionAdjustment
設置輸入框文本偏移量:
open var searchTextPositionAdjustment: UIOffset
用例:
let searchBar = searchController.searchBar
searchBar.searchTextPositionAdjustment = UIOffset.init(horizontal: 16, vertical: 16)
默認樣式 | 高亮 | |
---|---|---|
設置前 | ||
設置后 |
14. 設置(獲取)搜索框的圖標
可以設置(獲燃岵取)的搜索框圖標包括:
- 搜索圖標
- 清除輸入的文字的圖標
- 圖書圖標
- 搜索結果列表圖標
open func setImage(_ iconImage: UIImage?, for icon: UISearchBarIcon, state: UIControlState)
open func image(for icon: UISearchBarIcon, state: UIControlState) -> UIImage?
用例:
let searchBar = searchController.searchBar
searchBar.showsBookmarkButton = true
let searchImage = self.createImage(.red, size: CGSize.init(width: 20, height: 20))
let clearImage = self.createImage(.yellow, size: CGSize.init(width: 20, height: 20))
let bookmarkImage = self.createImage(.blue, size: CGSize.init(width: 20, height: 20))
let resultsListImage = self.createImage(.orange, size: CGSize.init(width: 20, height: 20))
searchBar.setImage(searchImage, for: .search, state: .normal)
searchBar.setImage(clearImage, for: .clear, state: .normal)
searchBar.setImage(bookmarkImage, for: .bookmark, state: .normal)
searchBar.setImage(resultsListImage, for: .resultsList, state: .normal)
默認樣式 | 高亮輸入空白 | 高亮輸入內(nèi)容 |
---|---|---|
搜索結果列表圖標在什么條件下會顯示呢荡灾?我沒有試出來。
15. 設置(獲人仓)搜索框的圖標的偏移量
除了可以設置(獲扰稀) 14 中的圖片,還可以設置(獲壬そ凇)的偏移量荧缘。
open func setPositionAdjustment(_ adjustment: UIOffset, for icon: UISearchBarIcon)
open func positionAdjustment(for icon: UISearchBarIcon) -> UIOffset
用例:
let searchBar = searchController.searchBar
searchBar.setPositionAdjustment(UIOffset.init(horizontal: 10, vertical: 10), for: .search)
默認樣式 | 高亮 |
---|---|
16. 顯示(隱藏)取消按鈕
可以用以下方法設置顯示(隱藏)取消按鈕:
open func setShowsCancelButton(_ showsCancelButton: Bool, animated: Bool)
當我們希望徹底隱藏掉取消按鈕的時候,應該怎么做呢拦宣?經(jīng)過測試發(fā)現(xiàn)截粗,只有在 UISearchController
的 delegate
中的 didPresentSearchController(_)
實現(xiàn)內(nèi)調用可以實現(xiàn)隱藏取消按鈕。
extension ViewController: UISearchControllerDelegate {
func didPresentSearchController(_ searchController: UISearchController) {
searchController.searchBar.setShowsCancelButton(false, animated: false)
}
}
效果如下:
可以發(fā)現(xiàn)取消按鈕先顯示了一下鸵隧,然后隱藏了绸罗,效果并不理想。如果想徹底隱藏取消按鈕豆瘫,有一種方法是繼承 UISearchController
和 UISearchBar
實現(xiàn)自定義珊蟀。代碼如下:
// 自定義 UISearchBar
class CustomSearchBar: UISearchBar {
override func layoutSubviews() {
super.layoutSubviews()
setShowsCancelButton(false, animated: false)
}
}
// 自定義 UISearchController
class CustomSearchController: UISearchController {
lazy var _searchBar: CustomSearchBar = { [unowned self] in
let result = CustomSearchBar(frame: CGRect.zero)
result.delegate = self
return result
}()
override var searchBar: UISearchBar {
return _searchBar
}
}
extension CustomSearchController: UISearchBarDelegate {
}
使用自定義的 CustomSearchController
可以完全隱藏取消按鈕,效果如下:
17. 設置取消按鈕的名稱
可以通過以下幾個方法修改取消按鈕的名稱:
方法一:
let searchBar = searchController.searchBar
searchBar.setValue("Done", forKey:"_cancelButtonText")
方法二:
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title = "Done"
方法三:
let searchBar = searchController.searchBar
searchBar.showsCancelButton = true
let cancelButton = searchBar.value(forKey: "cancelButton") as? UIButton
cancelButton?.setTitle("Done", for: .normal)
注意方法三的設置順序外驱,需要先設置 showsCancelButton 為 true育灸,這種方式的問題在于 cancelButton 一開始就要被設置為顯示腻窒。
18. 搜索框附屬分欄條
在搜索框下面可以顯示搜索框附屬分欄條。
用例:
let searchBar = searchController.searchBar
searchBar.showsScopeBar = true
// 選擇按鈕視圖的按鈕標題
searchBar.scopeButtonTitles = ["One", "Two", "Three"]
// 選中的選擇按鈕下標值磅崭,默認值為 0定页,如果超出索引范圍則會被忽略
searchBar.selectedScopeButtonIndex = 1
默認樣式 | 高亮 |
---|---|
19. 搜索框附屬分欄條——背景顏色
可以通過通過 scopeBarBackgroundImage
設置搜索框附屬分欄條的背景顏色
open var scopeBarBackgroundImage: UIImage?
用例(注意以下代碼的順序可能會產(chǎn)生不同的效果):
let searchBar = searchController.searchBar
searchBar.showsScopeBar = true
// 選擇按鈕視圖的按鈕標題
searchBar.scopeButtonTitles = ["One", "Two", "Three"]
// 選中的選擇按鈕下標值,默認值為 0绽诚,如果超出索引范圍則會被忽略
searchBar.selectedScopeButtonIndex = 1
searchBar.scopeBarBackgroundImage = self.createImage(UIColor.yellow, size: CGSize.init(width: 200, height: 100))
默認樣式 | 高亮 |
---|---|
20. 搜索框附屬分欄條——按鈕的背景圖片
用以下方法可以設置(獲取)搜索框附屬分欄條按鈕的背景圖片:
open func setScopeBarButtonBackgroundImage(_ backgroundImage: UIImage?, for state: UIControlState)
open func scopeBarButtonBackgroundImage(for state: UIControlState) -> UIImage?
用例:
let searchBar = searchController.searchBar
searchBar.showsScopeBar = true
// 選擇按鈕視圖的按鈕標題
searchBar.scopeButtonTitles = ["One", "Two", "Three"]
// 選中的選擇按鈕下標值杭煎,默認值為 0恩够,如果超出索引范圍則會被忽略
searchBar.selectedScopeButtonIndex = 1
searchBar.scopeBarBackgroundImage = self.createImage(UIColor.yellow, size: CGSize.init(width: 200, height: 100))
searchBar.setScopeBarButtonBackgroundImage(createImage(.orange, size: CGSize.init(width: 20, height: 20)), for: .normal)
默認樣式 | 高亮 |
---|---|
21. 搜索框附屬分欄條——按鈕的分割線圖片
可以用以下方法設置(獲取)搜索框附屬分欄條按鈕的分割線圖片:
open func setScopeBarButtonDividerImage(_ dividerImage: UIImage?, forLeftSegmentState leftState: UIControlState, rightSegmentState rightState: UIControlState)
open func scopeBarButtonDividerImage(forLeftSegmentState leftState: UIControlState, rightSegmentState rightState: UIControlState) -> UIImage?
用例:
let searchBar = searchController.searchBar
searchBar.showsScopeBar = true
// 選擇按鈕視圖的按鈕標題
searchBar.scopeButtonTitles = ["One", "Two", "Three"]
// 選中的選擇按鈕下標值羡铲,默認值為 0蜂桶,如果超出索引范圍則會被忽略
searchBar.selectedScopeButtonIndex = 1
searchBar.setScopeBarButtonDividerImage(createImage(.red, size: CGSize.init(width: 10, height: 20)), forLeftSegmentState: .normal, rightSegmentState: .normal)
默認樣式 | 高亮 |
---|---|
22. 搜索框附屬分欄條——按鈕的標題樣式
可以用以下方法設置(獲取)搜索框附屬分欄條按鈕的標題樣式:
open func setScopeBarButtonTitleTextAttributes(_ attributes: [String : Any]?, for state: UIControlState)
open func scopeBarButtonTitleTextAttributes(for state: UIControlState) -> [String : Any]?
用例:
let searchBar = searchController.searchBar
searchBar.showsScopeBar = true
// 選擇按鈕視圖的按鈕標題
searchBar.scopeButtonTitles = ["One", "Two", "Three"]
// 選中的選擇按鈕下標值也切,默認值為 0扑媚,如果超出索引范圍則會被忽略
searchBar.selectedScopeButtonIndex = 1
searchBar.setScopeBarButtonTitleTextAttributes([NSAttributedStringKey.font.rawValue : UIFont.systemFont(ofSize: 20), NSAttributedStringKey.foregroundColor.rawValue : UIColor.red], for: .normal)
searchBar.setScopeBarButtonTitleTextAttributes([NSAttributedStringKey.font.rawValue : UIFont.systemFont(ofSize: 24), NSAttributedStringKey.foregroundColor.rawValue : UIColor.yellow], for: .selected)
默認樣式 | 高亮 |
---|---|
23. 搜索頂部提示
在搜索框頂部可以通知 prompt 設置提示信息。
比如:
let searchBar = searchController.searchBar
searchBar.prompt = "非活躍"
可以在 searchBar 的代理里修改 prompt 的內(nèi)容雷恃,例如:
extension ViewController: UISearchBarDelegate {
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchBar.prompt = "開始編輯"
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
searchBar.prompt = "取消編輯"
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchBar.prompt = "當前輸入:\(searchText)"
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.prompt = "點擊取消"
}
}
效果如下
非活躍 | 開始編輯 | 輸入內(nèi) | 取消編輯 |
---|---|---|---|
可以發(fā)現(xiàn)頂部的提示文字和輸入框重合了疆股。所以向下調整一下輸入框的偏移量。
prompt 為空時 searchBar 的高度為 56倒槐,不為空時 searchBar 的高度為 75旬痹,所以我們將輸入框向下調整 19:
searchBar.searchFieldBackgroundPositionAdjustment = UIOffset.init(horizontal: 0, vertical: 19)
效果如下
非活躍 | 開始編輯 | 輸入內(nèi) | 取消編輯 |
---|---|---|---|
可以發(fā)現(xiàn)還是有問題:
- 取消按鈕和輸入框不在一行上了
- 如果 prompt 有時有值,有時為空讨越,searchBar 的高度無法靈活改變两残。
這些問題暫時沒有找到解決方案。
其他待解決問題
- isTranslucent 沒有發(fā)現(xiàn)效果
- inputAssistantItem
- inputAccessoryView
- 搜索結果列表圖標在什么條件下會顯示