美文网首页iOS开发(OC)
分析系统搜索框UISearchController

分析系统搜索框UISearchController

作者: 简_爱SimpleLove | 来源:发表于2017-05-20 17:01 被阅读53次

更新搜索的内容

在UISearchControllerDelegate代理方法updateSearchResultsForSearchController中通过以下的代码来实现搜索的数据更新:

- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
   NSString *searchText = searchController.searchBar.text;
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(SELF CONTAINS %@)", searchText];
    filterArr = searchText.length>0?[dataArr filteredArrayUsingPredicate:predicate]:dataArr; //当搜索内容清空后也有内容
    [self.tableView reloadData];
}

结果展示控制器问题

        EOCSearchResultViewCtrl *resultSearchCtrl = [[EOCSearchResultViewCtrl alloc] init];
        _searchCtrl = [[UISearchController alloc] initWithSearchResultsController:resultSearchCtrl];

在初始化UISearchController的时候initWithSearchResultsController如果设置为自己的话,设置成nil就好,不要设置成self,当设置为nil的时候也就是说搜索的结果,会在self中进行展示,当然一般是在self中用tableview进行展示。如果设置为别的控制器,就会展示在别的控制器中,其实也就只是相当于拆分开来罢了。

searchBar的问题

    [self.view addSubview:self.tableView];
    [self.tableView setTableHeaderView:self.searchCtrl.searchBar];

我们将searchBar设置为tableView的头视图,并且当点击搜索框的时候,在UISearchControllerDelegate代理的willPresentSearchController方法和didPresentSearchController方法分别打断点可得以下结果:


以上是打断点过后的图



以上是点击搜索框之前的图


以上是点击搜索框之后的图

从上可以知道当点击了searchBar过后,系统将searchBar取出来移到了导航栏上面,而不再是tableView的头视图,而且点击之前和之后的searchBar是同一个,查看他们的内存地址可以知道。

另外需要注意的点

  • 当使用搜索框的时候最好不要将self.automaticallyAdjustsScrollViewInsets设置为NO,因为会很难调坐标,会出现64px的问题。
  • 搜索框也能添加在scrollView上面
  • searchController必须设置成成员变量,否则只会是添加了一个view上去,而其代理方法那些都不会响应,因为你不设置成成员变量,出了那个方法,你就不释放掉了
  • definesPresentationContext 当SearchResultsController不为nil,即搜索结果在别的控制器展示的时候,需要将definesPresentationContext设置为YES,即表示当UISearchController控制器present到需要展示的目标控制器的时候,可以覆盖当前的控制器,否则当跳到目标控制器时,上面会有一段空白


修改搜索框的一些设置

    //修改背景色
    self.searchCtrl.searchBar.barTintColor = [UIColor yellowColor];
    //修改光标和取消文字颜色
    self.searchCtrl.searchBar.tintColor = [UIColor orangeColor];
    //修改图标
    [self.searchCtrl.searchBar setImage:[UIImage imageNamed:@"voice_gray"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];
    [self.searchCtrl.searchBar setImage:[UIImage imageNamed:@"message_gray"] forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal];
    [self.searchCtrl.searchBar setImage:[UIImage imageNamed:@"message_gray"] forSearchBarIcon:UISearchBarIconClear state:UIControlStateHighlighted];
    // KVC 修改textfield的文字
    UITextField *textField = [self.searchCtrl.searchBar valueForKey:@"_searchField"];
    textField.textColor = [UIColor orangeColor];
    textField.font = [UIFont systemFontOfSize:12.f];
    // KVC 修改textfield的默认提示文字   两级就用keyPath
    [textField setValue:[UIColor redColor] forKeyPath:@"_placeholderLabel.textColor"];
    // KVC 修改searchBar的取消按钮文字   两级就用keyPath
    [self.searchCtrl.searchBar setValue:@"取消" forKey:@"_cancelButtonText"];

上面是使用KVC来进行修改,也可以通过遍历的方法来进行修改,但是进行搜索过后,进入SearchResultsController后就回到了原状。

半定制搜索框

没有实现当点击搜索框的时候,会跳到导航条,但是可以改变textfield的大小,用系统的改变不了。自定义搜索框需要自定义UISearchController和UISearchBar。代码如下:
EOCClassSearchCtl:

#import <UIKit/UIKit.h>
#import "EOCClassSearchBar.h"

@protocol EOCClassSearchCtrlDelegate <NSObject>
- (void)didStartSearching;
- (void)didTapSearchBtn;
- (void)didTapCancelBtn;
- (void)didChangeSearchText:(NSString *)text;
@end

@interface EOCClassSearchCtl : UISearchController
@property(nonatomic, strong)EOCClassSearchBar *classSearchBar;
@property(nonatomic, weak)id <EOCClassSearchCtrlDelegate> classSearchCtrlDelegate;
@end
#import "EOCClassSearchCtl.h"

@interface EOCClassSearchCtl ()<UISearchBarDelegate>
@end

@implementation EOCClassSearchCtl

- (instancetype)initWithSearchResultsController:(UIViewController *)searchResultsController {
    
    if (self = [super initWithSearchResultsController:searchResultsController]) {
    }
    return self;
}

#pragma mark - UISearchBar delegate method
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
    //代理传递方法
    if (_classSearchCtrlDelegate) {
        [searchBar becomeFirstResponder];
        [_classSearchCtrlDelegate didStartSearching];
    }
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    
    if (_classSearchCtrlDelegate) {
        [searchBar resignFirstResponder];
        [_classSearchCtrlDelegate didTapCancelBtn];
    }
}

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
    
    if (_classSearchCtrlDelegate) {
        [_classSearchCtrlDelegate didChangeSearchText:searchText];
    }
}


