欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

iOS定制UISearchBar導(dǎo)航欄同步iOS11的方法

 更新時(shí)間:2017年12月18日 09:08:43   作者:HasjOH  
本篇文章主要介紹了iOS定制UISearchBar導(dǎo)航欄同步iOS11的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

系統(tǒng)原生的UISearchBar在iOS 11經(jīng)歷了一次變革,高度由原來(lái)的44變成了56 (使用默認(rèn)高度的估計(jì)都被坑了),樣式也發(fā)生了些微的變化,比如在未輸入狀態(tài)下圓角變化,放大鏡圖標(biāo)和文本的文字不再居中而是靠左了。具體看圖

一些主流App也常見(jiàn)在導(dǎo)航欄嵌入searchBar,以網(wǎng)易云音樂(lè)和知乎為例,左邊是主頁(yè),右邊是搜索頁(yè)面 (注意光標(biāo))。

實(shí)現(xiàn)思路與案例

核心思想是設(shè)置導(dǎo)航欄的titleView和左右的barButtonItem。主要有3種方式

  1.  首頁(yè)導(dǎo)航欄的titleView使用button來(lái)實(shí)現(xiàn),搜索頁(yè)面使用searchBar。
  2. 首頁(yè)和搜索頁(yè)面導(dǎo)航欄的titleView都是用searchBar,searchBar的樣式針對(duì)兩個(gè)頁(yè)面做不同的修改。這種方式可以重用我們定制的searchBar,減少冗余。
  3. 首頁(yè)導(dǎo)航欄titleView使用button來(lái)實(shí)現(xiàn),搜索頁(yè)面的使用textField。這種方式更徹底,更靈活,相對(duì)也更復(fù)雜一些。

為什么上面的titleView說(shuō)是button不是其他的?其他的當(dāng)然也可以實(shí)現(xiàn)。button自帶imageView和titleLabel,只需要設(shè)置偏移量更容易達(dá)到我們想要的,而且視圖層級(jí)更少,在流暢性方面更有保證些。

案例

網(wǎng)易云音樂(lè)首頁(yè)和搜索頁(yè)面的導(dǎo)航欄視圖層級(jí),titleView都使用MCSearchBar來(lái)實(shí)現(xiàn),并且設(shè)置了導(dǎo)航欄左右兩邊的按鈕 。這類(lèi)似上文所說(shuō)的第二種思路。

 

圖中可以清楚看到知乎首頁(yè)導(dǎo)航欄由2個(gè)button組成,搜索頁(yè)面使用了textField,這類(lèi)似上文提到的第三種思路。

實(shí)戰(zhàn)

通過(guò)自定義SearchBar實(shí)現(xiàn)一個(gè)如下樣式的導(dǎo)航欄

先自定義一個(gè)UISearchBar的初始化方法,觀察一下首頁(yè)和搜索頁(yè)的異同,像searchField的大小背景色是一致的,可以這部分可以直接給定,而placeholder是不一樣的,所以應(yīng)該在調(diào)用的時(shí)候提供。以此類(lèi)推,新建一個(gè)OHSearchBar類(lèi),一個(gè)初始化方法

- (instancetype)initWithFrame:(CGRect)frame placeholder:(NSString *)placeholder textFieldLeftView:(UIImageView *)leftView showCancelButton:(BOOL)showCancelButton tintColor:(UIColor *)tintColor { 
 if (self = [super initWithFrame:frame]) {
  self.frame = frame;
  self.tintColor = tintColor; //光標(biāo)顏色
  self.barTintColor = [UIColor whiteColor];
  self.placeholder = placeholder;
  self.showsCancelButton = showCancelButton;
  self.leftView = leftView; // 用來(lái)代替左邊的放大鏡
  [self setImage:[UIImage imageNamed:@"clear"] forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal]; // 替換輸入過(guò)程中右側(cè)的clearIcon
 }
 return self;
}

新建一個(gè)首頁(yè)OHHomeViewController,設(shè)置導(dǎo)航欄的titleView和rightBarButton

// navigation buttom
 UIButton *messageButton = [UIButton buttonWithType:UIButtonTypeSystem];
 [messageButton setImage:[UIImage imageNamed:@"msg"] forState:UIControlStateNormal];
 messageButton.bounds = CGRectMake(0, 0, 30, 30);
 UIBarButtonItem *messageBarButton = [[UIBarButtonItem alloc] initWithCustomView:messageButton];
 self.navigationItem.rightBarButtonItem = messageBarButton;
 
 // search bar
 UIImageView *leftView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"scan"]];
 leftView.bounds = CGRectMake(0, 0, 24, 24);
 self.ohSearchBar = [[OHSearchBar alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 44)
            placeholder:@"點(diǎn)擊我跳轉(zhuǎn)"
          textFieldLeftView:leftView
           showCancelButton:NO
            tintColor:[UIColor clearColor]];
 self.navigationItem.titleView = self.ohSearchBar;

