iOS9.0之後,UICollectionView多了兩個代理方法,可以通過這倆個方法來對其上的item進行移動編輯,本文主要說下移動功能,移動前加了個抖動手勢(類似APP删除時的抖動效果),然後拖動改變item的位置
- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(9_0);
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPathNS_AVAILABLE_IOS(9_0);
9.0 之前的系統不可用,不過現在應該很少有9.0之前的系統了吧。
項目demo連結:https://github.com/SunshineTraveller/LMEditItemDemo 覺得可以的給個星,QQQ
因為項目的原因,用到了這個,是以才有了本文;
在我們的項目中有這樣一個需求,首頁界面有三個子產品,子產品裡有不同内容,可通過另外一個編輯界面對首頁三個子產品裡内容的排列順序進行編輯,編輯界面長按内容開始抖動,然後進行拖拽就行排序,重新排序後,傳回首頁,首頁順序改變,并且預設第一個内容不可改變(即房源大廳、客戶跟進、我的門戶不可編輯,永遠在第一位),效果圖如下:
1.排序前:
2.自定義應用功能,重新排序,改變資管和二手房等位置(這裡的item其實是抖動的效果,圖檔上看不不出來,可從github上下載下傳demo運作)
3.排序成功傳回首頁,首頁的内容進行了改變,二手房等不見了 替換成新的内容
界面搭建就不多說了,說下主要的方法
-(void)addRecognize {
if (!_recognize) {
_recognize = [[UILongPressGestureRecognizeralloc] initWithTarget:selfaction:@selector(longPressGestureAction:)];
}
_recognize.minimumPressDuration =0.5;
[self.collectionViewaddGestureRecognizer:_recognize];
}
-(void)addLongGesture {
if (_longGesture ==nil) {
_longGesture = [[UILongPressGestureRecognizeralloc] initWithTarget:selfaction:@selector(handlelongGesture:)];
}
_longGesture.minimumPressDuration =0;
[self.collectionViewaddGestureRecognizer:_longGesture];
}
-(void)startLongPress:(WXHome_AllAppCell *)cell {
CABasicAnimation *animation = (CABasicAnimation *)[cell.layeranimationForKey:@"rotation"];
if (animation ==nil) {
[selfshakeImage:cell];
}else{
[selfresume:cell];
}
}
// 複原
-(void)resume:(WXHome_AllAppCell *)cell {
cell.layer.speed =1.0;
}
-(void)shakeImage:(WXHome_AllAppCell *)cell {
CABasicAnimation *animation = [CABasicAnimationanimationWithKeyPath:@"transform.rotation.z"];
[animation setDuration:0.1];
animation.fromValue =@(-M_1_PI/6);
animation.toValue =@(M_1_PI/6);
animation.repeatCount =HUGE_VAL;
animation.autoreverses =YES;
cell.layer.anchorPoint =CGPointMake(0.5,0.5);
[cell.layeraddAnimation:animation forKey:@"rotation"];
}
-(void)longPressGestureAction:(UILongPressGestureRecognizer *)longGesture {
switch (longGesture.state) {
caseUIGestureRecognizerStateBegan: {
// 判斷手勢點是否在路徑上
NSIndexPath *indexPath = [self.collectionViewindexPathForItemAtPoint:[longGesturelocationInView:self.collectionView]];
// 設定房源大廳不可移動
if (indexPath.row >=0) {
_isBegin =YES;
[self.collectionViewremoveGestureRecognizer:_recognize];
[selfaddLongGesture];
[selfaddConfirmBtn]; // 這個是右上角的确定按鈕,點選确定後,取消動畫效果
[self.collectionViewreloadData];
}else {
break;
}
}
break;
caseUIGestureRecognizerStateChanged: {}
break;
caseUIGestureRecognizerStateEnded: {}
break;
default:
break;
}
}
-(void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
if (sourceIndexPath.section ==0) {
id objc = [self.firstArrobjectAtIndex:sourceIndexPath.item];
if (destinationIndexPath.section ==0) {
[self.firstArrremoveObject:objc];
[self.firstArrinsertObject:objc atIndex:destinationIndexPath.item];
}else {
[self.viewaddSubview:[ZLMNoticeLabelmessage:@"隻能在同一功能裡移動哦"delaySecond:2]];
}
}elseif (sourceIndexPath.section ==1) {
id objc = [self.secondArrobjectAtIndex:sourceIndexPath.item];
if (destinationIndexPath.section ==1) {
[self.secondArrremoveObject:objc];
[self.secondArrinsertObject:objc atIndex:destinationIndexPath.item];
}else {
[self.viewaddSubview:[ZLMNoticeLabelmessage:@"隻能在同一功能裡移動哦"delaySecond:2]];
}
}else {
id objc = [self.thirdArrobjectAtIndex:sourceIndexPath.item];
if (destinationIndexPath.section ==2) {
[self.thirdArrremoveObject:objc];
[self.thirdArrinsertObject:objc atIndex:destinationIndexPath.item];
}else {
[self.viewaddSubview:[ZLMNoticeLabelmessage:@"隻能在同一功能裡移動哦"delaySecond:2]];
}
}
}
- (void)handlelongGesture:(UILongPressGestureRecognizer *)longGesture {
staticNSInteger index =0; // 記錄section,防止跨section移動
switch (longGesture.state) {
caseUIGestureRecognizerStateBegan:{
// 通過手勢擷取點,通過點擷取點選的indexPath,移動該item
NSIndexPath *AindexPath = [self.collectionViewindexPathForItemAtPoint:[longGesturelocationInView:self.collectionView]];
if (AindexPath.row >0) {
// 我們項目中第一個item是不允許移動的,是以row從>0 開始,根據實際需求改寫即可
[self.collectionViewbeginInteractiveMovementForItemAtIndexPath:AindexPath];
index = AindexPath.section;
}else{
break;
}
}
break;
caseUIGestureRecognizerStateChanged:{
// 更新移動位置
NSIndexPath *BindexPath = [self.collectionViewindexPathForItemAtPoint:[longGesturelocationInView:self.collectionView]];
if (BindexPath.row<1) {
break;
}else {
// 判斷是否是同一section
if (index == BindexPath.section) {
[self.collectionViewupdateInteractiveMovementTargetPosition:[longGesturelocationInView:self.collectionView]];
}else {
[self.viewaddSubview:[ZLMNoticeLabelmessage:@"隻能在同一功能裡移動"delaySecond:3]];
}
}
break;
}
break;
caseUIGestureRecognizerStateEnded:
// 移動完成關閉cell移動
[self.collectionViewendInteractiveMovement];
break;
default:
[self.collectionViewendInteractiveMovement];
break;
}
}
可從上面的連結下載下傳demo運作,demo中有真實資料,MKNetworkKit網絡請求的封裝,自定義提示框的封裝等,很實用的幹貨!