亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

iOS定制UISearchBar導航欄同步iOS11的方法

2020-07-26 02:35:08
字體:
來源:轉載
供稿:網友

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

一些主流App也常見在導航欄嵌入searchBar,以網易云音樂和知乎為例,左邊是主頁,右邊是搜索頁面 (注意光標)。

實現思路與案例

核心思想是設置導航欄的titleView和左右的barButtonItem。主要有3種方式

  1.  首頁導航欄的titleView使用button來實現,搜索頁面使用searchBar。
  2. 首頁和搜索頁面導航欄的titleView都是用searchBar,searchBar的樣式針對兩個頁面做不同的修改。這種方式可以重用我們定制的searchBar,減少冗余。
  3. 首頁導航欄titleView使用button來實現,搜索頁面的使用textField。這種方式更徹底,更靈活,相對也更復雜一些。

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

案例

網易云音樂首頁和搜索頁面的導航欄視圖層級,titleView都使用MCSearchBar來實現,并且設置了導航欄左右兩邊的按鈕 。這類似上文所說的第二種思路。

 

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

實戰

通過自定義SearchBar實現一個如下樣式的導航欄

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

- (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; //光標顏色  self.barTintColor = [UIColor whiteColor];  self.placeholder = placeholder;  self.showsCancelButton = showCancelButton;  self.leftView = leftView; // 用來代替左邊的放大鏡  [self setImage:[UIImage imageNamed:@"clear"] forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal]; // 替換輸入過程中右側的clearIcon } return self;}

新建一個首頁OHHomeViewController,設置導航欄的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:@"點擊我跳轉"          textFieldLeftView:leftView           showCancelButton:NO            tintColor:[UIColor clearColor]]; self.navigationItem.titleView = self.ohSearchBar;

讓我們來看下效果,左邊為iOS 9,右邊iOS 11

這時候可以看到幾處差異

  1. searchBar的高度
  2. searchBar的textField的放大鏡和文字位置
  3. textField的圓角不一致
  4. 更細心的還會發現,textField的位置不一致

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

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]; }}

對于第三和第四個問題,用KVC獲取textField,并對其進行定制。令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}; // 光標偏移量}

同樣的,先看下運行效果

原本以為這下是沒什么問題的,結果簡直是坑

textFild的長度、位置、圓角都不一樣 解釋下這里出現的問題

觀察上方圖片上方的searchBar,會發現textField左邊是圓角,右邊是直角,說明是被截取的。導航欄titleView的范圍就劃分到了那個部分,而下邊的searchBar連rightBarButton都不放過,直接搶占了位置。推測這是由于iOS 11導航欄視圖層級變化產生的,可以這里了解下 www.jianshu.com/p/352f101d6… ,或者自行科普,不詳細展開。所以對于searchBar的size設置要小心了,盡量控制在合適的范圍。

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

searchField.borderStyle = UITextBorderStyleNone;

查看視圖層級會發現,iOS 11以下,設置titleView,x的默認坐標居然是12,而iOS 11是0。所以設置textField的x坐標的話,在iOS 11下必須多出12才會是一致的位置。

 

修改代碼上面的代碼

