博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UISearchController 定制UI(Swift)
阅读量:6316 次
发布时间:2019-06-22

本文共 11696 字,大约阅读时间需要 38 分钟。

以下内容是在 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 // 不显示背景,系统自带的背景色无效,自定义的有效,常用在Calendar, Notes and Music}复制代码

用例:

let searchBar = searchController.searchBarsearchBar.searchBarStyle = .default复制代码
searchBarStyle 非活跃 活跃
default
prominent
minimal
2. tintColor

风格颜色,可用于修改:

  • 输入框的光标颜色
  • 取消按钮字体颜色
  • 选择栏被选中时的颜色
let searchBar = searchController.searchBarsearchBar.tintColor = .red复制代码
非活跃 活跃
3. barTintColor

搜索框背景颜色

let searchBar = searchController.searchBarsearchBar.barTintColor = .orange复制代码
非活跃 活跃
4. backgroundImage

搜索框背景图片

createImage(_:size:) 方法为创建一个指定颜色,指定 size 的图片。

let searchBar = searchController.searchBarsearchBar.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 promptfunc 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.searchBarsearchBar.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.searchBarsearchBar.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.searchBarsearchBar.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

设置搜索结果按钮为选中状态:

open var isSearchResultsButtonSelected: Bool // default is NO复制代码

用例:

let searchBar = searchController.searchBarsearchBar.showsSearchResultsButton = truesearchBar.isSearchResultsButtonSelected = true复制代码
isSearchResultsButtonSelected 非活跃 活跃
false
true
12. searchFieldBackgroundPositionAdjustment

设置输入框背景偏移量:

open var searchFieldBackgroundPositionAdjustment: UIOffset复制代码

用例:

let searchBar = searchController.searchBarsearchBar.searchFieldBackgroundPositionAdjustment = UIOffset.init(horizontal: 16, vertical: 16)复制代码
默认样式 高亮
设置前
设置后
13. searchTextPositionAdjustment

设置输入框文本偏移量:

open var searchTextPositionAdjustment: UIOffset复制代码

用例:

let searchBar = searchController.searchBarsearchBar.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.searchBarsearchBar.showsBookmarkButton = truelet 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)复制代码
默认样式 高亮输入空白 高亮输入内容

搜索结果列表图标在什么条件下会显示呢?我没有试出来。

15. 设置(获取)搜索框的图标的偏移量

除了可以设置(获取) 14 中的图片,还可以设置(获取)的偏移量。

open func setPositionAdjustment(_ adjustment: UIOffset, for icon: UISearchBarIcon)open func positionAdjustment(for icon: UISearchBarIcon) -> UIOffset复制代码

用例:

let searchBar = searchController.searchBarsearchBar.setPositionAdjustment(UIOffset.init(horizontal: 10, vertical: 10), for: .search)复制代码
默认样式 高亮
16. 显示(隐藏)取消按钮

可以用以下方法设置显示(隐藏)取消按钮:

open func setShowsCancelButton(_ showsCancelButton: Bool, animated: Bool)复制代码

当我们希望彻底隐藏掉取消按钮的时候,应该怎么做呢?经过测试发现,只有在 UISearchControllerdelegate 中的 didPresentSearchController(_) 实现内调用可以实现隐藏取消按钮。

extension ViewController: UISearchControllerDelegate {    func didPresentSearchController(_ searchController: UISearchController) {        searchController.searchBar.setShowsCancelButton(false, animated: false)    }}复制代码

效果如下:

可以发现取消按钮先显示了一下,然后隐藏了,效果并不理想。如果想彻底隐藏取消按钮,有一种方法是继承 UISearchControllerUISearchBar 实现自定义。代码如下:

// 自定义 UISearchBar class CustomSearchBar: UISearchBar {    override func layoutSubviews() {        super.layoutSubviews()        setShowsCancelButton(false, animated: false)    }}// 自定义 UISearchControllerclass 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.searchBarsearchBar.setValue("Done", forKey:"_cancelButtonText")复制代码

方法二:

UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title = "Done"复制代码

方法三:

let searchBar = searchController.searchBarsearchBar.showsCancelButton = truelet cancelButton = searchBar.value(forKey: "cancelButton") as? UIButtoncancelButton?.setTitle("Done", for: .normal)复制代码

注意方法三的设置顺序,需要先设置 showsCancelButton 为 true,这种方式的问题在于 cancelButton 一开始就要被设置为显示。