讓我們來(lái)看下效果,左邊為iOS 9,右邊iOS 11

這時(shí)候可以看到幾處差異

  1. searchBar的高度
  2. searchBar的textField的放大鏡和文字位置
  3. textField的圓角不一致
  4. 更細(xì)心的還會(huì)發(fā)現(xiàn),textField的位置不一致

解決方法: 第一和第二個(gè)問(wèn)題,判斷設(shè)備是否是iOS 11,若是則設(shè)置其高度,不是則讓其placeholder居左。關(guān)鍵代碼如下

if ([[UIDevice currentDevice] systemVersion].doubleValue >= 11.0) {
  [[self.heightAnchor constraintEqualToConstant:44.0] setActive:YES];
 } else {
  [self setLeftPlaceholder];
 }
- (void)setLeftPlaceholder {
 SEL centerSelector = NSSelectorFromString([NSString stringWithFormat:@"%@%@", @"setCenter", @"Placeholder:"]);
 if ([self respondsToSelector:centerSelector]) {
  BOOL centeredPlaceholder = NO;
  NSMethodSignature *signature = [[UISearchBar class] instanceMethodSignatureForSelector:centerSelector];
  NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
  [invocation setTarget:self];
  [invocation setSelector:centerSelector];
  [invocation setArgument:&centeredPlaceholder atIndex:2];
  [invocation invoke];
 }
}

對(duì)于第三和第四個(gè)問(wèn)題,用KVC獲取textField,并對(duì)其進(jìn)行定制。令textField位置、大小、圓角一致。

- (void)layoutSubviews{
 [super layoutSubviews];
 // search field
 UITextField *searchField = [self valueForKey:@"searchField"];
 searchField.backgroundColor = DARK_BLUE_COLOR;
 searchField.textColor = [UIColor whiteColor];
 searchField.font = [UIFont systemFontOfSize:16];
 searchField.leftView = self.leftView;
 searchField.frame = CGRectMake(0, 8, SCREEN_WIDTH, 28);
 searchField.layer.cornerRadius = 5;
 searchField.layer.masksToBounds = YES;
 [searchField setValue:[UIColor whiteColor] forKeyPath:@"placeholderLabel.textColor"];
 [self setValue:searchField forKey:@"searchField"]; 
 self.searchTextPositionAdjustment = (UIOffset){10, 0}; // 光標(biāo)偏移量
}

同樣的,先看下運(yùn)行效果

原本以為這下是沒(méi)什么問(wèn)題的,結(jié)果簡(jiǎn)直是坑

textFild的長(zhǎng)度、位置、圓角都不一樣 解釋下這里出現(xiàn)的問(wèn)題

觀察上方圖片上方的searchBar,會(huì)發(fā)現(xiàn)textField左邊是圓角,右邊是直角,說(shuō)明是被截取的。導(dǎo)航欄titleView的范圍就劃分到了那個(gè)部分,而下邊的searchBar連rightBarButton都不放過(guò),直接搶占了位置。推測(cè)這是由于iOS 11導(dǎo)航欄視圖層級(jí)變化產(chǎn)生的,可以這里了解下 www.jianshu.com/p/352f101d6… ,或者自行科普,不詳細(xì)展開(kāi)。所以對(duì)于searchBar的size設(shè)置要小心了,盡量控制在合適的范圍。

textField的圓角是不一致的,自定義圓角大小時(shí),取消其本身的圓角樣式

searchField.borderStyle = UITextBorderStyleNone;

查看視圖層級(jí)會(huì)發(fā)現(xiàn),iOS 11以下,設(shè)置titleView,x的默認(rèn)坐標(biāo)居然是12,而iOS 11是0。所以設(shè)置textField的x坐標(biāo)的話,在iOS 11下必須多出12才會(huì)是一致的位置。

 

修改代碼上面的代碼

