? ? ? 前段時間由于公司需求,恰好需要做一個CollectionView的Item長按后抖動并且可移動效果。但由于一些原因度陆,當(dāng)時并沒有來得及去處理,所以一直心有遺憾献幔。目前市場上此功能并不少見懂傀,而且在github上也有一些類似的開源代碼,所以其實(shí)總結(jié)來說:首先并不能作為一個功能難點(diǎn)蜡感,只能說是興趣至此蹬蚁;其次也是真心希望能幫助一些我能幫助的人,以及希望大家能給些建議郑兴。都說不想當(dāng)將軍的士兵不是好士兵犀斋,所以我覺得,不能溜溜的馬始終都是騾子...嘿嘿...回歸正題...(可以復(fù)制此鏈接瀏覽器下載demo? http://git.oschina.net/JHissuperman/CollectionView)
1.首先是UICollectionView的創(chuàng)建:
//創(chuàng)建一個layout布局類
UICollectionViewFlowLayout* layout = [[UICollectionViewFlowLayout alloc]init];
//設(shè)置布局方向?yàn)榇怪绷鞑季?/p>
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
//設(shè)置每個item的大小為127.5*127.5
layout.itemSize = CGSizeMake(114*kWidth/750.00, 114*kWidth/750.00);
//整體view據(jù)上左下右距離
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;
//創(chuàng)建collectionView 通過一個布局策略layout來創(chuàng)建
_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類型 這里使用系統(tǒng)的類型
[_vibrate registerClass:[VibrateCollectionViewCell class] forCellWithReuseIdentifier:@"vibrate"];
[self.view addSubview:_vibrate];
2.然后實(shí)現(xiàn)collectionview的代理方法:
//返回分區(qū)個數(shù)
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
//返回每個分區(qū)的item個數(shù)
-(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:)];
}
//長按響應(yīng)時間
_recognize.minimumPressDuration = 1;
[_vibrate addGestureRecognizer:_recognize];
}
- (void)longPress:(UILongPressGestureRecognizer *)longGesture {
//判斷手勢狀態(tài)
switch (longGesture.state) {
case UIGestureRecognizerStateBegan:{
//判斷手勢落點(diǎn)位置是否在路徑上
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];
}
}
//這個參數(shù)的理解比較復(fù)雜杈笔,我的理解是所在layer的時間與父layer的時間的相對速度闪水,為1時兩者速度一樣,為2那么父layer過了一秒蒙具,而所在layer過了兩秒(進(jìn)行兩秒動畫),為0則靜止球榆。
- (void)pause:(VibrateCollectionViewCell*)cell {
cell.layer.speed = 0.0;
}
- (void)resume:(VibrateCollectionViewCell*)cell {
cell.layer.speed = 1.0;
}
- (void)shakeImage:(VibrateCollectionViewCell*)cell {
//創(chuàng)建動畫對象,繞Z軸旋轉(zhuǎn)
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
//設(shè)置屬性,周期時長
[animation setDuration:0.08];
//抖動角度
animation.fromValue = @(-M_1_PI/2);
animation.toValue = @(M_1_PI/2);
//重復(fù)次數(shù)禁筏,無限大
animation.repeatCount = HUGE_VAL;
//恢復(fù)原樣
animation.autoreverses = YES;
//錨點(diǎn)設(shè)置為圖片中心持钉,繞中心抖動
cell.layer.anchorPoint = CGPointMake(0.5, 0.5);
[cell.layer addAnimation:animation forKey:@"rotation"];
}
3.2 移動手勢的添加
- (void)addLongGesture{
//此處給其增加長按手勢,用此手勢觸發(fā)cell移動效果
if(!_longGesture){
_longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handlelongGesture:)];
}
_longGesture.minimumPressDuration = 0;
[_vibrate addGestureRecognizer:_longGesture];
}
//監(jiān)聽手勢篱昔,并設(shè)置其允許移動cell和交換資源
- (void)handlelongGesture:(UILongPressGestureRecognizer *)longGesture {
//判斷手勢狀態(tài)
switch (longGesture.state) {
case UIGestureRecognizerStateBegan:{
//判斷手勢落點(diǎn)位置是否在路徑上
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;//第一個不可移動? 個人限制
}
//移動過程當(dāng)中隨時更新cell位置
[_vibrate updateInteractiveMovementTargetPosition:[longGesture locationInView:_vibrate]];
break;
}
case UIGestureRecognizerStateEnded:
//移動結(jié)束后關(guān)閉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數(shù)據(jù)
id objc = [_collectionArr objectAtIndex:sourceIndexPath.item];
//從資源數(shù)組中移除該數(shù)據(jù)
[_collectionArr removeObject:objc];
//將數(shù)據(jù)插入到資源數(shù)組中的目標(biāo)位置上
[_collectionArr insertObject:objc atIndex:destinationIndexPath.item];
//? ? [_vibrate reloadData];
}
具體效果? 可以復(fù)制此鏈接瀏覽器下載demo? http://git.oschina.net/JHissuperman/CollectionView
希望能幫助到一些人每强,也希望大家能夠指正一些問題。請大家多多留言發(fā)表意見州刽。
(開源中國http://my.oschina.net/JHissuperman/blog/745064)