UISearchBar类介绍与使用和UISearchController的使用

系统自带的搜索栏是继承于UIView的,封装TextField等UIView,但是这些控件并不能对外可见。

一、属性和构造器 

    public init(frame: CGRect)
    public init?(coder aDecoder: NSCoder)

    基本属性
    open var barStyle: UIBarStyle // default is UIBarStyleDefault (blue),其他值白色,黑色,黑色半透明

    weak open var delegate: UISearchBarDelegate? // weak reference. default is nil

    open var text: String? // current/starting search text

    open var prompt: String? // 附加字符串default is nil

    open var placeholder: String? //占位字符(灰色) default is nil

    open var showsBookmarkButton: Bool // default is NO

    open var showsCancelButton: Bool // 是否添加取消按钮default is NO

    @available(iOS 3.2, *)
    open var showsSearchResultsButton: Bool // default is NO

    @available(iOS 3.2, *)
    open var isSearchResultsButtonSelected: Bool // 是否显示选中按钮default is NO
    open var inputAssistantItem: UITextInputAssistantItem { get }
    open var tintColor: UIColor!                 //设置tint颜色

    open var barTintColor: UIColor?              // default is nil
    open var searchBarStyle: UISearchBarStyle    //搜索栏样式,有三个值,默认(输入框外侧灰暗)、输入框内侧灰暗

其他属性

    open var isTranslucent: Bool // 默认值为false 设置半透明,如果barstyle设置为半透明,则为半透明

    open var scopeButtonTitles: [String]? // 分割栏标题数组,如果设置就会有一个分割栏在搜索栏下面
    open var selectedScopeButtonIndex: Int // 显示选中分割栏的下标,不设置默认为0

    open var showsScopeBar: Bool // default is NO. if YES, shows the scope bar. call sizeToFit: 该方法可以更新设置frame
  
 
    open var inputAccessoryView: UIView? //输入框的遮掩视图【即在选中输入框时,除了输入框之外的空间,为它设置视图,如电话本的选中搜索栏后,其他区域的半透明黑色视图】
    open var backgroundImage: UIImage?   //背景图
    open var scopeBarBackgroundImage: UIImage?  //分隔栏的背景图

 

常用方法

下面就是一些方法

 

   //设置和获取背景图(一般为搜索框外部的)
open func setBackgroundImage(_ backgroundImage: UIImage?, for barPosition: UIBarPosition, barMetrics: UIBarMetrics) // Use UIBarMetricsDefaultPrompt to set a separate backgroundImage for a search bar with a prompt

   
    open func backgroundImage(for barPosition: UIBarPosition, barMetrics: UIBarMetrics) -> UIImage?

    
    //设置和获取搜索框内部的背景图(含控制状态)
    open func setSearchFieldBackgroundImage(_ backgroundImage: UIImage?, for state: UIControlState)
    open func searchFieldBackgroundImage(for state: UIControlState) -> UIImage?

    //设置某个icon,某种控制状态的图片
    open func setImage(_ iconImage: UIImage?, for icon: UISearchBarIcon, state: UIControlState)
    open func image(for icon: UISearchBarIcon, state: UIControlState) -> UIImage?

    
 
    open func setScopeBarButtonBackgroundImage(_ backgroundImage: UIImage?, for state: UIControlState)
    open func scopeBarButtonBackgroundImage(for state: UIControlState) -> UIImage?
    //设置和获取分割栏按钮的某种状态的背景图
    open func setScopeBarButtonDividerImage(_ dividerImage: UIImage?, forLeftSegmentState leftState: UIControlState, rightSegmentState rightState: UIControlState)
    open func scopeBarButtonDividerImage(forLeftSegmentState leftState: UIControlState, rightSegmentState rightState: UIControlState) -> UIImage?
     //设置和获取分割栏字体状态属性
 open func setScopeBarButtonTitleTextAttributes(_ attributes: [String : Any]?, for state: UIControlState)
    open func scopeBarButtonTitleTextAttributes(for state: UIControlState) -> [String : Any]?

 

    //设置文本框背景的偏移量
     open var searchFieldBackgroundPositionAdjustment: UIOffset
    // 设置文本框中文本的便宜量
    open var searchTextPositionAdjustment: UIOffset

   //设置和获取icon图标的偏移量
    open func setPositionAdjustment(_ adjustment: UIOffset, for icon: UISearchBarIcon)
    open func positionAdjustment(for icon: UISearchBarIcon) -> UIOffset

