最近做了一个项目要实现类似于手机上应用抖动删除排序的效果,整理出一个思路,先分别实现不同动画效果
首先我定义行列阵的ImageAndTitleView,并且每个ImageAndTitleView分别加上长按手势和拖拽手势,并且记录每个ImageAndTitleView的center,方便排序时使用.代码如下所示:
-(void)setUIwithCount:(NSInteger)count{
float hang = count/4.0;
NSInteger lie = count;
if (hang > count/4) {
hang = count/4+1;
}
if (hang < 1) {
lie = count;
}else{
lie = 4;
}
for (int i = 0; i < hang; i ++) {
for ( int j = 0; j < lie; j++) {
if (i == count/4) {
lie = count%4;
}
JobCollectModel * model = _dataarray[i * 4 + j];
ImageAndTitleView * imti = [[ImageAndTitleView alloc]initWithFrame:CGRectMake(80*j * kWIDTH, 90 *i + 30 * kHeight, 80* kWIDTH, 80 * kHeight)];
imti.backgroundColor = [UIColor whiteColor];
[imti.closeButton addTarget:self action:@selector(removeButtonAction:) forControlEvents:UIControlEventTouchUpInside];
imti.tag = 100 + i * 4 + j;
imti.cunrrentIndex = i * 4 + j;
UILongPressGestureRecognizer * longpress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(doudong:)];
[imti addGestureRecognizer:longpress];
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(enter:)];
[imti addGestureRecognizer:tap];
imti.label.text = [NSString stringWithFormat:@"%@",model.joblistModel.name];
UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(tuodong:)];
[imti addGestureRecognizer:pan];
CGPoint point = CGPointMake(imti.center.x, imti.center.y);
PointModel * pointmodel =[PointModel new];
pointmodel.X = point.x;
pointmodel.Y = point.y;
[_pointArray addObject:pointmodel];
}
}
}
实现效果
1.抖动:长按手势的方法,让所有视图添加抖动的动画效果
-(void)doudong:(UILongPressGestureRecognizer *)sender{
if (sender.state == UIGestureRecognizerStateBegan) {
for (int i = 0; i < _dataarray.count; i ++) {
ImageAndTitleView * title = [self.view viewWithTag:100+i];
self.anim = [CAKeyframeAnimation animation];
_anim.keyPath = @"transform.rotation";
_anim.values=@[@(angelToRandian(-1.5)),@(angelToRandian(1.5)),@(angelToRandian(-1.5))];
_anim.repeatCount = MAXFLOAT;
_anim.duration = 0.2;
[title.layer addAnimation:_anim forKey:nil];
title.actionState = 1;
}
// [self.imageBackView.layer addAnimation:_anim forKey:nil];
}
}
2.排序,排序分为两个动作,一个动作是拖动视图,让视图随着手指移动的轨迹运动,另一个动作是判断和哪个视图交换位置,偏差是多少交换,我这里是用中心点判断,类似于判断一个点是否在圆内,如果当前移动的视图在以某个视图为圆心,一半size为半径的圆内就让它两交换位置,如果没有这样的视图就回到原位,一旦交换成功,视图所代表的数据也要交换,具体代码如下:
-(void)tuodong:(UIPanGestureRecognizer *)senderr{
NSInteger index = senderr.view.tag-100;
ImageAndTitleView * imview = (ImageAndTitleView *)senderr.view;
if (imview.actionState == 0){
return;
CGPoint translation = [senderr translationInView:self.view];
senderr.view.center = CGPointMake(senderr.view.center.x + translation.x,
senderr.view.center.y + translation.y);
//设置随着手指运动
[senderr setTranslation:CGPointZero inView:self.view];
//开始判断是否在某一圆内
if (translation.x == 0&&translation.y == 0) {
for (int i =0; i < _pointArray.count; i ++) {
PointModel * models = _pointArray[i];
double XXX =senderr.view.center.x-models.X;
double YYY =senderr.view.center.y-models.Y;
double distance = sqrt(XXX*XXX + YYY * YYY);
if (distance < 25 * kHeight && index!=i) {
NSInteger viewTag = senderr.view.tag;
senderr.view.center = CGPointMake(models.X, models.Y);
ImageAndTitleView * panview = [self.view viewWithTag:100 + i];
senderr.view.tag = panview.tag;
panview.tag = viewTag;
PointModel * currentmodel = _pointArray[index];
[UIView animateWithDuration:0.3 animations:^{
panview.center = CGPointMake(currentmodel.X, currentmodel.Y);
}];
[self sortAppWithCurrent:index OutData:i];
return;
}
else{
PointModel * currentmodel = _pointArray[index]
senderr.view.center = CGPointMake(currentmodel.X, currentmodel.Y);
}
}
}
}
之后具体逻辑可以自行添加
网友评论