UISearchBar详解

今天公司的项目测试的差不多了,基本可以上架了,又有时间来分享一下最近遇到的一些问题了,公司的项目进行了大改版(应该是全改了,基本是一个新的项目了),老大决定用swift重写。之前一直在自学swift,终于这一次可以实战了。项目中搜索用的比较多,但是搜索框的样式与默认的差别太大了,所以只能自定义了。

<p>The UISearchBar class implements a text field control for text-based searches. The control provides a text field for entering text, a search button, a bookmark button, and a cancel button. The UISearchBar object does not actually perform any searches. You use a delegate, an object conforming to the UISearchBarDelegate protocol, to implement the actions when text is entered and buttons are clicked.<p>

以上是苹果对UISearchBar的解释,可以看见UISearchBar提供了类似UITextField的输入(其实它的组成中就有UITextField,下面会讲到),右边有搜索按钮、标签按钮、关闭按钮可供选择,搜索都是在协议UISearchBarDelegate中进行。

1.自定义外观


默认搜索外观
项目搜索外观

UISearchBar的层级很是复杂主要由UISearchBarBackgroud、UISearchBarTextField、UINavigationButton组成,其中UISearchBarTextField就是输入框,主要是由——UISearchBarSearchFieldBackgroundView、UIButton(❌)、UIImageView(🔍)等组成,获取TextField方法:

let searchFiled:UITextField = self.searchBar.value(forKey: "_searchField") as! UITextField

这样就可以通过修改 searchFiled来修改输入样式(圆角、字体等)。

UISearchBar的直接子控件是UIVIew,其上的子控件UISearchBarBackgroud的frame与UISearchBar的bounds相等,UISearchBarTextField的高度默认为28与UISearchBar左右有8像素的固定间距,上下间距为直接子控件UIView的高度 - UISearchBarTextField的默认高度28 再除以2。因此UISearchBar的输入框始终与设置的frame不一样,不便于布局,我们可以添加一个子类继承UISearchBar,可以更改其内边距。

class MySearchBar: UISearchBar {
    
    // 监听是否添加了该属性
    var contentInset: UIEdgeInsets? {
        didSet {
            self.layoutSubviews()
        }
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        // 便利寻找
        for view in self.subviews {
            for subview in view.subviews {
                // 判定是否是UISearchBarTextField
                if subview.isKind(of: UITextField.classForCoder()) {
                    if let textFieldContentInset = 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 {
                        // 设置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)
                    }
                }
            }
        }
    }

}

让实例化的UISearchBar继承MySearchBar,然后就可以很方便的直接控制内边距了

self.searchBar.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

接下来就是处理placeholder靠左,这个就比较麻烦了,查询了一大堆办法都挺麻烦的,最后找到了一个很投机的办法:先判定手机宽度,然后在placeholder右边加上空格做成靠左的假象。

 if SCREEN.WIDTH == 320 {
            self.searchBar.placeholder = "搜索位置       "
        }else if SCREEN.WIDTH == 373\5 {
            self.searchBar.placeholder = "搜索位置                  "
        }else if SCREEN.WIDTH == 414 {
            self.searchBar.placeholder = "搜索位置                                 "
        }

然后在storyboard中设置searchBar的BarStyle为Minimal就可以很方便的控制UISearchBar的外观了。
到这里就剩一个问题了:UISearchBar上下的两根黑线了,去除方法:

self.searchBar.setBackgroundImage(UIImage.init(), for: .any, barMetrics: .default)

2.搜索的使用
如苹果官方文档所说,与搜索相关的都是在其代理方法中完成。UISearchBar有很多的代理方法,感兴趣的可以点击进入查看UISearchBarDelegate我就介绍几个常用的:

当搜索内容变化时,执行该方法,可以实时监听输入框的变化,可以实现时实搜索。

- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)textNS_AVAILABLE_IOS(3_0);                 // called before text changes

也行你想把搜索事件放在点击搜索以后再触发,那就选用这个方法,它就是点击搜索后的代理方法

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar;

3.结束

当然如果你觉得这样太麻烦了,你还可以选择用UITextField来实现UISearchBar的功能,但是最终哪一个更加的麻烦还需要试一试才知道。

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

推荐阅读更多精彩内容