这周做完了任务筛选功能。花了半小时把筛选视图做成了一个小控件方便以后使用。
实际项目效果图如下
开源控件效果
支持手势侧滑,且view的frame和遮罩的alpha值跟随手势变化。
使用非常简单。导入头文件。
#import "SideBarView.h"
类方法调用
[SideBarView show];
筛选列表(FilterConditionView)是我单独封装的一个视图,可以根据项目需要替换自己的视图。其实如果你只需要侧栏滑动效果的视图,用SideBarView即可。
简单说一下代码
基于UIView的基础动画实现视图的淡入淡出效果,并且对子视图和父视图添加手势和KVO监听。
-(void)addSubViews{
[self addSubview:self.coverView];
[self addSubview:self.filterView];
[UIView animateWithDuration:0.25 animations:^{
self.coverView.alpha = 0.4;
self.filterView.x = SCREENW - 300;
}];
//给整个视图添加滑动手势
UIPanGestureRecognizer *pan=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panEvent:)];
pan.delegate = self;
[self addGestureRecognizer:pan];
//给遮罩视图添加轻触手势
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapEvent)];
[self.coverView addGestureRecognizer:tap];
//给筛选视图添加KVO监听其x值的变化
[self.filterView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
}
手势和KVO的监听方法
#pragma mark - private Methods
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{//监听筛选列表的x值变化
if ([keyPath isEqualToString:@"frame"]) {
CGRect new = [change[@"new"] CGRectValue];
CGFloat x = new.origin.x;
if (x < SCREENW) {
self.coverView.alpha = 0.4*(1-x/SCREENW)+0.1;
}else{
self.coverView.alpha = 0.0;
}
}
}
- (void)panEvent:(UIPanGestureRecognizer *)recognizer{//监听手指的移动
CGPoint translation = [recognizer translationInView:self];
if(UIGestureRecognizerStateBegan == recognizer.state || UIGestureRecognizerStateChanged == recognizer.state){
if (translation.x > 0 ) {//右滑
self.filterView.x = SCREENW-300 + translation.x;
}else{//左滑
if (self.filterView.x < SCREENW-300) {
self.filterView.x = self.filterView.x - translation.x;
}else{
self.filterView.x = SCREENW-300;
}
}
}else{
[self tapEvent];
}
}
- (void)tapEvent{//监听手指的轻触
[UIView animateWithDuration:0.25 animations:^{
self.coverView.alpha = 0.0;
self.filterView.x = SCREENW;
} completion:^(BOOL finished) {
[self removeAllSubviews];
[self removeFromSuperview];
}];
}
- (void)removeAllSubviews {
while (self.subviews.count) {
UIView* child = self.subviews.lastObject;
[child removeFromSuperview];
}
}
点击遮罩,或者左右滑动,视图都会自动消失,销毁view无需调用方法,都完全封装了。所有效果的呈现你只需要调用一个show方法即可。
这里的清空指的是清空列表中的所有选中的筛选条件及搜索框输入的关键字,回到一个清零的筛选状态。完成是指根据列表中的所有筛选条件进行筛选。
小小吐槽一下项目需求,虽然控件开发起来非常简单。但是做这个功能却用5个工作日。因为这里的数据处理非常麻烦。一般的多级筛选是交集,我的项目需求居然是并集,筛选条件越多,得出的结果越多,所有符合条件的结果都要展现。并且列出的筛选条件都是当前用户所用到的东西。此外各个筛选条件数据处理起来也非常麻烦。做移动OA开发,最恶心的就是数据处理。很多时候,你会感觉你是在做后台开发.....