iOS 搜索功能止吐,粗仿網(wǎng)易云音樂

/**
最近做的項目中需要到一個仿照網(wǎng)易云音樂的搜索功能,我把它抽離出來供大家分享诵冒,有一些寫的不好的地方撑碴,歡迎大家指正
我在這里用朋友的測試接口展示數(shù)據(jù),僅供測試使用叹话,請勿進行商業(yè)用途
/
/

這里會講一下基本的搜索功能的搭建偷遗,首先是當點擊搜索框的時候,調(diào)起鍵盤并顯示搜索歷史記錄驼壶,然后在點擊記錄時返回搜索數(shù)據(jù)
當點擊鍵盤時候氏豌,顯示匹配到的關鍵字,點擊字段返回數(shù)據(jù)并將該字段存入到歷史記錄中
雖然搜索功能很小很簡單热凹,但是不細心的話也會出現(xiàn)很多bug泵喘,我會把我想到的一些注意事項寫在項目中,歡迎大家指正補充
**/

效果圖如下:


搜索Gif.gif

我們先來分析一下:首先點擊搜索框的時候般妙,彈出鍵盤纪铺,顯示歷史記錄;點擊鍵盤開始輸入時碟渺,需要匹配關鍵字鲜锚;點擊鍵盤上的搜索,點擊歷史記錄苫拍,點擊匹配到的關鍵字的時候都要返回值芜繁,然后界面刷新UI。
我們需要搭建一個本地數(shù)據(jù)庫來存儲搜索的歷史記錄
DataBase.h
<pre>

import <Foundation/Foundation.h>

import "SearchModel.h"

@interface DataBase : NSObject

/**

  • 創(chuàng)建單例接口
    */
  • (DataBase *)shareDataBase;

pragma mark -

/**

  • 收藏接口
    */
  • (void)saveModel:(SearchModel )model;
    /
    *
  • 判斷是否已經(jīng)收藏
    */
  • (BOOL)isHadSaveModel:(SearchModel )model;
    /
    *
  • 獲取收藏的所有數(shù)據(jù)
    */
  • (NSArray )selectAllModel;
    /
    *
  • 刪除一個收藏
    */
  • (void)deleteOneModelByStr:(NSString *)str;

@end

</pre>
.m
<pre>

import "DataBase.h"

import "FMDB.h"

@interface DataBase ()

@property (nonatomic, strong) FMDatabase *db;

@end

@implementation DataBase
// 創(chuàng)建單例

  • (DataBase *)shareDataBase
    {
    static DataBase *single = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    single = [[DataBase alloc] init];
    [single creatDataBase];
    });
    return single;
    }

// 創(chuàng)建數(shù)據(jù)庫

  • (void)creatDataBase
    {
    // 在Documents文件夾下創(chuàng)建db.sqlite
    NSString *dbPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"db.splite"];

    // 初始化
    self.db = [FMDatabase databaseWithPath:dbPath];
    // 打開數(shù)據(jù)庫
    [self.db open];
    // 創(chuàng)建表格
    [self creatTable];

}

  • (void)creatTable
    {
    BOOL isSuccess = [self.db executeUpdate:@"create table if not exists MV(id integer primary key autoincrement, historyStr text)"];
    NSLog(@"%@", isSuccess ? @"表格創(chuàng)建成功":@"表格創(chuàng)建失敗");
    }

  • (BOOL)isHadSaveModel:(SearchModel *)model
    {
    FMResultSet *set = [self.db executeQuery:@"select * from MV where historyStr = ?", model.historyStr];
    while ([set next]) {
    NSString *historyStr = [set stringForColumn:@"historyStr"];
    if ([model.historyStr isEqualToString:historyStr]) {
    return YES;
    }
    }
    return NO;
    }

  • (void)saveModel:(SearchModel *)model
    {
    BOOL isSuccess = [self.db executeUpdate:@"insert into MV(historyStr) values (?)", model.historyStr];

    NSLog(@"%@", isSuccess ? @"收藏成功":@"收藏失敗");
    }

  • (NSArray *)selectAllModel
    {
    FMResultSet *set = [self.db executeQuery:@"select *from MV"];
    NSMutableArray *arr = [NSMutableArray array];
    while ([set next]) {
    NSString *historyStr = [set stringForColumn:@"historyStr"];
    SearchModel *model = [[SearchModel alloc] init];
    model.historyStr = historyStr;
    [arr addObject:model];
    }
    return arr;
    }

  • (void)deleteOneModelByStr:(NSString *)str
    {
    BOOL isSuccess = [self.db executeUpdate:@"delete from MV where historyStr = ?", str];

    NSLog(@"%@", isSuccess ? @"刪除成功":@"刪除失敗");
    }

</pre>

