嘗試使用UISearchDisplayController及對蘋果對控制項封裝習慣的理解

來源:互聯網
上載者:User

標籤:style   blog   http   io   ar   os   使用   for   sp   

本文轉載至 http://blog.sina.com.cn/s/blog_74e9d98d01019vji.html 

在之前做過的應用中,很多都有“搜尋”這個功能,大部分情況下我都是只採用UISearchBar並結合UItableView來展示搜尋結果,其 實IOS SDK中已經有內建的控制項能協助我們做好這些事,這就是UISearchDisplayController,當然這個控制項也有一些不足之處,下面我就一 一道來。。

首先我先講下UISearchDisplayController的實現原理:

UISearchDisplayController 不是一個viewController,不要被其字面意思給欺騙了,其實它的父類就是NSObject  ,它裡面就整合了 一個UISearchBar對象和一個UItableView對象,UISearchBar對象負責展示搜尋輸入框,UItableView對象負責展示 搜尋出來的結果。然後,調用者在外部實現一些UISearchDisplayDelegate中的方法來做一些自訂的處理,這個protocol中有很 多方法,其中最重要的就是

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString  此方法擷取使用者輸入的關鍵字searchString,然後開發人員處理出搜尋結果並返回YES,表示重新reload  UItableView對象

使用方法:

.h檔案

#import

 

@interface ViewController : UIViewController{

    UISearchDisplayController *searchDisplayController;

    NSArray *_searchResults;  //存放搜尋結果的數組

}

 

@property (retain, nonatomic) IBOutlet CustomSearchDisplayController *searchDisplayController;

@property (nonatomic, copy) NSArray *searchResults;

 

@end

 

.m檔案:

#pragma mark tableView

 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

    NSInteger rows = 0;

    if ([tableView  isEqual:self.searchDisplayController.searchResultsTableView]){ //表示當前tableView顯示的是搜尋結果

        rows = [self.searchResults count];

    }else{

        //此處可以展示所有的資料,一般本地搜尋可用到,如“電話簿”

    }   

 

    return rows;

}

 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];

        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    }  

 

   

 

    if ([tableView isEqual:self.searchDisplayController.searchResultsTableView]){

        cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];

    }else{

       // cell.textLabel.text = [self.allItems objectAtIndex:indexPath.row];

    }  

 

    return cell;

}

 

#pragma mark - UISearchDisplayController delegate methods

 

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller  shouldReloadTableForSearchString:(NSString *)searchString {

    //根據使用者的輸入的關鍵字searchString,處理出搜尋結果(可以是本地搜尋,可以是從伺服器請求過來的資料)到數組

self.searchResults中

    return YES; //返回yes,重新載入tableView對象

}

 

至此,UISearchDisplayController控制項的大致使用方法就是如此了。

 

不足之處

當使用UISearchDisplayController之後,你是否發現,當鍵盤彈出來的時候,會預設把navagationBar給隱藏起來,如果說不需要隱藏navagationBar,最好的處理方式就是重寫UISearchDisplayController的-(void)setActive:(BOOL)visible animated:(BOOL)animated方法:

    首先,自訂一個類CustomSearchDisplayController,繼承自UISearchDisplayController,然後在.m檔案中重寫該方法,並在該方法中主動顯示navagationBar,

    #import "CustomSearchDisplayController.h"

 

    @implementation CustomSearchDisplayController

 

    -(void)setActive:(BOOL)visible animated:(BOOL)animated

   {

     [super setActive:visible animated:animated];

     [self.searchContentsController.navigationController setNavigationBarHidden: NO animated: NO];

   }

 

   @end

 

   當沒有匹配的結果時,預設會在tableView上顯示一個“No Result”的標籤,如果說想自訂這個標籤,可以在tableview中迴圈遍曆出該標籤,然後按照你的想法去設定:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString

{

[self filterContentForSearchText:searchString];

if ([filteredListPinYin count] == 0) {

UITableView *tableView1 = self.searchDisplayController.searchResultsTableView;

for( UIView *subview in tableView1.subviews ) {

if( [subview class] == [UILabel class] ) {

UILabel *lbl = (UILabel*)subview; // sv changed to subview.

lbl.text = @”沒有結果”;

}

}

}

// Return YES to cause the search result table view to be reloaded.

return YES;

}

另外,由於UISearchDisplayController裡的UISearchBar對象和UITableView對象都是可訪問的,因此就給我們很多便利可以隨意的更改其在UI上的顯示效果

蘋果對控制項封裝習慣的理解:

   之前我做過的控制項封裝,基本上都是繼承自UIView或是UIViewController,這樣自訂出來的控制項通過初始化之後,可以直接add到view中並呈現出來,

但是仔細看看UISearchDisplayController,他並不是一個視圖類的對象,當通過調用初始化函數並指定delegate之後,我突然間陷入了無路之境,我現在已經建立好

UISearchDisplayController對象,我如何把它顯示到我應用的視圖上呢?

   研究了一會兒發現,只要把UISearchDisplayController的UISearchBar對象add到應用視圖中就OK了!這就很奇怪了,為什麼它的實現方式與之前自己的

實現不同呢,那之後再顯示搜尋結果的tableview的時候是如何展現到應用視圖中的呢?通過測試發現:

   原來UISearchDisplayController的UISearchBar對象初始化之後,預設進行了一些操作,如在UISearchDisplayController中實現UISearchBar的UISearchBarDelegate的相關方法,

以檢測跟蹤使用者的“點擊輸入框”、“搜尋索引鍵的變化”等一系列使用者行為,然後UISearchDisplayController根據這些行為進行“彈出鍵盤”、“顯示搜尋結果tableView”等,而這些響應的

行為它並沒有自己在類中寫死掉,而是通過留出一個delegate給外部,讓外部來實現這些具體的響應行為。至於它是怎樣將結果tableView添加到應用視圖中的,很明顯,

初始化函數:- (id)initWithSearchBar:(UISearchBar *)searchBar contentsController:(UIViewController *)viewController;中有個contentsController變數就是指的應用視圖congtoller,

這樣就明白了。

   由此,我們可以發現,蘋果對控制項的封裝是嚴格按照MVC的模式來的,在此處,UISearchDisplayController就是model層,它不是View,他不受View的管制(如初始化後add到應用視圖上),他應該是來管制視圖的,

它只去處理邏輯資料(如擷取使用者輸入的關鍵字並匹配出結果集),所以我們就可以明白了為什麼應用視圖只要add searchBar對象就行了的

嘗試使用UISearchDisplayController及對蘋果對控制項封裝習慣的理解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.