[iOS]關(guān)于UISearchBar, 看這個(gè)就夠了

UISearchBar一般我們不單獨(dú)使用他, 在iOS 8之后, 我們更多地是和UISearchController一起使用, 關(guān)于UISearchController的一些使用可參考[iOS]系統(tǒng)UISearchController詳解, 這里主要是關(guān)于UISearchBar的一些設(shè)置, 可以單獨(dú)使用, 也可以對(duì)UISearchController中的searchBar 進(jìn)行設(shè)置.
下面這個(gè)就是UISearchController默認(rèn)的樣子:

默認(rèn)

- barStyle

搜索框樣式

@property(nonatomic)        UIBarStyle              barStyle

下面是修改為黑色

search.searchBar.barStyle = UIBarStyleBlack;
黑色樣式

- delegate

代理, 不用多說(shuō), 大家都很熟悉;

@property(nullable,nonatomic,weak) id<UISearchBarDelegate> delegate;

- text & placeholder

這兩個(gè)屬性, 也很容易

// searchBar的文本內(nèi)容
@property(nullable,nonatomic,copy)   NSString               *text;
// 占位文本
@property(nullable,nonatomic,copy)   NSString               *placeholder;

- prompt

提示信息, 是在搜索框的上面可以設(shè)置一行提示文字

@property(nullable,nonatomic,copy)   NSString     *prompt;  

這里我設(shè)置為:

search.searchBar.prompt = @"這是一個(gè)prompt";

效果如下:

提示信息

這里在設(shè)置這個(gè)屬性的時(shí)候需要注意, 因?yàn)槎嗔艘粋€(gè)提示信息, 所以searchBar的高度變化了, 不再是默認(rèn)的44, 但是在剛剛創(chuàng)建的時(shí)候, 其高度還是 44, 這樣就會(huì)出現(xiàn)下面的情況:

可以看到, 剛進(jìn)去的時(shí)候, 視圖重疊了, 但是激活一次后, 就正常了; 所以, 我們需要處理一下這個(gè)問題, 這里有兩種方法來(lái)解決:

方法一

修改searchBarframe,
我在其代理方法打印了, 各個(gè)情況下的searchBarframe:

searchBarTextDidBeginEditing >>{{0, 0}, {320, 44}}
textDidChange >>{{0, 20}, {320, 75}}
searchBarTextDidEndEditing >>{{0, 20}, {320, 75}}

可以看出, 其高度變?yōu)?strong>75了, 也就是正常顯示的狀態(tài), 所以, 在開始的時(shí)候, 我們調(diào)整一下即可:

    CGRect rect = search.searchBar.frame;
    rect.size.height = 75;
    search.searchBar.frame = rect;

這樣就能, 正常顯示了;

方法二

直接在設(shè)置prompt 后, 調(diào)用一下sizeToFit, 來(lái)更新其 frame, 讓其重新布局子控件去自適應(yīng):

[search.searchBar sizeToFit];

- button

幾個(gè)搜索框的輔助按鈕

// 
@property(nonatomic)        BOOL                    showsBookmarkButton __TVOS_PROHIBITED;   // default is NO
@property(nonatomic)        BOOL                    showsCancelButton __TVOS_PROHIBITED;     // default is NO
@property(nonatomic)        BOOL                    showsSearchResultsButton NS_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED; // default is NO

