iOS自定义搜索框和历史搜索显示

作者: Maj_sunshine | 来源:发表于2017-09-23 21:25 被阅读2475次

    前言

    搜索框的使用在开发过程中已经是非常见了。现在几乎的app都带有搜索功能。系统给我们提供了搜索框UISeacherBar,但我在用了几次这个发现使用起来不是很方便,很多东西不好扩展。最近开发ipad就改用textField自定义一个SeacherBar ,点击搜索后保存搜索记录到本地,再将历史搜索记录显示。有点儿类似爱奇艺搜索界面。我修改了下布局,在iphone上使用。demo并没有封装太多接口修改属性。要修改可以去各个.m文件中修改。

    这个demo地址

    其实把项目中的功能提出来,也方便我以后查看。或许我以后会笑自己怎么会写成这么low的代码。。哈哈哈。不开玩笑了。

    先看下效果图

    搜索框界面.gif

    主要思路

    上面截屏截的不好。尴尬了旁边都看到了。。

    1 搜索框实现思路

    1. 输入框初始化的配置
    /*! 基础配置 */
    
    - (void)baseSetting{
       /*! 边框处理 */
       _textField.layer.borderColor = ZDGreenColor.CGColor;
       _textField.layer.borderWidth = 1;
       _textField.layer.cornerRadius = self.frame.size.height/2;
       _textField.layer.masksToBounds = YES;
       /*! 字体其他 */
       _textField.font = KweixinFont(14);
       _textField.tintColor = ZDGreenColor;
       _textField.keyboardType = UIKeyboardTypeDefault;
       _textField.delegate =self;
       /*! 设置键盘return样式为搜索样式 */
       _textField.returnKeyType = UIReturnKeySearch;
       /*! 设置为无文字就灰色不可点 */
       _textField.enablesReturnKeyAutomatically = YES;
       /*! 开启系统清除样式 */
       _textField.clearButtonMode = UITextFieldViewModeAlways;
       /*! 添加左边遮盖 */
       [_textField setTextOffsetWithLeftViewRect:CGRectMake(0, 0, leftViewWidth, self.frame.size.height) WithMode:UITextFieldViewModeAlways];
       /*! 编辑事件观察 */
       [_textField addTarget:self action:@selector(textFieldDidEditing:) forControlEvents:UIControlEventEditingChanged];
    }
    

    2 中间默认文字为UILabel,居中,搜索图片在文字左边15的位置
    3 实现的textField代理协议和监听文字改变

    /*! 当输入框开始编辑的时候 */
    - (void)textFieldDidBeginEditing:(UITextField *)textField{
       /*! _placeholderLabel移动到关标右边*/
       [_placeholderLabel mas_updateConstraints:^(MASConstraintMaker *make) {
           make.centerX.mas_equalTo(_textField).offset(-_textField.frame.size.width/2+leftViewWidth+_size.width/2+5);
       }];
       /*! _searchImage移动到关标左边 */
       [_searchImage mas_updateConstraints:^(MASConstraintMaker *make) {
           make.centerX.mas_equalTo(_textField).offset(-_textField.frame.size.width/2-space+leftViewWidth);
       }];
       [UIView animateWithDuration:0.25 animations:^{
    //        执行更新
           [self layoutIfNeeded];
       }];
       
    }
    
    /*! 输入框结束编辑 因为项目里用了IQKeyboardManager 上面有工具栏 如果没成 这个代理方法可以不添加 */
    - (void)textFieldDidEndEditing:(UITextField *)textField{
       if (textField.text.length>0) {
           NSLog(@"进行搜索");
           [_SearchDelegate searchWithStr:textField.text];
       }
    }
    
    /*! 点击键盘搜索按钮的回调 */
    - (BOOL)textFieldShouldReturn:(UITextField *)textField{
       [_textField resignFirstResponder];
       [_SearchDelegate searchWithStr:textField.text];
       NSLog(@"点击了搜索");
       return YES;
    }
    

    这些简单的动画都是通过mas_updateConstraints配合[self layoutIfNeeded],简单又好用的。

    2 历史搜索的实现

    1. 这里主要是UICollectionView的使用 ,主要是UICollectionViewFlowLayout的写法。图中文字阴影部分这时label的背景颜色,其实两个item之间的距离固定只有5 。实现方法
    //设置两个item之间的最小距离固定为5
    self.minimumInteritemSpacing = 5;
    //自己声明两个item之间的最大距离属性maximumInteritemSpacing 通过下面方法设置。
    
    - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
    {
        //使用系统帮我们计算好的结果。
        NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
        
        //第0个cell没有上一个cell,所以从1开始
        for(int i = 1; i < [attributes count]; ++i) {
            //这里 UICollectionViewLayoutAttributes 的排列总是按照 indexPath的顺序来的。
            UICollectionViewLayoutAttributes *curAttr = attributes[i];
            UICollectionViewLayoutAttributes *preAttr = attributes[i-1];
            
            NSInteger origin = CGRectGetMaxX(preAttr.frame);
            //根据  maximumInteritemSpacing 计算出的新的 x 位置
            CGFloat targetX = origin + _maximumInteritemSpacing;
            // 只有系统计算的间距大于  maximumInteritemSpacing 时才进行调整
            if (CGRectGetMinX(curAttr.frame) > targetX) {
                // 换行时不用调整
                if (targetX + CGRectGetWidth(curAttr.frame) < self.collectionViewContentSize.width) {
                    CGRect frame = curAttr.frame;
                    frame.origin.x = targetX;
                    curAttr.frame = frame;
                }
            }
        }
        return attributes;
    }
    

    2 通过上面方法固定左右item间距为5,第二步:根据本地历史搜索的字符串数组计算UICollectionView有多少行。 如果累加的长度大于屏幕宽度,则行数+1

    /*! 历史搜索高度 */
    - (NSInteger)rowForCollection :(NSArray *)array{
        CGFloat width = 0;
        NSInteger row = 1;
        /*! 55为cell额外宽度 +5的边距 */
        for (NSString *str in array) {
            CGSize size = [str boundingRectWithSize:CGSizeMake(1000, 30) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName :KweixinFont(14)} context:nil].size;
            width = width +size.width+55;
            NSLog(@"width = %f",width);
            /*! 减5 时因为最后一个item不需要 + 5的边距 */
            if ((width-5)/(kScreenWidth)>1) {
                row = row+1;
                width =size.width+55 ;
            }
        }
        return row>4?4:row;
    }
    

    我上面的方法可以不好,你也可以通过上面第一个代理里面计算,实现下面方法

    -(CGSize)collectionViewContentSize{
    }
    
    

    直接计算contentsize 。

    3 cell的删除
    我想通过下面的方法添加一个抖动的cell,不过效果不是很好,希望有人能告诉我更好的实现方法

    /*! 添加抖动动画 */
    
    - (void)addShake : (SearchCollectionViewCell *)cell{
        [UIView animateKeyframesWithDuration:0.3 delay:0 options:UIViewKeyframeAnimationOptionRepeat animations:^{
            [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.075 animations:^{
                cell.transform = CGAffineTransformMakeRotation(-8/ 180.0 * M_PI);
            }];
            [UIView addKeyframeWithRelativeStartTime:0.1 relativeDuration:0.15 animations:^{
                cell.transform = CGAffineTransformRotate(cell.transform,16 /180.0 * M_PI);
            }];
            [UIView addKeyframeWithRelativeStartTime:0.2 relativeDuration:0.1 animations:^{
                cell.transform = CGAffineTransformRotate(cell.transform, -8 / 180.0 * M_PI);
            }];
        } completion:nil];
    }
    

    结束啦 这个demo地址 fighting

    相关文章

      网友评论

      • a465b0bc41be:你的github上面的代码运行后不会显示历史搜索的记录?是不是哪里有问题?
        Maj_sunshine:我下载了下 是有显示的 就是一年前的代码不规范了点可能难看

      本文标题:iOS自定义搜索框和历史搜索显示

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