修改搜索框TextField的属性

通过搜索栏并没有TextField的属性开发,可以通过kvc 获取到TextField,示例代码

if  let textField = self.value(forKey: "searchField") as? UITextField {
           // 设置textField 的各项属性,比如背景色。圆角等
        }

扩展:UITextInputTaits协议

由于搜索栏遵循了UITextInputTraits(文本输入类都遵循了)
还可以设置协议属性控制,以下属性都是可选实现的。

 

    //
    autocapitalizationType: UITextAutocapitalizationType { get set } // default is UITextAutocapitalizationTypeSentences
//自动检查类型 (值有:不检查,检查所有字符、检查单词、检查句子) (值有:不检查,检查所有字符、检查单词、检查句子)
    autocorrectionType: UITextAutocorrectionType { get set } // default is UITextAutocorrectionTypeDefault

//拼写检查          
    spellCheckingType: UITextSpellCheckingType { get set } // default is UITextSpellCheckingTypeDefault;
//键盘类型
    keyboardType: UIKeyboardType { get set } // default is UIKeyboardTypeDefault
//
    keyboardAppearance: UIKeyboardAppearance { get set } // default is UIKeyboardAppearanceDefault
//返回键类型(字面值不一样)
    returnKeyType: UIReturnKeyType { get set } // default is UIReturnKeyDefault (See note under UIReturnKeyType enum)
//自动返回值
    enablesReturnKeyAutomatically: Bool { get set } // default is NO (when YES, will automatically disable return key when text widget has zero-length contents, and will automatically enable when text widget has non-zero-length contents)
//安全输入(将输入变为*)如输入密码时
    isSecureTextEntry: Bool { get set } // default is NO

//文本内容类型   
    // The textContentType property is to provide the keyboard with extra information about the semantic intent of the text document.
    textContentType: UITextContentType! { get set } // default is nil

 

UISearchBarDelegate

 

该代理主要处理搜索栏的第一响应器、文本改变处理、文本编辑处理;几个按钮事件回掉和scoped时间回掉。

常用方法如下

    
    optional public func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool // 如果像让搜索栏不成为第一响应器,可以返回NO值

    //文本编辑时调用
    optional public func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) // called when text starts editing

    //返回NO注销搜索栏的第一响应
    optional public func searchBarShouldEndEditing(_ searchBar: UISearchBar) -> Bool // return NO to not resign first responder

    //结束编辑时调用
    optional public func searchBarTextDidEndEditing(_ searchBar: UISearchBar) // called when text ends editing

    //文本改变时调用
    optional public func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) // called when text changes (including clear)

    //文本改变之前调用
    optional public func searchBar(_ searchBar: UISearchBar, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool // called before text changes

    
    //点击键盘搜索时调用,处理搜索过滤。
    optional public func searchBarSearchButtonClicked(_ searchBar: UISearchBar) // called when keyboard search button pressed

    //书签点击回掉
    optional public func searchBarBookmarkButtonClicked(_ searchBar: UISearchBar) // called when bookmark button pressed

    //取消按钮点击调用
    optional public func searchBarCancelButtonClicked(_ searchBar: UISearchBar) // called when cancel button pressed

    //结果列表按钮点击回掉
    optional public func searchBarResultsListButtonClicked(_ searchBar: UISearchBar) // called when search results button pressed

    //当分割栏点击改变时调用。
    optional public func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int)

UISearchBar的使用

这个控件的功能不是那么复杂,总体实现比较简单,大部分属性都可以使用IB的可视化设置。

搜索栏添加导航栏

目前只通过代码方式(为导航栏的视图添加子视图方案)实现,无法直接实现通过拖控件的方法实现(即时实现也有视图被剪切,不知道是不是某些设置问题)。

代码如下:

 

        var searchBar = UISearchBar(frame: CGRect(x:0 , y: 20, width: UIScreen.main.bounds.width, height: (self.navigationController?.navigationBar.bounds.height)!))                          //y值设置20,否则导航栏将有可能在状体栏底层。
        searchBar.delegate = self                            //注意实现代理,也可以进行其他配置
        self.navigationController?.view.addSubview(searchBar)//是在它的view下添加子view


运行结果图:

 

UISearchBar类介绍与使用和UISearchController的使用_第1张图片

设置导航栏全透明