其點(diǎn)擊事件, 可以從其相應(yīng)的代理方法獲取:

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar;                     // called when keyboard search button pressed
- (void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar __TVOS_PROHIBITED; // called when bookmark button pressed
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar __TVOS_PROHIBITED;   // called when cancel button pressed
- (void)searchBarResultsListButtonClicked:(UISearchBar *)searchBar NS_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED; // called when search results button pressed

- tintColor & barTintColor

// 主要是修改了搜索框上所有子控件的顏色
@property(null_resettable, nonatomic,strong) UIColor *tintColor;
// 設(shè)置bar的前景色(背景色), 不要使用backgroundColor, 表現(xiàn)不出來(lái)
@property(nullable, nonatomic,strong) UIColor *barTintColor NS_AVAILABLE_IOS(7_0)

例如:

search.searchBar.tintColor = [UIColor redColor];
search.searchBar.barTintColor = [UIColor greenColor];

效果:

效果圖

下面設(shè)置一下backgroundColor, 看看效果:

search.searchBar.backgroundColor = [UIColor orangeColor];

可以看出, 背景色被上面的前景色覆蓋了, 所以沒有表現(xiàn)出來(lái).

- ScopeBar

選項(xiàng)卡

// 選項(xiàng)按鈕標(biāo)題(大于等于2個(gè), 才會(huì)顯示)
@property(nullable, nonatomic,copy) NSArray<NSString *>   *scopeButtonTitles  
// 默認(rèn)選中的選項(xiàng)卡
@property(nonatomic)      NSInteger  selectedScopeButtonIndex  
// 是否顯示選項(xiàng)卡(一般不需設(shè)置)
@property(nonatomic)      BOOL       showsScopeBar 

其點(diǎn)擊事件, 在代理方法中獲取:

- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope

這里需要注意, 在設(shè)置了scopeButtonTitles 后, 就不用設(shè)置showsScopeBar 了, 或者將其設(shè)置為NO, 如果為YES, 會(huì)發(fā)生下面的情況:


正常情況應(yīng)該是這樣的:

上面的問題是在剛進(jìn)來(lái)的時(shí)候, 就顯示了選項(xiàng)卡, 而且在激活搜索框的時(shí)候, 選項(xiàng)卡不見了, 而是多出來(lái)一部分空白. 而正常剛進(jìn)來(lái)的時(shí)候是不顯示選項(xiàng)卡的, 搜索框激活時(shí)才顯示, 所以設(shè)置時(shí)不用設(shè)置showsScopeBar;

設(shè)置選項(xiàng)卡的屬性

可以使用下面的方法, 來(lái)設(shè)置選項(xiàng)卡文字的屬性( 字體, 顏色, 大小等):

- (void)setScopeBarButtonTitleTextAttributes:(nullable NSDictionary<NSString *, id> *)attributes forState:(UIControlState)state

常用到的鍵為:

 NSForegroundColorAttributeName // 修改文字顏色
NSFontAttributeName // 修改文字字體及大小

更多鍵名可參考
NSAttributedString.h
設(shè)置背景色

可參考下面 backgroundImage & scopeBarBackgroundImage, 使用純色圖片來(lái)設(shè)置背景圖, 達(dá)到設(shè)置背景色的目的; 也可以使用下面的方法:

 UIView *backView = [[searchBar.subviews firstObject].subviews firstObject];
    
    UISegmentedControl *segmentedController = nil;
    // 找到 UISegmentedControl
    for (UIView *tmp in backView.subviews) {
        
        if ([tmp isKindOfClass:[UISegmentedControl class]]) {
            
            segmentedController = (UISegmentedControl *)tmp;
            break;
        }
    }
    // 如果存在
    if (segmentedController) {
        
        [segmentedController setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor redColor]} forState:UIControlStateNormal];
        [segmentedController setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor blackColor]} forState:UIControlStateSelected];

// 設(shè)置中顏色
        segmentedController.tintColor = [UIColor redColor];
    }

找到這個(gè)UISegmentedControl 后, 就可以使用 UISegmentedControlAPI來(lái)設(shè)置相關(guān)的屬性了;

- inputAccessoryView

為搜索框的鍵盤添加一個(gè)輔助視圖

@property (nullable, nonatomic, readwrite, strong) UIView *inputAccessoryView;

可以這樣使用:

UILabel *label = [[UILabel alloc]init];
    label.text = @"這是一個(gè)inputAccessoryView";
    label.textAlignment = NSTextAlignmentCenter;
    label.textColor = [UIColor blackColor];
    
    label.frame = CGRectMake(0, 0, 0, 30);
    label.backgroundColor = [UIColor redColor];
    search.searchBar.inputAccessoryView = label;

這里的frame 中起作用的是高度, 其他的設(shè)置了沒效果;

以上設(shè)置的, 效果圖如下:

search.searchBar.inputAccessoryView

- backgroundImage & scopeBarBackgroundImage

背景圖和選項(xiàng)卡的背景圖

// 搜索框的背景圖
@property(nullable, nonatomic,strong) UIImage *backgroundImage 
// 選項(xiàng)卡的背景圖
@property(nullable, nonatomic,strong) UIImage *scopeBarBackgroundImage 

還有幾個(gè)設(shè)置相關(guān)背景圖的方法:

// 設(shè)置tabbar背景圖
- (void)setBackgroundImage:(nullable UIImage *)backgroundImage forBarPosition:(UIBarPosition)barPosition barMetrics:(UIBarMetrics)barMetrics
// 設(shè)置搜索文本框背景圖, state的取值只能是: UIControlStateNormal and UIControlStateDisabled
- (void)setSearchFieldBackgroundImage:(nullable UIImage *)backgroundImage forState:(UIControlState)state 