搭建一下主界面绒极,這里我是用一個collectionView寫的. 實現(xiàn)代理方法
<pre>
/**

  • 創(chuàng)建一個collectionView
    */
  • (void)creatCollectionView
    {
    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
    self.myCollection = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 60, ScreenWidth, ScreenHeight - 60) collectionViewLayout:flowLayout];
    self.myCollection.backgroundColor = [UIColor orangeColor];
    _myCollection.dataSource = self;
    _myCollection.delegate = self;
    [self.view addSubview:_myCollection];
    [_myCollection registerClass:[UserCollectionViewCell class] forCellWithReuseIdentifier:cellID];
    [self.view addSubview:_myCollection];

    // 在collection上添加一個搜索框
    self.searchTextField = [[UITextField alloc] initWithFrame:CGRectMake(50, 20, ScreenWidth-100, 40)];
    _searchTextField.placeholder = @"??輸入關鍵字查詢";
    _searchTextField.textColor = [UIColor redColor];
    _searchTextField.borderStyle = UITextBorderStyleRoundedRect;
    [self.view addSubview:_searchTextField];
    // 設置textfield的return鍵為搜索鍵
    _searchTextField.returnKeyType = UIReturnKeySearch;
    // 設置textfield的代理
    _searchTextField.delegate = self;

}

</pre>

然后我們需要再寫一個tableView骏令,用來展示歷史記錄和匹配到的關鍵字
<pre>
**

  • table的cell有兩種,一種是歷史的cell集峦,一種是匹配關鍵字的cell伏社,這里我建了兩個cell
  • 分別展示抠刺,根據(jù)傳入的一個標識分別創(chuàng)建(因為兩個cell只有一個button的區(qū)別,也可以創(chuàng)建一
  • 個cell再來控制button的顯隱性摘昌。不過我特么就是想創(chuàng)建兩個)
    */
  • (void)creatTableViewWithStr:(NSString *)str
    {
    self.myTable = [[UITableView alloc] initWithFrame:CGRectMake(0, 60, ScreenWidth, ScreenHeight-60) style:(UITableViewStylePlain)];
    if ([str isEqualToString:@"history"]) {
    [_myTable registerNib:[UINib nibWithNibName:@"HistoryTableViewCell" bundle:nil] forCellReuseIdentifier:tableCellId];
    }else {
    [_myTable registerNib:[UINib nibWithNibName:@"KeyWordTableViewCell" bundle:nil] forCellReuseIdentifier:tableCellId];
    } _myTable.delegate = self;
    _myTable.dataSource = self;

    // 當tableView滑動時收起鍵盤
    _myTable.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
    // 取消tableView的分割線
    _myTable.separatorStyle = UITableViewCellSeparatorStyleNone;

    [self.view addSubview:_myTable];
    }

</pre>
在這里看一下我在主控制器中所定義的屬性速妖,都是要用到的。
<pre>
@interface ViewController ()<UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, UITextFieldDelegate, UITableViewDelegate, UITableViewDataSource>

@property (nonatomic, strong) UICollectionView *myCollection; //

@property (nonatomic, strong) UITableView *myTable; //

@property (nonatomic, strong) UITextField *searchTextField; // 搜索框

@property (nonatomic, strong) NSMutableArray dataSource; // cell數(shù)據(jù)源
@property (nonatomic, strong) NSMutableArray textFieldDataSource; // 匹配字段數(shù)據(jù)源
@property (nonatomic, strong) NSMutableArray historyDataSource; // 搜索歷史數(shù)據(jù)源
/
我在這里用一個替換字段接收請求下來的匹配字段的數(shù)據(jù)聪黎。罕容。不這樣做的話,在匹配字段返回的cell時稿饰,如果是在漢語模式下編輯锦秒,在沒有確定輸入字段時,此時已經(jīng)匹配到了字段喉镰,但是如果點擊的時候旅择,在點擊事件中,原來的數(shù)據(jù)源是空的侣姆,可能是我在哪里清空了原來的數(shù)據(jù)源生真,我沒有找到,只能用一個新的數(shù)據(jù)源來替代捺宗。英文模式下輸入柱蟀,暫時沒有發(fā)現(xiàn)這種問題(讀這個源碼的朋友如果能改進這個錯誤請私信我,萬分感謝Q晾鳌3ひ选!)
*/
@property (nonatomic, strong) NSMutableArray *placeTextDataSource; // 替換匹配字段

@property (nonatomic, strong) NSString *judgeStr; // 用來判斷展示的table

@property (nonatomic, strong) SearchModel *model;

// 輸入顯示字段
@property (nonatomic, strong) NSString *textFieldStr;

@end
</pre>
我們要通過textField的代理事件來實現(xiàn)搜索的交互事件
<pre>

pragma mark --- TextFieldDelegate

