UISearchController样式设置

以下内容是在 Swift 4.0,iOS 11 下的运行结果

如果传入的searchresultscontroller为nil,则表示搜索的结果在当前控制器中显示,现在我让它在searchresultvc中显示

默认样式

初始化一个 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

}

用例:

letsearchBar = searchController.searchBar

searchBar.searchBarStyle = .default


2. tintColor

风格颜色,可用于修改:

输入框的光标颜色

取消按钮字体颜色

选择栏被选中时的颜色

letsearchBar = searchController.searchBar

searchBar.tintColor = .red

3. barTintColor

搜索框背景颜色

letsearchBar = searchController.searchBar

searchBar.barTintColor = .orange

4. backgroundImage

搜索框背景图片

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

letsearchBar = searchController.searchBar

searchBar.backgroundImage = self.createImage(UIColor.red, size: CGSize.init(width: 200, height: 100))



5. 设置(获取)搜索框背景图片

可以通过以下方式设置(获取)搜索框背景图片:

// 设置

// Use UIBarMetricsDefaultPrompt toseta separate backgroundImagefora search bar with a prompt

funcsetBackgroundImage(_ backgroundImage: UIImage?,forbarPosition: UIBarPosition, barMetrics: UIBarMetrics)

// 获取

open func backgroundImage(forbarPosition: 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.

}

用例:

letsearchBar = searchController.searchBar

searchBar.setBackgroundImage(createImage(.blue, size: CGSize.init(width: 20, height: 20)),for: .any, barMetrics: .default)



6. 文本框的背景图片

open funcsetSearchFieldBackgroundImage(_ backgroundImage: UIImage?,forstate: UIControlState)

open func searchFieldBackgroundImage(forstate: UIControlState) -> UIImage?

letsearchBar = 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`

caseblack

}

用例:

letsearchBar = searchController.searchBar

searchBar.barStyle = .black

8. showsBookmarkButton

是否显示搜索框右侧的图书按钮

open var showsBookmarkButton: Bool // default is NO

9. showsCancelButton

是否显示搜索框右侧的取消按钮

open var showsCancelButton: Bool // default is NO

10. showsSearchResultsButton

是否显示搜索框右侧的搜索结果按钮

open var showsSearchResultsButton: Bool // default is NO

11. isSearchResultsButtonSelected

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

open var isSearchResultsButtonSelected: Bool // default is NO

用例:

letsearchBar = searchController.searchBar

searchBar.showsSearchResultsButton =true

searchBar.isSearchResultsButtonSelected =true

12. searchFieldBackgroundPositionAdjustment

设置输入框背景偏移量:

open var searchFieldBackgroundPositionAdjustment: UIOffset

用例:

letsearchBar = searchController.searchBar

searchBar.searchFieldBackgroundPositionAdjustment = UIOffset.init(horizontal: 16, vertical: 16)

13. searchTextPositionAdjustment

设置输入框文本偏移量:

open var searchTextPositionAdjustment: UIOffset

用例:

letsearchBar = searchController.searchBar

searchBar.searchTextPositionAdjustment = UIOffset.init(horizontal: 16, vertical: 16)

14. 设置(获取)搜索框的图标

可以设置(获取)的搜索框图标包括:

搜索图标

清除输入的文字的图标

图书图标

搜索结果列表图标

open funcsetImage(_ iconImage: UIImage?,foricon: UISearchBarIcon, state: UIControlState)

open func image(foricon: UISearchBarIcon, state: UIControlState) -> UIImage?

letsearchBar = searchController.searchBar

searchBar.showsBookmarkButton =true

letsearchImage = self.createImage(.red, size: CGSize.init(width: 20, height: 20))

letclearImage = self.createImage(.yellow, size: CGSize.init(width: 20, height: 20))

letbookmarkImage = self.createImage(.blue, size: CGSize.init(width: 20, height: 20))

letresultsListImage = 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 funcsetPositionAdjustment(_ adjustment: UIOffset,foricon: UISearchBarIcon)

open func positionAdjustment(foricon: UISearchBarIcon) -> UIOffset

用例:

letsearchBar = searchController.searchBar

searchBar.setPositionAdjustment(UIOffset.init(horizontal: 10, vertical: 10),for: .search)

16. 显示(隐藏)取消按钮

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

open funcsetShowsCancelButton(_ showsCancelButton: Bool, animated: Bool)

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

extension ViewController: UISearchControllerDelegate {

    func didPresentSearchController(_ searchController: UISearchController) {

searchController.searchBar.setShowsCancelButton(false, animated:false)

    }

}

效果如下:

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

// 自定义 UISearchBar

class CustomSearchBar: UISearchBar {

override funclayoutSubviews() {

        super.layoutSubviews()

setShowsCancelButton(false, animated:false)

    }

}

// 自定义 UISearchController

class CustomSearchController: UISearchController {

lazy var _searchBar: CustomSearchBar = { [unowned self]in

letresult = CustomSearchBar(frame: CGRect.zero)

        result.delegate = self

returnresult

    }()


    override var searchBar: UISearchBar {

return_searchBar

    }

}

extension CustomSearchController: UISearchBarDelegate {


}

使用自定义的 CustomSearchController 可以完全隐藏取消按钮,效果如下:

17. 设置取消按钮的名称

可以通过以下几个方法修改取消按钮的名称:

方法一:(已失效)

letsearchBar = searchController.searchBar

searchBar.setValue("Done",forKey:"_cancelButtonText")

方法二:

UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title ="Done"

方法三:

letsearchBar = searchController.searchBar

searchBar.showsCancelButton =true

letcancelButton = searchBar.value(forKey:"cancelButton") as? UIButton

cancelButton?.setTitle("Done",for: .normal)

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

18. 搜索框附属分栏条

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

letsearchBar = searchController.searchBar

searchBar.showsScopeBar =true

// 选择按钮视图的按钮标题

searchBar.scopeButtonTitles = ["One","Two","Three"]

// 选中的选择按钮下标值,默认值为 0,如果超出索引范围则会被忽略

searchBar.selectedScopeButtonIndex = 1

19. 搜索框附属分栏条——背景颜色

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

open var scopeBarBackgroundImage: UIImage?

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

letsearchBar = 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 funcsetScopeBarButtonBackgroundImage(_ backgroundImage: UIImage?,forstate: UIControlState)

open func scopeBarButtonBackgroundImage(forstate: UIControlState) -> UIImage?

用例:

letsearchBar = 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 funcsetScopeBarButtonDividerImage(_ dividerImage: UIImage?,forLeftSegmentState leftState: UIControlState, rightSegmentState rightState: UIControlState)

open func scopeBarButtonDividerImage(forLeftSegmentState leftState: UIControlState, rightSegmentState rightState: UIControlState) -> UIImage?

用例:

letsearchBar = 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 funcsetScopeBarButtonTitleTextAttributes(_ attributes: [String : Any]?,forstate: UIControlState)

open func scopeBarButtonTitleTextAttributes(forstate: UIControlState) -> [String : Any]?

用例:

letsearchBar = 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 设置提示信息。

比如:

letsearchBar = searchController.searchBar

searchBar.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)

可以发现还是有问题:

取消按钮和输入框不在一行上了

如果 prompt 有时有值,有时为空,searchBar 的高度无法灵活改变。

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

其他待解决问题

isTranslucent 没有发现效果

inputAssistantItem

inputAccessoryView

搜索结果列表图标在什么条件下会显示

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容