- (void)setScopeBarButtonBackgroundImage:(nullable UIImage *)backgroundImage forState:(UIControlState)state

修改搜索框默認(rèn)圖標(biāo)

這個(gè)方法可以修改搜索框默認(rèn)的一些圖標(biāo),:

- (void)setImage:(nullable UIImage *)iconImage forSearchBarIcon:(UISearchBarIcon)icon state:(UIControlState)state

修改哪個(gè)圖標(biāo), 是用參數(shù)icon 來(lái)指定, 他是一個(gè)枚舉:

typedef NS_ENUM(NSInteger, UISearchBarIcon) {
    UISearchBarIconSearch, // The magnifying glass
    UISearchBarIconClear __TVOS_PROHIBITED, // The circle with an x in it
    UISearchBarIconBookmark __TVOS_PROHIBITED, // The open book icon
    UISearchBarIconResultsList __TVOS_PROHIBITED, // The list lozenge icon
};

如下, 我修改了默認(rèn)的搜索圖標(biāo):

[search.searchBar setImage:[UIImage imageNamed:@"MoreExpressionShops"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];

修改默認(rèn)圖標(biāo)偏移量

修改偏移量可使用下面的方法, 參數(shù)就是你要修改的是哪個(gè)圖標(biāo)(搜索, 刪除等):

- (void)setPositionAdjustment:(UIOffset)adjustment forSearchBarIcon:(UISearchBarIcon)icon 

參數(shù)是一個(gè)枚舉:

typedef NS_ENUM(NSInteger, UISearchBarIcon) {
    UISearchBarIconSearch, // 搜索圖標(biāo)
    UISearchBarIconClear // 刪除圖標(biāo)
    UISearchBarIconBookmark // 閱讀樣式圖標(biāo)
    UISearchBarIconResultsList // 詳細(xì)結(jié)果展示圖標(biāo)
};

- 修改右側(cè)取消按鈕

搜索框右側(cè)的取消按鈕, 默認(rèn)是藍(lán)色的英文cancel, 大多數(shù)情況下我們都要修改這個(gè), 下面我來(lái)介紹三種修改的方法:

方法一 : 找到這個(gè)button來(lái)修改,

由于搜索框剛創(chuàng)建的時(shí)候, 沒有顯示這個(gè)取消按鈕, 所以實(shí)際上, 這個(gè)按鈕不在searchBar 的子視圖中(懶加載), 所以, 我們可以在其代理方法中添加如下代碼:

// 由于其子控件是懶加載模式, 所以找之前先將其顯示
[searchBar setShowsCancelButton:YES animated:YES];
    // 這個(gè)方法來(lái)遍歷其子視圖, 找到cancel按鈕
    for (UIView *subview in searchBar.subviews) {
        
        for (UIView *tempView in subview.subviews) {
            // 找到cancelButton
            if ([tempView isKindOfClass:NSClassFromString(@"UINavigationButton")]) {
                // 在這里轉(zhuǎn)化為UIButton, 設(shè)置其屬性
                UIButton *btn = (UIButton*)tempView;
                [btn setTitle:@"取消" forState:UIControlStateNormal];
            }
        }
    }

效果如下:

這個(gè)方法可以設(shè)置, 按鈕標(biāo)題及其屬性(顏色, 字體等)
注意, 這里設(shè)置文字顏色的時(shí)候, 如果使用按鈕的方式設(shè)置, 會(huì)有一些問題, 第一次激活搜索框的時(shí)候, 他的顏色并沒有改變, 第二次之后才會(huì)改變:

// 這樣首次激活搜索框 ,顏色沒有改變
[btn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
方式二 : 設(shè)置tintColor

使用searchBartintColor來(lái)設(shè)置, 也能改變這個(gè)按鈕的文字顏色, 但是底部的選項(xiàng)卡也會(huì)跟著變色:

search.searchBar.tintColor = [UIColor redColor];

因?yàn)? 這樣雖然改變了按鈕標(biāo)題顏色, 但是其他的控件也受到了影響, 所以, 有時(shí)候也不是我們想要的.

方式三 : 最優(yōu)解決

下面介紹一種, 直接修改按鈕標(biāo)題顏色, 而不影響其他的控件( 例如: 選項(xiàng)卡 ); 在初始化UISearchController的時(shí)候, 添加如下代碼即可:

// 修改按鈕標(biāo)題文字屬性( 顏色, 大小, 字體)
[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTitleTextAttributes:@{NSForegroundColorAttributeName: [UIColor redColor], NSFontAttributeName: [UIFont systemFontOfSize:16]} forState:UIControlStateNormal];
  
 // 修改標(biāo)題文字
 [[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTitle:@"souSuo"];

這樣也能達(dá)到修改按鈕文字及其顏色的效果, 但是不會(huì)影響其他的控件.

設(shè)置光標(biāo)

設(shè)置光標(biāo)偏移量

searchBar 有兩個(gè)UIOffset類型的屬性:

// 搜索框光標(biāo)偏移量
@property(nonatomic) UIOffset searchFieldBackgroundPositionAdjustment 
// 搜索框在searchBar內(nèi)的位置偏移量
@property(nonatomic) UIOffset searchTextPositionAdjustment

例如, 如下設(shè)置后:

search.searchBar.searchTextPositionAdjustment = UIOffsetMake(20, 0);
search.searchBar.searchFieldBackgroundPositionAdjustment = UIOffsetMake(20, 0);

效果是這樣的:

搜索框的偏移量
光標(biāo)偏移
修改光標(biāo)顏色

修改光標(biāo)的顏色可以直接設(shè)置searchBartintColor屬性, 缺點(diǎn)就是會(huì)影響整個(gè)搜索框的前景色.
目前, 還沒有找到特別有效的方法來(lái)單獨(dú)設(shè)置光標(biāo)的顏色, 能想到的就是遍歷其子視圖, 找到輸入框UITextField, 方法類似上面找cancelButton :

UITextField *textField = nil;
    
    for (UIView *tmp in backView.subviews) {
        
        if ([tmp isKindOfClass:NSClassFromString(@"UISearchBarTextField")]) {
            
            textField = (UITextField *)tmp;
            break;
        }
    }
    // 找到這個(gè)textField, 就可以按UITextField類來(lái)設(shè)置了
    if (textField) {
        
        textField.tintColor = [UIColor orangeColor];
    }

這樣就修改為了, 橘黃色:

以上在遍歷子控件, 找自己需要的控件的時(shí)候, 判斷class時(shí)的類型, 我們?cè)趺粗朗鞘裁搭愋偷哪? 這里給出, searchControllersearchBar的視圖層次結(jié)構(gòu):

子視圖層次關(guān)系
可視化視圖

這樣, 我們就可以看到各個(gè)子控件的類型了.

(完)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末钧嘶,一起剝皮案震驚了整個(gè)濱河市蠕嫁,隨后出現(xiàn)的幾起案子脆荷,更是在濱河造成了極大的恐慌,老刑警劉巖慨仿,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異景描,居然都是意外死亡堰乔,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)抡秆,“玉大人奕巍,你說(shuō)我怎么就攤上這事∪迨浚” “怎么了的止?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)着撩。 經(jīng)常有香客問我诅福,道長(zhǎng),這世上最難降的妖魔是什么拖叙? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任氓润,我火速辦了婚禮,結(jié)果婚禮上薯鳍,老公的妹妹穿的比我還像新娘咖气。我一直安慰自己,他們只是感情好辐啄,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布采章。 她就那樣靜靜地躺著,像睡著了一般壶辜。 火紅的嫁衣襯著肌膚如雪悯舟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天砸民,我揣著相機(jī)與錄音抵怎,去河邊找鬼。 笑死岭参,一個(gè)胖子當(dāng)著我的面吹牛反惕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播演侯,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼姿染,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了秒际?” 一聲冷哼從身側(cè)響起悬赏,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎娄徊,沒想到半個(gè)月后闽颇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡寄锐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年兵多,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了尖啡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡剩膘,死狀恐怖衅斩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情援雇,我是刑警寧澤矛渴,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站惫搏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蚕涤。R本人自食惡果不足惜筐赔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望揖铜。 院中可真熱鬧茴丰,春花似錦、人聲如沸天吓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)龄寞。三九已至汰规,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間物邑,已是汗流浹背溜哮。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留色解,地道東北人茂嗓。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像科阎,于是被迫代替她去往敵國(guó)和親述吸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)锣笨、插件蝌矛、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,022評(píng)論 4 62
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 6,358評(píng)論 0 17
  • import "AppDelegate.h" // 宏定義顏色 define COLORRGB(r,g,b,a) ...
    ThEAll閱讀 355評(píng)論 0 0
  • 不知你是否會(huì)有這種感覺 白天各種正能量票唆,夜幕來(lái)臨回到家不開燈朴读,葛優(yōu)癱在沙發(fā)上,感覺好累走趋,懷疑現(xiàn)在的生活與選擇衅金。感覺...
    L_Yao閱讀 309評(píng)論 0 1