- (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, *)) {  // 查看視圖層級,在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}; // 光標偏移量}

這時候就是我們想要的結果了。

首頁暫時告一段落,接著開始我們的搜索頁面。與首頁不同的是需要searchBar與searchController配合使用。新建一個OHSearchController類 添加一個屬性

@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:@"請輸入搜索內容進行搜索"                  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;

完成這一步后到了交互環節了,點擊首頁的searchBar跳轉搜索頁面,點擊搜索頁面的取消按鈕返回到首頁。 首頁設置searchbar的代理,并完成一下代理方法

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

搜索頁設置searchbar的代理,并完成一下代理方法

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

這時候問題又出現了,點擊搜索頁面的取消按鈕,沒有跳回首頁而是還在這個頁面。但是可以看到屏幕的閃動。通過打印消息發現,點了取消按鈕,執行了首頁的- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar方法。 仔細推敲之后想明白了原因是沒有取消第一響應者,加上導航欄的交互機制,pop到上個頁面的時候并不會進行頁面刷新導致了這個問題。 解決辦法在首頁要push搜索頁面的時候取消第一響應者

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

到此,便大功告成了。可以看下源碼加深理解。希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久精品免费| 亚洲国产精品一区二区久| 欧美精品videos另类日本| 91久久精品国产91久久性色| 成人日韩在线电影| 亚洲一区二区三区视频播放| 7m第一福利500精品视频| 久久这里只有精品99| 亚洲免费成人av电影| 亚洲人成电影网站色xx| 国产区精品在线观看| 欧美自拍视频在线观看| 久久男人资源视频| 日韩有码在线电影| 国产精品自拍网| 国产一区二区三区在线| 欧美一级成年大片在线观看| 国产精自产拍久久久久久| 国产精品第8页| 亚洲人成在线免费观看| 成人午夜小视频| 亚洲精品一区av在线播放| 国产97在线|日韩| 91av在线精品| 色偷偷av一区二区三区乱| 日韩高清有码在线| 中文字幕在线亚洲| 日韩精品亚洲精品| 欧美激情va永久在线播放| 成人精品一区二区三区| 日韩欧美在线视频| 国产精品久久久久久久久久小说| 精品国产乱码久久久久久虫虫漫画| 亚洲第一精品电影| 色爱av美腿丝袜综合粉嫩av| 精品偷拍各种wc美女嘘嘘| 成人免费自拍视频| 欧美日韩加勒比精品一区| 最新69国产成人精品视频免费| 国产成人一区二区三区电影| 91豆花精品一区| www.99久久热国产日韩欧美.com| 欧美精品情趣视频| 国产视频综合在线| 欧美黄色成人网| 亚洲一区第一页| 国产一区二区三区在线| 亚洲美女动态图120秒| 欧美视频在线视频| 亚洲电影在线看| 中日韩午夜理伦电影免费| 亚洲免费中文字幕| 国产精品视频大全| 亚洲精品国产免费| 久久久久久久999精品视频| 久久97精品久久久久久久不卡| 夜夜躁日日躁狠狠久久88av| 国产精品亚洲欧美导航| 日本精品一区二区三区在线播放视频| 亚洲人成毛片在线播放| 欧美成人中文字幕在线| 国模私拍一区二区三区| 日韩在线观看免费全集电视剧网站| 久久久成人精品视频| 国产成人综合av| 日韩精品在线免费观看视频| 欧美亚洲激情在线| 亚洲第一区在线| www.色综合| 亚洲va国产va天堂va久久| 欧美黑人极品猛少妇色xxxxx| 亚洲欧美成人在线| 中文字幕日韩精品有码视频| 全色精品综合影院| 亚洲aⅴ日韩av电影在线观看| 亚洲自拍欧美另类| 午夜精品久久久久久99热软件| 久久成年人免费电影| 国产91精品久久久久久久| 国产香蕉精品视频一区二区三区| 亚洲欧美制服中文字幕| 欧美激情中文字幕在线| 亚洲欧美制服综合另类| 日韩av在线天堂网| 欧美一级淫片丝袜脚交| 国产精品wwwwww| 日产精品久久久一区二区福利| 91精品国产自产在线观看永久| 伊人久久久久久久久久| 麻豆乱码国产一区二区三区| 成人精品视频久久久久| 日韩精品视频中文在线观看| 国产精品自拍偷拍视频| 亚洲成年人在线| 黄色一区二区在线| 欧美激情喷水视频| 最近2019免费中文字幕视频三| 91在线精品播放| 久久影视免费观看| 一本一道久久a久久精品逆3p| 亚洲天堂av综合网| 欧美成人午夜剧场免费观看| 自拍偷拍亚洲在线| 亚洲精品美女久久| 海角国产乱辈乱精品视频| 欧美伊久线香蕉线新在线| 欧美日韩国产123| 久久精品国产成人| www.99久久热国产日韩欧美.com| 91亚洲精品久久久久久久久久久久| 91av成人在线| 国产亚洲精品久久久久久牛牛| 国产精品免费一区豆花| 国产精品视频自在线| 91免费看片网站| 国产精自产拍久久久久久蜜| 岛国视频午夜一区免费在线观看| 日本中文字幕不卡免费| 日韩乱码在线视频| 97不卡在线视频| 亚洲国产精品电影在线观看| 国产精品吊钟奶在线| 中文在线资源观看视频网站免费不卡| 91最新国产视频| 性欧美视频videos6一9| 国产精品日韩在线播放| 91久久久久久久久久| 成人美女av在线直播| 成人午夜高潮视频| 精品久久久久久国产| 日韩视频免费在线观看| 久久亚洲精品一区| 国产精品扒开腿做爽爽爽视频| 国产有码在线一区二区视频| 亚洲一区二区久久久久久久| 欧美日韩亚洲系列| 欧美丰满片xxx777| 中国日韩欧美久久久久久久久| 亚洲一区制服诱惑| 美女国内精品自产拍在线播放| 亚洲欧美精品一区| 亚洲精品自在久久| 国模私拍一区二区三区| 欧美综合一区第一页| 欧美精品一本久久男人的天堂| 日韩av黄色在线观看| 欧美日韩一区二区在线| 成人亚洲欧美一区二区三区| 青青草原一区二区| 久久色在线播放| 午夜精品在线观看| 成人免费视频在线观看超级碰| 精品久久久久久久久中文字幕| 这里只有精品久久| 欧美肥婆姓交大片| 姬川优奈aav一区二区| 在线观看亚洲区| 中文字幕日本精品| 亚洲国产精品va在线看黑人动漫| www.日韩免费| 亚洲无av在线中文字幕| 91精品国产电影| 亚洲福利视频久久| 亚洲永久在线观看|