#pragma mark - getter method
- (EOCClassSearchBar *)classSearchBar {
    
    if (!_classSearchBar) {
        _classSearchBar = [[EOCClassSearchBar alloc] initWithFrame:CGRectMake(0.f, 0.f, self.view.eoc_width, 44.f)];
        _classSearchBar.delegate = self;
    }
    return _classSearchBar;
}

@end

EOCClassSearchBar:
.h里面没有什么东西,.m文件如下:

#import "EOCClassSearchBar.h"

@interface EOCClassSearchBar ()

@property(nonatomic, strong)UITextField *searchTextField;
@property(nonatomic, strong)UIButton *cancelBtn;
@property(nonatomic, strong)UIImageView *searchBarImageView;

@end

@implementation EOCClassSearchBar


- (instancetype)initWithFrame:(CGRect)frame {
    
    if (self = [super initWithFrame:frame]) {
        // 截取手势事件,避免当修改textfield的frame后,点击最左边的区域,也响应了事件
        UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
        [self addGestureRecognizer:tapGesture];
    }
    return self;
}


- (void)tapAction
{
    NSLog(@"%s", __func__);
}
//修改textfield的frame只能在layoutSubviews中
- (void)layoutSubviews {
    [super layoutSubviews];
    // 修改textfield的frame
    self.searchTextField.frame = ({
        CGRect frame = self.searchTextField.frame;
        frame.origin.x = 60.f;
        frame.size.width -= 60.f;
        frame;
    });
}
// 绘制搜索框
- (void)drawRect:(CGRect)rect {
    self.barTintColor = [UIColor orangeColor];
    self.tintColor = [UIColor redColor];
    
    self.showsCancelButton = YES;
    //    self.barTintColor = EOCColor(240, 243, 245);
    [self becomeFirstResponder];
    
    UITextField *textField = self.searchTextField;
    textField.placeholder = @"Search EightClock";
    textField.font = [UIFont systemFontOfSize:12.f];
    textField.backgroundColor = EOCColor(240, 243, 245);
    textField.textColor = [UIColor greenColor];
    textField.textAlignment = NSTextAlignmentLeft;
    
    [self.cancelBtn setTitle:@"取消" forState:UIControlStateNormal];
    [self.cancelBtn addTarget:self action:@selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];
    
    //在搜索框的底部画一条绿线  画线条
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(0.f, self.frame.size.height)];
    [path addLineToPoint:CGPointMake(self.frame.size.width, self.frame.size.height)];
    
    CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
    shapeLayer.path = path.CGPath;
    shapeLayer.strokeColor = [UIColor greenColor].CGColor;
    shapeLayer.lineWidth = 2.5f;
    [self.layer addSublayer:shapeLayer];
    
}

- (void)btnAction:(UIButton *)btn {
    
    self.searchTextField.text = @"";
    // 调用代理,清空搜索内容
    [self.delegate searchBar:self textDidChange:@""];
    
}

#pragma mark - getter method
- (UITextField *)searchTextField {
    
    if (!_searchTextField) {
        for (id view in [[self.subviews lastObject ]subviews]) {
            if ([view isKindOfClass:NSClassFromString(@"UISearchBarTextField")]) {
                _searchTextField = (UITextField *)view;
            }
        }
    }
    
    return _searchTextField;
}

- (UIButton *)cancelBtn {
    
    if (!_cancelBtn) {
        for (id view in [[self.subviews lastObject ]subviews]) {
            if ([view isKindOfClass:NSClassFromString(@"UINavigationButton")]) {
                _cancelBtn = (UIButton *)view;
            }
        }
    }
    
    return _cancelBtn;
}

- (UIImageView *)searchBarImageView {
    if (!_searchBarImageView) {
        for (id view in [[self.subviews lastObject ]subviews]) {
            if ([view isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) {
                _searchBarImageView = (UIImageView *)view;
//                _searchBarImageView.userInteractionEnabled = YES;
            }
        }
    }
    return _searchBarImageView;
}
@end

相关文章

网友评论

    本文标题:分析系统搜索框UISearchController

    本文链接:https://www.haomeiwen.com/subject/lvhnzttx.html