iOS开发之旅(2):实现一个APP界面框架之搜索功能

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shenjie12345678/article/details/77806208

前言

在上一篇博文中,为大家演示了如何去构建完成一个 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


好了。祝大家生活愉快。多多收获友谊和爱情。如果想获取更多的讯息,请扫描下方二维码关注我的微信公众号:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/shenjie12345678/article/details/77806208