18. 搜索框附属分栏条

在搜索框下面可以显示搜索框附属分栏条。 用例:

let searchBar = searchController.searchBarsearchBar.showsScopeBar = true// 选择按钮视图的按钮标题searchBar.scopeButtonTitles = ["One", "Two", "Three"]// 选中的选择按钮下标值,默认值为 0,如果超出索引范围则会被忽略searchBar.selectedScopeButtonIndex = 1复制代码
默认样式 高亮
19. 搜索框附属分栏条——背景颜色

可以通过通过 scopeBarBackgroundImage 设置搜索框附属分栏条的背景颜色

open var scopeBarBackgroundImage: UIImage?复制代码

用例(注意以下代码的顺序可能会产生不同的效果):

let searchBar = searchController.searchBarsearchBar.showsScopeBar = true// 选择按钮视图的按钮标题searchBar.scopeButtonTitles = ["One", "Two", "Three"]// 选中的选择按钮下标值,默认值为 0,如果超出索引范围则会被忽略searchBar.selectedScopeButtonIndex = 1searchBar.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.searchBarsearchBar.showsScopeBar = true// 选择按钮视图的按钮标题searchBar.scopeButtonTitles = ["One", "Two", "Three"]// 选中的选择按钮下标值,默认值为 0,如果超出索引范围则会被忽略searchBar.selectedScopeButtonIndex = 1searchBar.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.searchBarsearchBar.showsScopeBar = true// 选择按钮视图的按钮标题searchBar.scopeButtonTitles = ["One", "Two", "Three"]// 选中的选择按钮下标值,默认值为 0,如果超出索引范围则会被忽略searchBar.selectedScopeButtonIndex = 1searchBar.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.searchBarsearchBar.showsScopeBar = true// 选择按钮视图的按钮标题searchBar.scopeButtonTitles = ["One", "Two", "Three"]// 选中的选择按钮下标值,默认值为 0,如果超出索引范围则会被忽略searchBar.selectedScopeButtonIndex = 1searchBar.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.searchBarsearchBar.prompt = "非活跃"复制代码

可以在 searchBar 的代理里修改 prompt 的内容,例如:

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 = "点击取消"    }}复制代码

效果如下

非活跃 开始编辑 输入内 取消编辑

可以发现顶部的提示文字和输入框重合了。所以向下调整一下输入框的偏移量。 prompt 为空时 searchBar 的高度为 56,不为空时 searchBar 的高度为 75,所以我们将输入框向下调整 19:

searchBar.searchFieldBackgroundPositionAdjustment = UIOffset.init(horizontal: 0, vertical: 19)复制代码

效果如下

非活跃 开始编辑 输入内 取消编辑

可以发现还是有问题:

  1. 取消按钮和输入框不在一行上了
  2. 如果 prompt 有时有值,有时为空,searchBar 的高度无法灵活改变。

这些问题暂时没有找到解决方案。

其他待解决问题
  1. isTranslucent 没有发现效果
  2. inputAssistantItem
  3. inputAccessoryView
  4. 搜索结果列表图标在什么条件下会显示

转载地址:http://nyyaa.baihongyu.com/

你可能感兴趣的文章
Android开发之蓝牙 --修改本机蓝牙设备的可见性,并扫描周围可用的蓝牙设备
查看>>
[Head First设计模式]生活中学设计模式——外观模式
查看>>
Repository模式中,Update总是失败及其解析
查看>>
.Net 转战 Android 4.4 日常笔记(2)--HelloWorld入门程序
查看>>
[原创]浅谈测试团队转型,思维模式的转变是关键
查看>>
Redis学习-SortedSet
查看>>
android CoordinatorLayout使用
查看>>
机器学习资料大汇总
查看>>
Python selenium 滚动条 详解
查看>>
poj1035Spell checker
查看>>
微信程序开发
查看>>
如何退出minicom【学习笔记】
查看>>
李开复教你如何给自己的简历打分
查看>>
C++内存布局之虚拟继承
查看>>
Sqlserver 数据库基本查询
查看>>
图书馆维护系统总结
查看>>
[hadoop源码阅读][5]-counter的使用和默认counter的含义
查看>>
SAP HUM 如何对一个HU做上架?
查看>>
LINUX系统中动态链接库的创建与使用{补充}
查看>>
三维视觉国际会议首度在中国举办
查看>>