- (void)layoutSubviews{
 [super layoutSubviews];
 // search field
 UITextField *searchField = [self valueForKey:@"searchField"];
 searchField.backgroundColor = DARK_BLUE_COLOR;
 searchField.textColor = [UIColor whiteColor];
 searchField.font = [UIFont systemFontOfSize:16];
 searchField.leftView = self.leftView;
 if (@available(iOS 11.0, *)) {
  // 查看視圖層級(jí),在iOS 11之前searchbar的x是12
  searchField.frame = CGRectMake(12, 8, SCREEN_WIDTH*0.8, 28);

 } else {
  searchField.frame = CGRectMake(0, 8, SCREEN_WIDTH*0.8, 28);
 }
 searchField.borderStyle = UITextBorderStyleNone;
 searchField.layer.cornerRadius = 5;
 searchField.layer.masksToBounds = YES;
 [searchField setValue:[UIColor whiteColor] forKeyPath:@"placeholderLabel.textColor"];
 [self setValue:searchField forKey:@"searchField"];
  self.searchTextPositionAdjustment = (UIOffset){10, 0}; // 光標(biāo)偏移量
}

這時(shí)候就是我們想要的結(jié)果了。

首頁(yè)暫時(shí)告一段落,接著開(kāi)始我們的搜索頁(yè)面。與首頁(yè)不同的是需要searchBar與searchController配合使用。新建一個(gè)OHSearchController類(lèi) 添加一個(gè)屬性

@property (nonatomic, strong) OHSearchBar *ohSearchBar;

初始化代碼

- (instancetype)initWithSearchResultsController:(UIViewController *)searchResultsController searchBarFrame:(CGRect)searchBarFrame placeholder:(NSString *)placeholder textFieldLeftView:(UIImageView *)leftView showCancelButton:(BOOL)showCancelButton barTintColor:(UIColor *)barTintColor{
 if (self = [super initWithSearchResultsController:searchResultsController]) {
  self.ohSearchBar = [[OHSearchBar alloc] initWithFrame:searchBarFrame
             placeholder:placeholder
           textFieldLeftView:leftView
            showCancelButton:YES
             tintColor:barTintColor];
  
  UIButton *button = [self.ohSearchBar valueForKey:@"cancelButton"];
  button.tintColor = [UIColor whiteColor];
  [button setTitle:@"取消" forState:UIControlStateNormal];
  [self.ohSearchBar setValue:button forKey:@"cancelButton"];
 }
 return self;
}

接著是我們的視圖控制器OHSearchViewController

UIImageView *leftView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"search"]];
 leftView.bounds = CGRectMake(0, 0, 24, 24);
 self.ohSearchController = [[OHSearchController alloc] initWithSearchResultsController:self
                   searchBarFrame:CGRectMake(0, 0, SCREEN_WIDTH, 44)
                    placeholder:@"請(qǐng)輸入搜索內(nèi)容進(jìn)行搜索"
                  textFieldLeftView:leftView
                   showCancelButton:YES
                    barTintColor:BASE_BLUE_COLOR];
 
 [self.ohSearchController.ohSearchBar becomeFirstResponder];
 self.ohSearchController.ohSearchBar.delegate = self;
 [self.ohSearchController.ohSearchBar setLeftPlaceholder];
 self.navigationItem.titleView = self.ohSearchController.ohSearchBar;
 self.navigationItem.hidesBackButton = YES;

完成這一步后到了交互環(huán)節(jié)了,點(diǎn)擊首頁(yè)的searchBar跳轉(zhuǎn)搜索頁(yè)面,點(diǎn)擊搜索頁(yè)面的取消按鈕返回到首頁(yè)。 首頁(yè)設(shè)置searchbar的代理,并完成一下代理方法

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
 OHSearchViewController *ohSearchViewController = [[OHSearchViewController alloc] init];
 [self.navigationController pushViewController:ohSearchViewController animated:NO];
 return YES;
}

搜索頁(yè)設(shè)置searchbar的代理,并完成一下代理方法

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
 [self.navigationController popViewControllerAnimated:NO];
}

- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
 [self.ohSearchController.ohSearchBar resignFirstResponder];
 // 讓取消按鈕一直處于激活狀態(tài)
 UIButton *cancelBtn = [searchBar valueForKey:@"cancelButton"];
 cancelBtn.enabled = YES;
}

