【Objective-C】世界で一番簡単にUICollectionViewの並び替えを実行する書き方【Xcode10.2対応】

こういう人に向けて発信しています。
・CollectionViewをアニメーション込みで並び替えてたい人
・並び替える際にCollectionViewの範囲からははみ出して欲しくない人
・Objective-C中級者

アプリイメージ図

構成

・ViewController.h/m/xib
・CustomCell.h/m/xib

ViewController.h/m

//hファイル
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController


@end




//mファイル
#import "ViewController.h"
#import "CustomCell.h"

@interface ViewController ()<UICollectionViewDelegate,UICollectionViewDataSource>
@property (nonatomic) UICollectionView *collectionView;
@property (nonatomic) NSMutableArray *comboArray;  //今回表示している配列(ダミーデータ入れます)
@end

@implementation ViewController


- (void)viewDidLoad {
   [super viewDidLoad];
   self.comboArray = @[@"ライオン",@"トラ",@"チーター",@"サイ",@"ゴリラ",@"ゾウ",@"クワガタ",@"カマキリ",@"バッタ",@"シャチ",@"ウナギ",@"タコ"].mutableCopy;
   
   
   
   [self setCollectionView];
   
   self.collectionView.dataSource = self;
   self.collectionView.delegate = self;
   
   UINib *nib = [UINib nibWithNibName:@"CustomCell" bundle:nil];
   [self.collectionView registerNib:nib forCellWithReuseIdentifier:@"CustomCell"];
   
}


-(void)setCollectionView{
   CGRect rect = CGRectMake(0, self.view.bounds.size.height/2, self.view.bounds.size.width, 120);
   self.collectionView = [[UICollectionView alloc]initWithFrame:rect collectionViewLayout:[self collectionBrank]];
   self.collectionView.backgroundColor = [UIColor whiteColor];
   self.collectionView.bounces = NO;
   [self.view addSubview:self.collectionView];
   
   //ジェスチャーを設定
   UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongGesture:)];
   //長押しのジェスチャーが動作するまでの時間(1.0などにすると1秒間長押ししないと呼び出されなくなる。)
   longPress.minimumPressDuration = 0.3;
   //ジェスチャーをcollectionViewに適用した。
   [self.collectionView addGestureRecognizer:longPress];
   
   
}

-(void)handleLongGesture:(UILongPressGestureRecognizer *)gestureRecognizer{
   
   // UILongPressGestureRecognizerからlocationInView:を使ってタップした場所のCGPointを取得する
   CGPoint selectedCellPoint = [gestureRecognizer locationInView:self.collectionView];

   // 取得したCGPointを利用して、indexPathForRowAtPoint:でタップした場所のNSIndexPathを取得する
   NSIndexPath *selectedCell =  [self.collectionView indexPathForItemAtPoint:selectedCellPoint];
   switch (gestureRecognizer.state) {
       case UIGestureRecognizerStateBegan:
           //移動しはじめた初回1回のみ通る。
           [self.collectionView beginInteractiveMovementForItemAtIndexPath:selectedCell];
           break;
       case UIGestureRecognizerStateChanged:
           //移動し続ける間、通り続ける。
           selectedCellPoint.y = self.collectionView.bounds.size.height/2;  //スクロールビューの高さの中心にしか移動しないように
           [self.collectionView updateInteractiveMovementTargetPosition:selectedCellPoint];
           break;
       case UIGestureRecognizerStateEnded:
           
           [self.collectionView endInteractiveMovement];
           break;
       default:
           [self.collectionView cancelInteractiveMovement];
           break;
   }
}

#pragma mark collectionView load

//collectionViewのレイアウトの諸設定を行う。
- (UICollectionViewFlowLayout *)collectionBrank{
   UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];  //CollectionViewのレイアウトに関するクラスを初期化する
   layout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10);  //itemの余白をセットする。 上、左、下、右の順番
   layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;  //横向きにスクロールできるようにする
   return layout;
}

#pragma mark collectionView DataSource

//セクションの数を決める(itemではない)
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
   return 1;
}

//itemの数を決める
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
   return self.comboArray.count;
}


//itemの中身を返す。
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
   //カスタムセルの場合
   CustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CustomCell" forIndexPath:indexPath];
   cell.cellLabel.text = self.comboArray[indexPath.row];
   return cell;
}


//正常に移動された時のみ動作する(弾き出したりしても動作しない)
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
   NSLog(@"sourceIndexPath_このセルは%ld番目のセルになります!", (long)sourceIndexPath.row);
   NSLog(@"destinationIndexPathこのセルは%ld番目のセルになります!", (long)destinationIndexPath.row);

   NSString *targetString = self.comboArray[sourceIndexPath.row];
   [self.comboArray removeObject:targetString];
   [self.comboArray insertObject:targetString atIndex:destinationIndexPath.row];  //入れ替えではうまくいかなった
}

//itemのサイズを返す
- (CGSize)collectionView:(UICollectionView *)collectionView
                 layout:(UICollectionViewLayout*)collectionViewLayout
 sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
   return CGSizeMake(100, 100);
}

@end


いいなと思ったら応援しよう!