在设置之前,你需要明白,我们看到的导航栏其实是导航栏(UINavigationBar)的背景图片,而不是背景色,所以设置背景色是无法实现透明的。

可以设置全透明的图片作为背景图和shadowImage(下面的那根线).

一个更简单的方法,直接创建两掌无内容的图片实例放在那里。

代码如下:

 

        self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
        self.navigationController?.navigationBar.shadowImage = UIImage()    //这个也要设置,否则有一条白线。

 

 

 

 

 

UISearchController的使用(搜索栏结合表格常用案例)

首先得知道UiSearchController不是一个容器控制类,而是相当于搜索栏工具类。

UISearchController是UISearchBar+DisplayViewController的替代品,是iOS8之后的接口类

 

实现实时搜索表格显示

这里需要学习一下面向协议编程,当有多个代理协议时
官方文档

代码如下:

 

import UIKit

class TextViewController: UIViewController {

    var searchController:UISearchController!
    var tableView:UITableView!
    //偷的航哥的数据
    var rawDatasour = ["清华大学","北京大学","中国人民大学","北京交通大学","北京工业大学",
                       "北京航空航天大学","北京理工大学","北京科技大学","中国政法大学",
                       "中央财经大学","华北电力大学","北京体育大学","上海外国语大学","复旦大学",
                       "华东师范大学","上海大学","河北工业大学"]
    //过滤数组
    var filterArray = [String](){
        didSet{
           tableView.reloadData() //很巧妙
        }
    }
    
    var cell:UITableViewCell!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        initTableView()
        initSearchController()
        self.view.addSubview(tableView)
        //【特别重要】搜索栏放tableView的HeaderView上 
        tableView.tableHeaderView = searchController.searchBar
        //self.view.addSubview(searchController.searchBar)
        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    
    //MARK:自定义方法
    //配置tableView
    func initTableView() -> Void {
        var tableViewFrame = CGRect(x: 0, y: 20, width: self.view.bounds.width, height: self.view.bounds.height-20)
        tableView = UITableView(frame:tableViewFrame , style: .plain)
        tableView.delegate = self
        tableView.dataSource = self
        
    }
    
    //提示一下:SearchController,内部默认实现的将导航栏影藏,放搜索栏,可以设置 
    func initSearchController() -> Void {
        searchController = UISearchController(searchResultsController: nil)
        searchController.delegate = self
        searchController.searchResultsUpdater = self
        
        searchController.searchBar.searchBarStyle = .minimal
        searchController.searchBar.showsCancelButton = false
        searchController.searchBar.delegate = self
    }
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}
   //通过表格实现数据的显示。
//MARK:--UITableViewDelegate,UITableViewDataSource
extension TextViewController:UITableViewDelegate,UITableViewDataSource{
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if searchController.isActive {//记得需要同步更改行数,然会数据展示出错
            return filterArray.count
        }else{
            return rawDatasour.count
        }
        
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        cell = UITableViewCell(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.tableView.rowHeight))
        //注意这里的数据源根据searchController的active(选中、编辑、点击搜索,直到取消)切换
        if searchController.isActive { //搜索状态
            cell.textLabel?.text = filterArray[indexPath.row]
            
        }else{
            cell.textLabel?.text = rawDatasour[indexPath.row]
        }
        
        return cell
    }

}

     //代理的实现
//MARK:UISearchBarDelegate
extension TextViewController:UISearchResultsUpdating,UISearchBarDelegate,UISearchControllerDelegate{
    //实时响应,当成为第一响应的时候,或者文本改变的时候调用。
    //当样本数据量很大的时候不建议使用
    func updateSearchResults(for searchController: UISearchController) {
        filterArray = rawDatasour.filter({ (str) -> Bool in
            return str.contains((searchController.searchBar.text!))
            
        })
    }
    
    //点击按钮之后再调用,适合大量数据显示的时候
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        
            filterArray = rawDatasour.filter({ (str) -> Bool in
                return str.contains((searchController.searchBar.text!))
                
            })
    }
    
    //TODO:怎么将按钮设置为中文,或者自定义样式(难道要使用runtime?)
    func willPresentSearchController(_ searchController: UISearchController) {
        
    }
}

运行结果图:

UISearchBar类介绍与使用和UISearchController的使用_第2张图片

 

搜索结果:

UISearchBar类介绍与使用和UISearchController的使用_第3张图片

 

 

你可能感兴趣的:(iOS,移动开发,#,Swift,语言基础,#,UI控件)