這時(shí)候問(wèn)題又出現(xiàn)了,點(diǎn)擊搜索頁(yè)面的取消按鈕,沒(méi)有跳回首頁(yè)而是還在這個(gè)頁(yè)面。但是可以看到屏幕的閃動(dòng)。通過(guò)打印消息發(fā)現(xiàn),點(diǎn)了取消按鈕,執(zhí)行了首頁(yè)的- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar方法。 仔細(xì)推敲之后想明白了原因是沒(méi)有取消第一響應(yīng)者,加上導(dǎo)航欄的交互機(jī)制,pop到上個(gè)頁(yè)面的時(shí)候并不會(huì)進(jìn)行頁(yè)面刷新導(dǎo)致了這個(gè)問(wèn)題。 解決辦法在首頁(yè)要push搜索頁(yè)面的時(shí)候取消第一響應(yīng)者

- (void)viewWillDisappear:(BOOL)animated {
 [self.ohSearchBar resignFirstResponder];
}

到此,便大功告成了??梢钥聪略创a加深理解。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 你應(yīng)該知道的tableViewCell行高計(jì)算處理

    你應(yīng)該知道的tableViewCell行高計(jì)算處理

    這篇文章主要給大家介紹了關(guān)于tableViewCell行高計(jì)算的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • 關(guān)于ios配置微信config出現(xiàn)驗(yàn)簽失敗的問(wèn)題解決

    關(guān)于ios配置微信config出現(xiàn)驗(yàn)簽失敗的問(wèn)題解決

    這篇文章主要介紹了關(guān)于ios配置微信config出現(xiàn)驗(yàn)簽失敗的問(wèn)題解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • iOS正則表達(dá)式驗(yàn)證手機(jī)號(hào)、郵箱、身份證號(hào)等

    iOS正則表達(dá)式驗(yàn)證手機(jī)號(hào)、郵箱、身份證號(hào)等

    這篇文章主要介紹了iOS正則表達(dá)式驗(yàn)證手機(jī)號(hào)、郵箱、身份證號(hào)等信息,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • iOS Swift開(kāi)發(fā)之日歷插件開(kāi)發(fā)示例

    iOS Swift開(kāi)發(fā)之日歷插件開(kāi)發(fā)示例

    本篇文章主要介紹了iOS Swift開(kāi)發(fā)之日歷插件開(kāi)發(fā)示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • iOS中Label實(shí)現(xiàn)顯示不同顏色與字體的方法

    iOS中Label實(shí)現(xiàn)顯示不同顏色與字體的方法

    這篇文章主要給大家介紹了關(guān)于在iOS中Label實(shí)現(xiàn)顯示不同顏色與字體的相關(guān)資料,文中分別介紹了利用range或者文字兩種實(shí)現(xiàn)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-11-11
  • iOS實(shí)現(xiàn)帶文字的圓形頭像效果

    iOS實(shí)現(xiàn)帶文字的圓形頭像效果

    隨著騰訊QQ的普及,現(xiàn)在越來(lái)越多的社交類(lèi)APP在顯示頭像的時(shí)候,都選擇了圓形頭像,本文將更進(jìn)一步的介紹如何實(shí)現(xiàn)帶文字的圓形頭像效果,效果非常不錯(cuò),感興趣的朋友們可以參考借鑒,下面來(lái)一起看看吧。
    2016-10-10
  • iOS開(kāi)發(fā)學(xué)習(xí) ViewController使用示例詳解

    iOS開(kāi)發(fā)學(xué)習(xí) ViewController使用示例詳解

    這篇文章主要為大家介紹了iOS開(kāi)發(fā)學(xué)習(xí) ViewController使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • iOS?Lotusoot模塊化工具應(yīng)用的動(dòng)態(tài)思路

    iOS?Lotusoot模塊化工具應(yīng)用的動(dòng)態(tài)思路

    項(xiàng)目的不斷更迭,導(dǎo)致項(xiàng)目越來(lái)越大,越來(lái)越臃腫,為了讓項(xiàng)目更加條理,需要對(duì)項(xiàng)目進(jìn)行模塊化處理,為了減少模塊之間的耦合,于是就有了Lotusoot這個(gè)工具
    2022-08-08
  • IOS打開(kāi)系統(tǒng)相機(jī)的閃光燈

    IOS打開(kāi)系統(tǒng)相機(jī)的閃光燈

    今天給大家分享一下如何調(diào)用iphone的拍照功能和打開(kāi)閃光燈,有些代碼我也不太理解,很多是在網(wǎng)上借鑒其他人的。
    2015-05-05
  • iOS實(shí)現(xiàn)H5支付(微信、支付寶)原生封裝

    iOS實(shí)現(xiàn)H5支付(微信、支付寶)原生封裝

    這篇文章主要介紹了iOS實(shí)現(xiàn)H5支付(微信、支付寶)原生封裝,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02

最新評(píng)論