iOS开发之旅(2):实现一个APP界面框架之搜索功能
2017-09-03 10:20
931 查看
前言
在上一篇博文中,为大家演示了如何去构建完成一个 APP 的雏形,就好像我们盖楼一样得先把这栋屋子的地基先稳固了,只有地基稳固了万丈高楼才能拔地而起,在上篇文章中,我们就先把 APP 的雏形给写完了,在这次的文章中,来给大家演示如何写一个搜索功能。效果图如下:
废话不多说,咋们直接开撸!
第一部分
在导航栏右上角加上搜索按钮,由于上一篇的自定义导航栏功能过于简单,所以这次我重写了导航栏的代码,可以自定义设置导航栏的标题与按钮样式,代码如下:// // CustomNaviBarView.m // CoolFrame // // Created by silicon on 2017/8/3. // Copyright © 2017年 com.snailgames.coolframe. All rights reserved. // #import "CustomNaviBarView.h" #import "GlobalDefine.h" @implementation CustomNaviBarView @synthesize btnBack = _btnBack; @synthesize labelTitle = _labelTitle; @synthesize imgViewBg = _imgViewBg; @synthesize btnLeft = _btnLeft; @synthesize btnRight = _btnRight; + (CGRect)leftBtnFrame{ return Rect(10, 22.0f, [[self class] barBtnSize].width, [[self class] barBtnSize].height); } + (CGRect)rightBtnFrame{ return Rect(ScreenWidth - 60.0f, 22.0f, [[self class] barBtnSize].width, [[self class] barBtnSize].height); } + (CGSize)barBtnSize{ return Size(50.0f, 40.0f); } + (CGSize)barSize{ return Size(ScreenWidth, 64.0f); } + (CGRect)titleViewFrame{ return Rect(65.0f, 22.0F, ScreenWidth - 130, 40.0f); } + (UIButton *)createNavBarImageBtn:(NSString *)imgStr Highligthed:(NSString *)imgHighStr Target:(id)target Action:(SEL)action{ UIImage *imgNormal = [UIImage imageNamed:imgStr]; UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; [btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside]; [btn setImage:imgNormal forState:UIControlStateNormal]; [btn setImage:[UIImage imageNamed:(imgHighStr ? imgHighStr : imgStr)] forState:UIControlStateHighlighted]; CGFloat fDeltaWidth = ([[self class] barBtnSize].width - imgNormal.size.width)/2.0f; CGFloat fDeltaHeight = ([[self class] barBtnSize].height - imgNormal.size.height)/2.0f; fDeltaWidth = (fDeltaWidth >= 2.0f) ? fDeltaWidth/2.0f : 0.0f; fDeltaHeight = (fDeltaHeight >= 2.0f) ? fDeltaHeight/2.0f : 0.0f; [btn setImageEdgeInsets:UIEdgeInsetsMake(fDeltaHeight, fDeltaWidth, fDeltaHeight, fDeltaWidth)]; [btn setTitleEdgeInsets:UIEdgeInsetsMake(fDeltaHeight, -imgNormal.size.width, fDeltaHeight, fDeltaWidth)]; return btn; } - (id)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if(self){ [self initUI]; } return self; } - (void)initUI{ self.backgroundColor = [UIColor clearColor]; self.btnBack = [[self class] createNavBarImageBtn:@"return_icon" Highligthed:@"return_icon" Target:self Action:@selector(btnBack:)]; self.labelTitle = [[UILabel alloc] initWithFrame:CGRectZero]; self.labelTitle.backgroundColor = [UIColor clearColor]; self.labelTitle.textColor = [UIColor whiteColor]; self.labelTitle.textAlignment = NSTextAlignmentCenter; self.imgViewBg = [[UIImageView alloc] initWithFrame:self.bounds]; self.imgViewBg.image = [[UIImage imageNamed:@"nav_bg"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)]; self.labelTitle.frame = [[self class] titleViewFrame]; [self addSubview:self.imgViewBg]; [self addSubview:self.labelTitle]; [self addSubview:self.btnBack]; } - (UIImage *)m_background{ return _imgViewBg.image; } - (void)setTitle:(NSString *)titleStr{ [self.labelTitle setText:titleStr]; } - (void)setLeftBtn:(UIButton *)btn{ if(_btnLeft){ [_btnLeft removeFromSuperview]; _btnLeft = nil; } _btnLeft = btn; if(_btnLeft){ [_btnLeft setFrame:[[self class] leftBtnFrame]]; [self addSubview:_btnLeft]; } } - (void)setRightBtn:(UIButton *)btn{ if(_btnRight){ [_btnRight removeFromSuperview]; _btnRight = nil; } _btnRight = btn; if(_btnRight){ [_btnRight setFrame:[[self class] rightBtnFrame]]; [self addSubview:_btnRight]; } } - (void)btnBack:(id)sender{ if(self.m_viewCtrlParent){ [self.m_viewCtrlParent.navigationController popViewControllerAnimated:YES]; } } - (void)showCoverView:(UIView *)view { [self showCoverView:view animation:NO]; } - (void)showCoverView:(UIView *)view animation:(BOOL)bIsAnimation { if (view) { [self hideOriginalBarItem:YES]; [view removeFromSuperview]; view.alpha = 0.4f; [self addSubview:view]; if (bIsAnimation) { [UIView animateWithDuration:0.2f animations:^() { view.alpha = 1.0f; }completion:^(BOOL f){}]; } else { view.alpha = 1.0f; } } } - (void)showCoverViewOnTitleView:(UIView *)view { if (view) { if (_labelTitle) { _labelTitle.hidden = YES; }else{} [view removeFromSuperview]; view.frame = CGRectMake(_labelTitle.frame.origin.x + 10, _labelTitle.frame.origin.y +4, _labelTitle.frame.size.width - 20, _labelTitle.frame.size.height - 8); [self addSubview:view]; } } - (void)hideCoverView:(UIView *)view { [self hideOriginalBarItem:NO]; if (view && (view.superview == self)) { [view removeFromSuperview]; } } - (void)hideOriginalBarItem:(BOOL)bIsHide { if (_btnLeft) { _btnLeft.hidden = bIsHide; } if (_btnBack) { _btnBack.hidden = bIsHide; } if (_btnRight) { _btnRight.hidden = bIsHide; } if (_labelTitle) { _labelTitle.hidden = bIsHide; } } @end
第二部分
如大家图上所见,我们在搜索的界面中包含了三个部分,首先是搜索栏,其次是热搜榜,最后是搜索历史,为了能够更为有效的去管理我们的搜索逻辑,这里就要去实现一个搜索管理类,这个类别主要是用于处理我们搜索的回调,热搜榜,以及搜索结果,搜索历史,代码如下:
// // NaviBarSearchController.m // CoolFrame // // Created by shenjie on 2017/8/6. // Copyright © 2017年 com.snailgames.coolframe. All rights reserved. // #import "NaviBarSearchController.h" #import "GlobalDefine.h" #import "CustomNaviBarView.h" #import "HotSearchCell.h" #import "SearchHistoryCell.h" #define RECT_NaviBar Rect(0.0f, StatusBarHeight, ScreenWidth, 44.0f) #define RECT_SearchBarFrame Rect(0.0f, 0.0f, [CustomNaviBarView rightBtnFrame].origin.x + 10, 44.0f) #define RECT_SearchBarCoverCancelBtnFrame Rect(0.0f, 0.0f, ScreenWidth, NaviBarHeight) #define RECT_CancelBtnFrame Rect([CustomNaviBarView rightBtnFrame].origin.x, 0.0f, [CustomNaviBarView rightBtnFrame].size.width, NaviBarHeight) @interface SearchTableHeaderView : UIView @property (strong, nonatomic) UIImageView *sep_line; @property (strong, nonatomic) UILabel *titleLabel; @property (strong, nonatomic) UIButton *btnOp; @end @implementation SearchTableHeaderView @synthesize sep_line = _sep_line; @synthesize titleLabel = _titleLabel; @synthesize btnOp = _btnOp; - (id)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if(self){ self.titleLabel = [[UILabel alloc] init]; [self.titleLabel setTextAlignment:NSTextAlignmentLeft]; [self.titleLabel setFont:[UIFont systemFontOfSize:14]]; [self.titleLabel setTextColor:RGBA(255, 255, 255, 0.5)]; [self.titleLabel setBackgroundColor:[UIColor clearColor]]; [self addSubview:self.titleLabel]; self.btnOp = [[UIButton alloc] init]; [self.btnOp setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight]; [self.btnOp.titleLabel setFont:[UIFont systemFontOfSize:14]]; [self.btnOp setTitleColor:RGBA(255, 255, 255, 0.5) forState:UIControlStateNormal]; [self.btnOp setBackgroundColor:[UIColor clearColor]]; [self addSubview:self.btnOp]; self.sep_line = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"separator_line"]]; [self.sep_line setContentMode:UIViewContentModeBottom]; self.sep_line.clipsToBounds = YES; [self addSubview:self.sep_line]; } return self; } - (void)layoutSubviews{ [super layoutSubviews]; CGRect rcView = [self bounds]; CGRect rcTitle= CGRectMake(10*ScreenScale, (rcView.size.height -20)/2, rcView.size.width/2 - 15, 20); self.titleLabel.frame = rcTitle; CGRect rcBtn = CGRectMake(rcView.size.width - 10*ScreenScale - 50, (rcView.size.height -20)/2, 50, 20); self.btnOp.frame = rcBtn; CGRect rcSep = CGRectMake(10*ScreenScale, rcView.size.height -4, rcView.size.width - 20*ScreenScale, 4); self.sep_line.frame = rcSep; } @end @implementation NaviBarSearchController @synthesize delegate = _delegate; @synthesize m_viewCtrlParent = _m_viewCtrlParent; @synthesize m_viewNaviBar = _m_viewNaviBar; @synthesize m_searchBar = _m_searchBar; @synthesize m_btnCancel = _m_btnCancel; @synthesize m_tableView = _m_tableView; @synthesize m_arrRecent = _m_arrRecent; @synthesize m_arrHot = _m_arrHot; @synthesize m_viewBlackCover = _m_viewBlackCover; @synthesize m_imgBlurBg = _m_imgBlurBg; @synthesize m_bIsWorking = _m_bIsWorking; @synthesize m_bIsFixation = _m_bIsFixation; @synthesize m_bIsCoverTitleView = _m_bIsCoverTitleView; - (id)initWithParentViewCtrl:(CustomViewController *)viewCtrl{ self = [super init]; if(self){ self.m_viewCtrlParent = viewCtrl; [self initUI]; } return self; } - (void)initUI{ self.m_viewNaviBar = [[UIView alloc] initWithFrame:CGRectMake(0, StatusBarHeight, ScreenWidth, 44.0f)]; //设置自定义的搜索栏 self.m_searchBar = [[CustomUISearchBar alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, 44.0f)]; self.m_searchBar.placeholder = @"mo reng"; self.m_searchBar.translucent = YES; self.m_searchBar.backgroundColor = [UIColor clearColor]; self.m_searchBar.searchBarStyle = UISearchBarStyleMinimal; UIColor *color = [UIColor colorWithRed:255/255.0 green:255/255.0 blue:255/255.0 alpha:1]; [self.m_searchBar changeBarTextfieldWithColor:color bgImageName:nil]; self.m_searchBar.delegate = self; self.m_btnCancel = [[UIButton alloc] init]; [self.m_btnCancel setFrame:CGRectMake([CustomNaviBarView rightBtnFrame].origin.x, 0.0f, [CustomNaviBarView rightBtnFrame].size.width, 44.0f)]; [self.m_btnCancel setTitle:@"取消" forState:UIControlStateNormal]; [self.m_btnCancel.titleLabel setFont:[UIFont systemFontOfSize:15.0f]]; [self.m_btnCancel addTarget:self action:@selector(clickBtnCancel:) forControlEvents:UIControlEventTouchUpInside]; [self.m_btnCancel setTintColor:[UIColor whiteColor]]; self.m_btnCancel.hidden = YES; [self.m_viewNaviBar addSubview:self.m_searchBar]; [self.m_viewNaviBar addSubview:self.m_btnCancel]; self.m_viewBlackCover = [[UIImageView alloc] initWithFrame:self.m_viewCtrlParent.view.bounds]; [self.m_viewBlackCover setBackgroundColor:[UIColor clearColor]]; self.m_viewBlackCover.userInteractionEnabled = YES; self.m_viewBlackCover.backgroundColor = RGBA(0.0f, 0.0f, 0.0f, 0.0f); UITapGestureRecognizer *tapToClose = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapToClose:)]; [self.m_viewBlackCover addGestureRecognizer:tapToClose]; } - (void)resetPlaceHolder:(NSString *)holderStr{ self.m_searchBar.placeholder = holderStr; } //- (void)showTempSearchCtrl{ // [self.m_viewCtrlParent naviBarAddCoverView:self.m_viewNaviBar]; // self.m_bIsFixation = NO; // self.m_bIsCoverTitleView = NO; // // [self startSearch]; //} - (void)startSearch{ if(_delegate && [_delegate respondsToSelector:@selector(naviBarSearchCtrlStartSearch:)]){ [_delegate naviBarSearchCtrlStartSearch:self]; } [self startWorking]; } - (void)removeSearchCtrl{ if([self.m_searchBar isFirstResponder]){ [self.m_searchBar resignFirstResponder]; } [_m_viewCtrlParent naviBarRemoveCoverView:self.m_viewNaviBar]; [_m_viewBlackCover removeFromSuperview]; } - (void)showFixationSearchCtrl{ [self.m_viewCtrlParent naviBarAddCoverView:self.m_viewNaviBar]; self.m_bIsFixation = YES; self.m_bIsCoverTitleView = NO; } //- (void)showFixationSearchCtrlOnTitleView{ // [self.m_viewNaviBar setFrame:[CustomNaviBarView titleViewFrame]]; // [self.m_searchBar setFrame:self.m_viewNaviBar.bounds]; // // [self.m_viewCtrlParent naviBarAddCoverViewOnTitleView:self.m_viewNaviBar]; // // self.m_bIsFixation = YES; // self.m_bIsCoverTitleView = YES; //} - (void)setRecentKeyword:(NSArray *)arrRecentKeyword{ if(arrRecentKeyword){ self.m_arrRecent = [NSArray arrayWithArray:arrRecentKeyword]; }else{ self.m_arrRecent = nil; } if(self.m_tableView){ [self.m_tableView reloadData]; } } - (void)setKeyword:(NSString *)strKeyowrd{ if(self.m_searchBar){ [self.m_searchBar setText:strKeyowrd]; } } - (void)setHotSearchKeys:(NSArray *)arrSearchKeys{ if(arrSearchKeys){ self.m_arrHot = [NSArray arrayWithArray:arrSearchKeys]; }else{ self.m_arrHot = nil; } if(self.m_tableView){ [self.m_tableView reloadData]; } } #pragma mark -click event - (void)clickBtnCancel:(id)sender{ _m_searchBar.text = @""; [self endWorking]; if(_delegate && [_delegate respondsToSelector:@selector(naviBarSearchCtrlCancel:)]){ [_delegate naviBarSearchCtrlCancel:self]; } } - (void)handleTapToClose:(UIGestureRecognizer *)gesture{ [self endWorking]; if (_delegate && [_delegate respondsToSelector:@selector(naviBarSearchCtrlCancel:)]) { [_delegate naviBarSearchCtrlCancel:self]; } } #pragma mark -start search - (void)startWorking{ _m_btnCancel.hidden = NO; if (_m_bIsCoverTitleView) { _m_viewNaviBar.frame = RECT_NaviBar; _m_searchBar.frame = RECT_SearchBarFrame; } else { _m_searchBar.frame = RECT_SearchBarFrame; } _m_viewBlackCover.alpha = 0.0f; [_m_viewCtrlParent.view addSubview:_m_viewBlackCover]; if (![_m_searchBar isFirstResponder]) { [_m_searchBar becomeFirstResponder]; }else{} [self showRecentTable:YES]; [_m_viewCtrlParent bringNaviBarToTopmost]; _m_bIsWorking = YES; } - (void)endWorking{ _m_btnCancel.hidden = NO; if (_m_bIsCoverTitleView) { _m_viewNaviBar.frame = [CustomNaviBarView titleViewFrame]; _m_searchBar.frame = RECT_SearchBarFrame; } else { _m_searchBar.frame = RECT_SearchBarFrame; } if ([_m_searchBar isFirstResponder]) { [_m_searchBar resignFirstResponder]; }else{} [_m_viewBlackCover removeFromSuperview]; [self showRecentTable:NO]; _m_bIsWorking = NO; } - (void)showRecentTable:(BOOL)bIsShow{ if(bIsShow){ if(!self.m_tableView){ self.m_tableView = [[UITableView alloc] initWithFrame:_m_viewCtrlParent.view.bounds style:UITableViewStylePlain]; [self.m_tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone]; [_m_viewCtrlParent.view addSubview:_m_tableView]; UITapGestureRecognizer *tapToClose = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapToClose:)]; tapToClose.delegate = self; [self.m_tableView addGestureRecognizer:tapToClose]; [self.m_tableView setBackgroundColor:[UIColor clearColor]]; self.m_tableView.delegate = self; self.m_tableView.dataSource = self; } self.m_tableView.hidden = NO; self.m_tableView.frame = Rect(_m_tableView.frame.origin.x, _m_tableView.frame.origin.y+_m_tableView.frame.size.height, _m_tableView.frame.size.width, _m_tableView.frame.size.height); [UIView animateWithDuration:0.3f animations:^() { _m_tableView.frame = CGRectMake(0,[CustomNaviBarView barSize].height, CGRectGetWidth(_m_viewCtrlParent.view.bounds), CGRectGetHeight(_m_viewCtrlParent.view.bounds) - [CustomNaviBarView barSize].height); }]; }else{ if(_m_tableView){ [_m_tableView removeFromSuperview]; _m_tableView = nil; } } } #pragma mark - UISearchBarDelegate - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{ if(searchBar.text){ NSString *strKeyword = [[searchBar.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] copy]; if(strKeyword.length > 0){ searchBar.text = @""; [self endWorking]; if (_delegate && [_delegate respondsToSelector:@selector(naviBarSearchCtrl:searchKeyword:)]) { [_delegate naviBarSearchCtrl:self searchKeyword:strKeyword]; } }else{ searchBar.text = @""; } } } - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{ [self startSearch]; } #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 2; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ if(section == 0){ return 1; }else if(section == 1){ NSInteger iCount = self.m_arrRecent ? self.m_arrRecent.count : 0; return iCount; } return 0; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ if(indexPath.section == 0){ HotSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:@"hotsearchcell"]; if(!cell){ cell = [[HotSearchCell alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, 120)]; [cell setBackgroundColor:[UIColor clearColor]]; [cell initWithHotKeys:self.m_arrHot]; } return cell; }else if(indexPath.section == 1){ SearchHistoryCell *cell = [tableView dequeueReusableCellWithIdentifier:@"histroysearchcell"]; if(!cell){ cell = [[SearchHistoryCell alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, 45)]; } [cell.history setText:[_m_arrRecent objectAtIndex:indexPath.row]]; [cell.clear addTarget:self action:@selector(btnRemoveSearchRecord:) forControlEvents:UIControlEventTouchUpInside]; return cell; } return nil; } #pragma mark - table view delegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ NSString *strKeyword = [self.m_arrRecent objectAtIndex:indexPath.row]; [self.m_searchBar setText:strKeyword]; [self searchBarSearchButtonClicked:self.m_searchBar]; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ if(indexPath.section == 0){ return 120.0f; }else if(indexPath.section == 1){ return 45.0f; } return 35.0f; } - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{ return 44; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{ SearchTableHeaderView *view = [[SearchTableHeaderView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, 44)]; if(section == 0){ [view.titleLabel setText:@"热搜"]; [view.btnOp setTitle:@"换一批" forState:UIControlStateNormal]; [view.btnOp addTarget:self action:@selector(btnNewHotSearchKeys:) forControlEvents:UIControlEventTouchUpInside]; }else if(section == 1){ [view.titleLabel setText:@"搜索历史"]; [view.btnOp setTitle:@"清除" forState:UIControlStateNormal]; [view.btnOp addTarget:self action:@selector(btnClearSearchRecord:) forControlEvents:UIControlEventTouchUpInside]; } return view; } - (void)btnNewHotSearchKeys:(id)sender{ if(_delegate && [_delegate respondsToSelector:@selector(naviBarSearchCtrlRefreshHotSearchKey:)]){ [_delegate naviBarSearchCtrlRefreshHotSearchKey:self]; } } - (void)btnClearSearchRecord:(id)sender{ if(_delegate && [_delegate respondsToSelector:@selector(naviBarSearchCtrlClearKeywordRecord:)]){ [_delegate naviBarSearchCtrlClearKeywordRecord:self]; } } - (void)btnRemoveSearchRecord:(id)sender{ if(_delegate && [_delegate respondsToSelector:@selector(naviBarSearchCtrl:RemoveSearchRecord:)]){ SearchHistoryCell *cell = (SearchHistoryCell *)[[sender superview] superview]; if(cell){ NSIndexPath* indexPath = [_m_tableView indexPathForCell:cell]; if(nil == indexPath) return; NSString *strKeyword = _m_arrRecent[indexPath.row]; [_delegate naviBarSearchCtrl:self RemoveSearchRecord:strKeyword]; } } } #pragma mark - gesture delegate - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{ return YES; } @end
第三部分
万能的 UITableView 登场,想必大家对它不陌生吧!用它来对数据进行管理,高效直观,这里我们就把它来嵌入到我们的搜索界面中,以及模拟一些搜索数据,代码如下:// // SearchViewController.m // CoolFrame // // Created by silicon on 2017/8/4. // Copyright © 2017年 com.snailgames.coolframe. All rights reserved. // #import "SearchViewController.h" #import "CustomNaviBarView.h" #import "GlobalDefine.h" #import "JSONKit.h" #import "SearchResultCell.h" static NSArray *data; static NSArray *hotSearch; @interface SearchViewController () @end @implementation SearchViewController @synthesize searchController = _searchController; @synthesize searchResultTableView = _searchResultTableView; @synthesize searchResultDataSource = _searchResultDataSource; @synthesize recentSearchKeys = _recentSearchKeys; @synthesize noSearchResultView = _noSearchResultView; - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. data = @[@"习近平对四川九寨沟7.0级地震作出重要指示", @"五年深改成绩单 不畏深水 砥砺奋进 治国理政", @"俞正声观看庆内蒙古自治区成立70周年文艺晚会", @"微电影:哪怕当裤子也要打狗棍 专题", @"九寨沟地震已致13人死亡 轻伤180人重伤37人", @"中央气象台发布震区未来三天天气预报:阴有雨", @"新疆精河县6.6级地震 已致32伤其中2人重伤", @"销量低迷的锤子手机还值得投资吗?", @"田径世锦赛官方酒店爆发食物中毒:30人受影响"]; hotSearch = @[@"习近平", @"四川", @"九寨沟", @"地震", @"指示", @"天气预报"]; [self.view setBackgroundColor:RGBA(31, 27, 38, 1)]; self.searchController = [[NaviBarSearchController alloc] initWithParentViewCtrl:self]; self.searchController.delegate = self; [self.searchController resetPlaceHolder:@"搜索关键字"]; [self.searchController showFixationSearchCtrl]; self.recentSearchKeys = [NSMutableArray new]; [self initRecentKeywords]; [self.searchController setRecentKeyword:_recentSearchKeys]; CGRect bound = CGRectMake(0, [CustomNaviBarView barSize].height, ScreenWidth, ScreenHeight - [CustomNaviBarView barSize].height); self.searchResultDataSource = [NSMutableArray new]; self.searchResultTableView = [[UITableView alloc] initWithFrame:bound style:UITableViewStylePlain]; self.searchResultTableView.delegate = self; self.searchResultTableView.dataSource = self; [self.searchResultTableView setSeparatorStyle:UITableViewCellSeparatorStyleNone]; self.searchResultTableView.hidden = YES; [self.searchResultTableView setBackgroundColor:[UIColor clearColor]]; [self.view addSubview:self.searchResultTableView]; self.noSearchResultView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 120, 120)]; [self.noSearchResultView setBackgroundColor:[UIColor clearColor]]; UIImageView *noResultIcon = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"no_searchresult"]]; [self.noSearchResultView addSubview:noResultIcon]; noResultIcon.center = CGPointMake(60, 48); UILabel *noSearchResultTip = [[UILabel alloc] init]; [noSearchResultTip setBackgroundColor:[UIColor whiteColor]]; [noSearchResultTip setTextAlignment:NSTextAlignmentCenter]; [noSearchResultTip setText:@"抱歉,好像什么都没有..."]; [noSearchResultTip setTextColor:[UIColor whiteColor]]; [self.noSearchResultView addSubview:noSearchResultTip]; noSearchResultTip.center = CGPointMake(60, 108); [self.searchResultTableView addSubview:self.noSearchResultView]; self.noSearchResultView.center = CGPointMake(ScreenWidth/2, 150); self.noSearchResultView.hidden = YES; //初始化热搜榜 [self.searchController setHotSearchKeys:hotSearch]; } - (void)viewWillAppear:(BOOL)animated{ [_searchController startSearch]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)initRecentKeywords{ NSFileManager *fileManager = [NSFileManager defaultManager]; NSArray *Paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [Paths objectAtIndex:0]; NSString *path = [documentsDirectory stringByAppendingPathComponent:@"recentkeywords.json"]; if(![fileManager fileExistsAtPath:path]){ [self.recentSearchKeys addObjectsFromArray:@[]]; NSData *jsonData = [self.recentSearchKeys JSONData]; if(jsonData){ [jsonData writeToFile:path atomically:YES]; } } NSData *jsonData = [[NSFileManager defaultManager] contentsAtPath:path]; NSArray *list = [jsonData objectFromJSONData]; [self.recentSearchKeys addObjectsFromArray:list]; } #pragma mark - table delegate - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ if(tableView == _searchResultTableView){ if(_searchResultDataSource){ return _searchResultDataSource.count; } } return 0; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ SearchResultCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SearchResultCell"]; if(!cell){ cell = [[SearchResultCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"SearchResultCell"]; [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; } if(!_searchResultDataSource || [_searchResultDataSource count] == 0) return cell; NSString *strResult = [_searchResultDataSource objectAtIndex:indexPath.row]; [cell.result setText:strResult]; return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ //跳转到指定页面 } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 55.0f; } #pragma mark -NaviBarSearchControllerDelegate - (void)naviBarSearchCtrl:(NaviBarSearchController *)ctrl searchKeyword:(NSString *)strKeyword{ if (strKeyword && strKeyword.length > 0) { if(![_recentSearchKeys containsObject:strKeyword]){ [_recentSearchKeys addObject:strKeyword]; } [_searchController setRecentKeyword:_recentSearchKeys]; [_searchResultDataSource removeAllObjects]; [_searchResultTableView reloadData]; for (int index = 0; index < [data count]; index++) { NSString *strValue = [data objectAtIndex:index]; if([strValue containsString:strKeyword]){ [_searchResultDataSource addObject:strValue]; } } [_searchResultTableView setHidden:NO]; if([_searchResultDataSource count] > 0){ [_noSearchResultView setHidden:YES]; }else{ [_noSearchResultView setHidden:NO]; } [_searchResultTableView reloadData]; NSData *jsonData = [_recentSearchKeys JSONData]; NSArray*paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); NSString*documentsDirectory =[paths objectAtIndex:0]; NSString*path =[documentsDirectory stringByAppendingPathComponent:@"recentkeywords.json"]; [jsonData writeToFile:path atomically:YES]; } } - (void)naviBarSearchCtrlCancel:(NaviBarSearchController *)ctrl{ [self.navigationController popViewControllerAnimated:YES]; } - (void)naviBarSearchCtrlClearKeywordRecord:(NaviBarSearchController *)ctrl{ [_searchController setRecentKeyword:nil]; [_recentSearchKeys removeAllObjects]; NSData *jsonData = [_recentSearchKeys JSONData]; NSArray*paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); NSString*documentsDirectory =[paths objectAtIndex:0]; NSString*path =[documentsDirectory stringByAppendingPathComponent:@"recentkeywords.json"]; [jsonData writeToFile:path atomically:YES]; } - (void)naviBarSearchCtrlStartSearch:(NaviBarSearchController *)ctrl{ [_searchResultTableView setHidden:YES]; } - (void)naviBarSearchCtrl:(NaviBarSearchController *)ctrl clickHotSearchKey:(NSString*)searchKey{ } - (void)naviBarSearchCtrlRefreshHotSearchKey:(NaviBarSearchController *)ctrl{ } - (void)naviBarSearchCtrl:(NaviBarSearchController *)ctrl RemoveSearchRecord:(NSString*)searchRecord{ [_recentSearchKeys removeObject:searchRecord]; [_searchController setRecentKeyword:_recentSearchKeys]; NSData *jsonData = [_recentSearchKeys JSONData]; NSArray*paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); NSString*documentsDirectory =[paths objectAtIndex:0]; NSString*path =[documentsDirectory stringByAppendingPathComponent:@"recentkeywords.json"]; [jsonData writeToFile:path atomically:YES]; } @end
总结
我们这个搜索的功能,主要包括了自定义的搜索栏,热搜榜,搜索历史等功能,所以在编写这样的功能时就要注意要去有效的管理好我们的数据,争取要把接口做到高内聚低耦合;另外,自定义控件的好处就是我们可以写出我们自己想要的效果,能不用官方的就尽量自己写吧!好了,今天的文章就到这里了,谢谢!
附上GitHub地址:https://github.com/ShenJieSuzhou/CoolFrame
好了。祝大家生活愉快。多多收获友谊和爱情。如果想获取更多的讯息,请扫描下方二维码关注我的微信公众号:
相关文章推荐
- iOS开发之旅(1):实现一个APP界面框架
- iOS开发之使用UICollectionView实现美团App的分类功能【偶现大众点评App的一个小bug】
- iOS开发之使用UICollectionView实现美团App的分类功能【偶现大众点评App的一个小bug】
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- iOS开发UI基础—23使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
- iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- ioS开发之UI基础--使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
- ios开发UI基础—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
- C# 优化基于插件的开发框架实现Ribbon界面与功能的分离附DEMO
- iOS开发使用Picker View实现一个图片浏览的App
- 从今天开始学习iOS开发(iOS 7版)--实现一款App之Foundation框架的使用
- iOS开发UI基础—24使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- ios开发:怎么实现点击一个按钮,跳转到一个新的界面
- 实现一个录音播放功能的app(ios)
- iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
- iOS开发之UI基础--纯代码自定义UItableviewcell实现一个简单的微博界面布局
- 一个功能,两个平台,三种语言 -(iOS,Swift,Android)App代码实现对比篇