前言
搜索框的使用在开发过程中已经是非常见了。现在几乎的app都带有搜索功能。系统给我们提供了搜索框UISeacherBar,但我在用了几次这个发现使用起来不是很方便,很多东西不好扩展。最近开发ipad就改用textField自定义一个SeacherBar ,点击搜索后保存搜索记录到本地,再将历史搜索记录显示。有点儿类似爱奇艺搜索界面。我修改了下布局,在iphone上使用。demo并没有封装太多接口修改属性。要修改可以去各个.m文件中修改。
这个demo地址
其实把项目中的功能提出来,也方便我以后查看。或许我以后会笑自己怎么会写成这么low的代码。。哈哈哈。不开玩笑了。
先看下效果图
![](https://img.haomeiwen.com/i4288700/d07701c230442192.gif)
主要思路
上面截屏截的不好。尴尬了旁边都看到了。。
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 历史搜索的实现
- 这里主要是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];
}
网友评论