美文网首页00『 基础知识 』iOS,object-c和swift开发iOS开发
iOS之UICollectionView的Item长按后抖动并且

iOS之UICollectionView的Item长按后抖动并且

作者: 陌路卖酱油 | 来源:发表于2016-09-10 03:46 被阅读2662次

          前段时间由于公司需求,恰好需要做一个CollectionView的Item长按后抖动并且可移动效果。但由于一些原因,当时并没有来得及去处理,所以一直心有遗憾。目前市场上此功能并不少见,而且在github上也有一些类似的开源代码,所以其实总结来说:首先并不能作为一个功能难点,只能说是兴趣至此;其次也是真心希望能帮助一些我能帮助的人,以及希望大家能给些建议。都说不想当将军的士兵不是好士兵,所以我觉得,不能溜溜的马始终都是骡子...嘿嘿...回归正题...(可以复制此链接浏览器下载demo  http://git.oschina.net/JHissuperman/CollectionView)

    1.首先是UICollectionView的创建:

    //创建一个layout布局类

    UICollectionViewFlowLayout* layout = [[UICollectionViewFlowLayout alloc]init];

    //设置布局方向为垂直流布局

    layout.scrollDirection = UICollectionViewScrollDirectionVertical;

    //设置每个item的大小为127.5*127.5

    layout.itemSize = CGSizeMake(114*kWidth/750.00, 114*kWidth/750.00);

    //整体view据上左下右距离

    layout.sectionInset = UIEdgeInsetsMake(48*kWidth/750.00, 48*kWidth/750.00, 48*kWidth/750.00,48*kWidth/750.00);

    //每个item上下距离

    layout.minimumLineSpacing = 90*kWidth/750.00;

    //每个item左右距离

    layout.minimumInteritemSpacing = 66*kWidth/750.00;

    //创建collectionView 通过一个布局策略layout来创建

    _vibrate = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0*kWidth/750.00, kWidth, kHeight) collectionViewLayout:layout];

    _vibrate.delegate = self;

    _vibrate.dataSource = self;

    _vibrate.backgroundColor = [UIColor lightGrayColor];

    _vibrate.showsHorizontalScrollIndicator = NO;

    _vibrate.showsVerticalScrollIndicator = NO;

    _vibrate.userInteractionEnabled = YES;

    //注册item类型 这里使用系统的类型

    [_vibrate registerClass:[VibrateCollectionViewCell class] forCellWithReuseIdentifier:@"vibrate"];

    [self.view addSubview:_vibrate];

    2.然后实现collectionview的代理方法:

    //返回分区个数

    -(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{

    return 1;

    }

    //返回每个分区的item个数

    -(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{

    return _collectionArr.count;

    }

    //返回每个item

    -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{

    VibrateCollectionViewCell * cell  = [collectionView dequeueReusableCellWithReuseIdentifier:@"vibrate" forIndexPath:indexPath];

    //    [cell sizeToFit];

    if(!cell){

    NSLog(@"-----------");

    }

    NSInteger num = indexPath.row;

    cell.nameLable.text = _collectionArr[num];

    cell.headImageView.image = [UIImage imageNamed:[NSString stringWithFormat:@"00%@",_collectionArr[num]]];

    if(_isBegin == YES ){

    [self starLongPress:cell];

    }

    return cell;

    }

    3.添加手势

    3.1  抖动手势的添加

    - (void)addRecognize{

    //添加长按抖动手势

    if(!_recognize){

    _recognize = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];

    }

    //长按响应时间

    _recognize.minimumPressDuration = 1;

    [_vibrate addGestureRecognizer:_recognize];

    }

    - (void)longPress:(UILongPressGestureRecognizer *)longGesture {

    //判断手势状态

    switch (longGesture.state) {

    case UIGestureRecognizerStateBegan:{

    //判断手势落点位置是否在路径上

    NSIndexPath *indexPath = [self.vibrate indexPathForItemAtPoint:[longGesture locationInView:self.vibrate]];

    if (indexPath.row >= 0) {//第一个不可移动  个人限制

    _isBegin = YES;

    [_vibrate removeGestureRecognizer:_recognize];

    [self addLongGesture];

    [self addSureButton];

    [_vibrate reloadData];

    NSLog(@"1");

    }else{

    break;

    }

    }

    break;

    case UIGestureRecognizerStateChanged:{

    NSLog(@"2");

    break;

    }

    case UIGestureRecognizerStateEnded:

    NSLog(@"3");

    break;

    default:

    NSLog(@"4");

    break;

    }

    }

    //开始抖动

    - (void)starLongPress:(VibrateCollectionViewCell*)cell{

    CABasicAnimation *animation = (CABasicAnimation *)[cell.layer animationForKey:@"rotation"];

    if (animation == nil) {

    [self shakeImage:cell];

    }else {

    [self resume:cell];

    }

    }

    //这个参数的理解比较复杂,我的理解是所在layer的时间与父layer的时间的相对速度,为1时两者速度一样,为2那么父layer过了一秒,而所在layer过了两秒(进行两秒动画),为0则静止。

    - (void)pause:(VibrateCollectionViewCell*)cell {

    cell.layer.speed = 0.0;

    }

    - (void)resume:(VibrateCollectionViewCell*)cell {

    cell.layer.speed = 1.0;

    }

    - (void)shakeImage:(VibrateCollectionViewCell*)cell {

    //创建动画对象,绕Z轴旋转

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];

    //设置属性,周期时长

    [animation setDuration:0.08];

    //抖动角度

    animation.fromValue = @(-M_1_PI/2);

    animation.toValue = @(M_1_PI/2);

    //重复次数,无限大

    animation.repeatCount = HUGE_VAL;

    //恢复原样

    animation.autoreverses = YES;

    //锚点设置为图片中心,绕中心抖动

    cell.layer.anchorPoint = CGPointMake(0.5, 0.5);

    [cell.layer addAnimation:animation forKey:@"rotation"];

    }

    3.2 移动手势的添加

    - (void)addLongGesture{

    //此处给其增加长按手势,用此手势触发cell移动效果

    if(!_longGesture){

    _longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handlelongGesture:)];

    }

    _longGesture.minimumPressDuration = 0;

    [_vibrate addGestureRecognizer:_longGesture];

    }

    //监听手势,并设置其允许移动cell和交换资源

    - (void)handlelongGesture:(UILongPressGestureRecognizer *)longGesture {

    //判断手势状态

    switch (longGesture.state) {

    case UIGestureRecognizerStateBegan:{

    //判断手势落点位置是否在路径上

    NSIndexPath *indexPath = [self.vibrate indexPathForItemAtPoint:[longGesture locationInView:self.vibrate]];

    if (indexPath.row > 0) {//第一个不可移动  个人限制

    [_vibrate beginInteractiveMovementForItemAtIndexPath:indexPath];

    }else{

    break;

    }

    }

    break;

    case UIGestureRecognizerStateChanged:{

    NSIndexPath* indexPath = [_vibrate indexPathForItemAtPoint:[longGesture locationInView:_vibrate]];

    if(indexPath.row<1){

    break;//第一个不可移动  个人限制

    }

    //移动过程当中随时更新cell位置

    [_vibrate updateInteractiveMovementTargetPosition:[longGesture locationInView:_vibrate]];

    break;

    }

    case UIGestureRecognizerStateEnded:

    //移动结束后关闭cell移动

    [_vibrate endInteractiveMovement];

    break;

    default:

    [_vibrate endInteractiveMovement];

    //            [_vibrate cancelInteractiveMovement];

    break;

    }

    }

    - (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath{

    return YES;

    }

    - (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath {

    //取出源item数据

    id objc = [_collectionArr objectAtIndex:sourceIndexPath.item];

    //从资源数组中移除该数据

    [_collectionArr removeObject:objc];

    //将数据插入到资源数组中的目标位置上

    [_collectionArr insertObject:objc atIndex:destinationIndexPath.item];

    //    [_vibrate reloadData];

    }

    具体效果  可以复制此链接浏览器下载demo  http://git.oschina.net/JHissuperman/CollectionView

    希望能帮助到一些人,也希望大家能够指正一些问题。请大家多多留言发表意见。

    (开源中国http://my.oschina.net/JHissuperman/blog/745064)

    相关文章

      网友评论

      • Brade_Tong:为什么第一个不能移动的????
      • 7d0e5c9e8949:适配ios9以前么!大神
      • 陈丽薇:大神,collectionView不同区之间的item可以移动吗

      本文标题:iOS之UICollectionView的Item长按后抖动并且

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