/**

  • 點擊鍵盤搜索按鈕
    */
  • (BOOL)textFieldShouldReturn:(UITextField *)textField
    {
    // 收起鍵盤
    [_searchTextField resignFirstResponder];
    // 移除tableView
    [_myTable removeFromSuperview];
    // 先清空數(shù)據(jù)源昼牛,然后請求數(shù)據(jù)
    [self.dataSource removeAllObjects];
    [self getDataByText:textField.text];

    // 存入搜索歷史
    _model.historyStr = textField.text;
    if (textField.text.length>0) {
    if (![[DataBase shareDataBase] isHadSaveModel:_model]) {
    [[DataBase shareDataBase] saveModel:_model];
    }
    }

return YES;

}
/**

  • 點擊輸入框開始編輯時走這個方法术瓮。 (我們需要點擊輸入框時,在輸入框下面出現(xiàn)一
  • 個tableView來展示搜索的歷史記錄)
    */
  • (void)textFieldDidBeginEditing:(UITextField *)textField
    {

    // 先移除之前添加上的tableView
    [self.myTable removeFromSuperview];
    // 再次添加
    self.judgeStr = History;
    [self creatTableViewWithStr:self.judgeStr];

    // 打開輸入框后匾嘱,展示搜索歷史記錄
    self.historyDataSource = [NSMutableArray arrayWithArray:[[DataBase shareDataBase] selectAllModel]];
    [self.myTable reloadData];
    }

/**

  • 當我們開始編輯時斤斧,根據(jù)我們當前輸入的字段進行匹配關鍵字,需要用到這個方法霎烙。 這個方法
  • 是當輸入框內(nèi)容開始發(fā)生變化時調(diào)用
    */
  • (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {

    // 輸入時開始匹配關鍵字,顯示另一個tableView
    // 先移除之前添加上的tableView
    [self.myTable removeFromSuperview];
    // 再次添加
    self.judgeStr = keyWord;
    [self creatTableViewWithStr:self.judgeStr];

    self.textFieldStr = string;

    // 請求匹配關鍵字
    // 先清空保存的數(shù)據(jù)
    [self.textFieldDataSource removeAllObjects];
    [self getDataByTextfieldText:self.textFieldStr];

    return YES;
    }

</pre>

代碼有點多蕊连,不明白的同學可以到我的git主頁上下載源碼悬垃,里面注釋寫的也比較詳細
git:https://github.com/you12138/SearchLikeWangYiMusic.git

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市甘苍,隨后出現(xiàn)的幾起案子尝蠕,更是在濱河造成了極大的恐慌,老刑警劉巖载庭,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件看彼,死亡現(xiàn)場離奇詭異廊佩,居然都是意外死亡,警方通過查閱死者的電腦和手機靖榕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門标锄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人茁计,你說我怎么就攤上這事料皇。” “怎么了星压?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵践剂,是天一觀的道長。 經(jīng)常有香客問我娜膘,道長逊脯,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任竣贪,我火速辦了婚禮军洼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘贾富。我一直安慰自己歉眷,他們只是感情好,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布颤枪。 她就那樣靜靜地躺著汗捡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪畏纲。 梳的紋絲不亂的頭發(fā)上扇住,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機與錄音盗胀,去河邊找鬼艘蹋。 笑死,一個胖子當著我的面吹牛票灰,可吹牛的內(nèi)容都是我干的女阀。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼屑迂,長吁一口氣:“原來是場噩夢啊……” “哼浸策!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起惹盼,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤庸汗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后手报,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚯舱,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡改化,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了枉昏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陈肛。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖凶掰,靈堂內(nèi)的尸體忽然破棺而出燥爷,到底是詐尸還是另有隱情,我是刑警寧澤懦窘,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布前翎,位于F島的核電站,受9級特大地震影響畅涂,放射性物質(zhì)發(fā)生泄漏港华。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一午衰、第九天 我趴在偏房一處隱蔽的房頂上張望立宜。 院中可真熱鬧,春花似錦臊岸、人聲如沸橙数。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灯帮。三九已至,卻和暖如春逻住,著一層夾襖步出監(jiān)牢的瞬間钟哥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工瞎访, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留腻贰,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓扒秸,卻偏偏與公主長得像播演,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子伴奥,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,163評論 25 707
  • Swift版本點擊這里歡迎加入QQ群交流: 594119878最新更新日期:18-09-17 About A cu...
    ylgwhyh閱讀 25,393評論 7 249
  • 我在這里肄程, 你也在這里锣吼, 我們熟識选浑,卻又像路人, 我們不曾伴著咖啡長談玄叠, 只有匆匆的遇見古徒。 美麗過后,你還是那個你...
    流楓鮰雪閱讀 53評論 0 0
  • 睡不著的時候读恃,最美好的事便是靜聽夜的語言隧膘。 最近天氣燥熱地非常,每晚不能正常入睡寺惫,今晚算是徹底的一回疹吃。我在床上輾轉(zhuǎn)...
    曾彧閱讀 528評論 9 2
  • 這幾天心里很煩,人生的諸多不順總是在不經(jīng)意的襲來西雀,社會繁忙凝成了心中沉重的困惑萨驶,我自己仿佛成了一只孤獨而又疲...
    玫瑰心閱讀 202評論 0 1