关于 控件抖动以及 互换位置的说写

2024-06-18 22:08
文章标签 位置 控件 抖动 互换

本文主要是介绍关于 控件抖动以及 互换位置的说写,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

    前段时间由于公司需求,恰好需要做一个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://www.chinasem.cn/article/1073187

相关文章

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

POJ1269 判断2条直线的位置关系

题目大意:给两个点能够确定一条直线,题目给出两条直线(由4个点确定),要求判断出这两条直线的关系:平行,同线,相交。如果相交还要求出交点坐标。 解题思路: 先判断两条直线p1p2, q1q2是否共线, 如果不是,再判断 直线 是否平行, 如果还不是, 则两直线相交。  判断共线:  p1p2q1 共线 且 p1p2q2 共线 ,共线用叉乘为 0  来判断,  判断 平行:  p1p

lvgl8.3.6 控件垂直布局 label控件在image控件的下方显示

在使用 LVGL 8.3.6 创建一个垂直布局,其中 label 控件位于 image 控件下方,你可以使用 lv_obj_set_flex_flow 来设置布局为垂直,并确保 label 控件在 image 控件后添加。这里是如何步骤性地实现它的一个基本示例: 创建父容器:首先创建一个容器对象,该对象将作为布局的基础。设置容器为垂直布局:使用 lv_obj_set_flex_flow 设置容器

Linux Centos 迁移Mysql 数据位置

转自:http://www.tuicool.com/articles/zmqIn2 由于业务量增加导致安装在系统盘(20G)磁盘空间被占满了, 现在进行数据库的迁移. Mysql 是通过 yum 安装的. Centos6.5Mysql5.1 yum 安装的 mysql 服务 查看 mysql 的安装路径 执行查询 SQL show variables like

PDFQFZ高效定制:印章位置、大小随心所欲

前言 在科技编织的快节奏时代,我们不仅追求速度,更追求质量,让每一分努力都转化为生活的甜蜜果实——正是在这样的背景下,一款名为PDFQFZ-PDF的实用软件应运而生,它以其独特的功能和高效的处理能力,在PDF文档处理领域脱颖而出。 它的开发,源自于对现代办公效率提升的迫切需求。在数字化办公日益普及的今天,PDF作为一种跨平台、不易被篡改的文档格式,被广泛应用于合同签署、报告提交、证书打印等各个

小程序button控件上下边框的显示和隐藏

问题 想使用button自带的loading图标功能,但又不需要button显示边框线 button控件有一条淡灰色的边框,在控件上了样式 border:none; 无法让button边框隐藏 代码如下: <button class="btn">.btn{border:none; /*一般使用这个就是可以去掉边框了*/} 解决方案 发现button控件有一个伪元素(::after

MFC中Spin Control控件使用,同时数据在Edit Control中显示

实现mfc spin control 上下滚动,只需捕捉spin control 的 UDN_DELTAPOD 消息,如下:  OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult) {  LPNMUPDOWN pNMUpDown = reinterpret_cast(pNMHDR);  // TODO: 在此添加控件通知处理程序代码    if

MFC 控件重绘(2) NM_CUSTOMDRAW, WM_DRAWITEM, 虚函数DrawItem

控件重绘有三种方法: 1 设定界面属性 2 利用Windows的消息机制,通过Windows消息映射(Message Mapping)和反映射(Message Reflecting),在合适的时机修改控件的状态和行为。此方式涉及NM_CUSTOMDRAW和WM_DRAWITEM 3 利用虚函数机制,重载虚函数。即DrawItem虚函数。 对于NM_CUSTOMDRAW,某些支持此消息的控件

C# 通过拖控件移动窗体

目录 引言一、通过控件事件移动窗体1、创建窗体界面2、添加控件事件3、添加代码 二、通过windowsAPI移动窗体1、 构建窗体和添加事件2、代码展示 引言 在C#Form窗体设计中,如果我们不需要使用默认边框设计自己个性化的窗体(FromBorderStyle=none时),这时候你会发现拖动窗体的功能就没有了,这里需要自己构建方法让用户可以拖动整个窗体,这里我们使用前辈的

Qt-常用控件(3)-多元素控件、容器类控件和布局管理器

1. 多元素控件 Qt 中提供的多元素控件有: QListWidgetQListViewQTableWidgetQTableViewQTreeWidgetQTreeView xxWidget 和 xxView 之间的区别,以 QTableWidget 和 QTableView 为例. QTableView 是基于 MVC 设计的控件.QTableView 自身不持有数据,使用 QTab