【Xcode】UICollectionView で Grid 表示する

この記事について

環境Xcode、Objective-C、Storyboard
目的Grid(格子)状の表示をUICollectionViewで作る
結果UICollectionViewDataSource/Delegateを実装し、セルのタグ経由で画像とラベルを設定して表示できた

つまずきポイント要約

  • storyboard上のオブジェクトにつけたタグとコードのviewWithTagが一致しないと反映されない
  • dataSource・delegate・New Referencing Outletの結線を忘れない

Grid(格子)状の表示は UICollectionView を使うとできる。

参考ページ
https://akira-watson.com/iphone/uicollectionview.html

以下はその手順。

1.storyboard に Collection View を設定する

Object Library から Collection View を選んで、 storyboard の View Controller に配置する。背景が黒で見にくいので、Light Gray に設定。

「View」->「Collection View」にある
「Show the Size inspector」アイコンを選択

例として、Cell を横に3つ入るように
Cell Size を 106 x 106 に
Min Spacing For Lines(セルの間隔)を 1 に
設定します。

参考:セルの間隔

2.Collection View Cell に名前をつけ、UIImageView と Label を配置

配置した Collection View には、すでに Collection View Cell がひとつ設定されているはず。そのCell の Identifier に再利用のためのIDを「Cell」と設定する。さらにその Cell の中に、ライブラリーからUIImageView と Label を持ってきて配置。
UIImageView の Attributes inspector で View Tag を「1」とセット。
Label の Attributes inspector で Tag を「2」とセット。
Label の文字色は白に設定。

3.必要な画像をプロジェクトに追加

photo1.jpg から photo10.jpg の画像を10個用意して「Add Files to “xxx”…」でプロジェクトに追加する。

4.ViewController にコードを記述


ViewController.h

UICollectionViewDataSource, UICollectionViewDelegate を設定

UICollectionViewDataSource → UICollectionViewを利用して表示するデータを提供するためのメソッドを定義するプロトコル。
UICollectionViewDelegate → UICollectionViewに対する選択等の操作を委譲するデリゲートプロトコル。

この二つのプロトコルを実装することで、 Collection View の Connections inspector の Outlets 欄に 「dataSource」「delegate」の二つの項目ができる。

UICollectionViewを構成するクラス

#import <UIKit/UIKit.h>
 
@interface ViewController : UIViewController<UICollectionViewDataSource, UICollectionViewDelegate>

//Assistant editor にして、collectionView オブジェクトをドラッグして作成
@property IBOutlet UICollectionView *collectionView;
 
@end

ViewController.m

#import "ViewController.h"
 
@interface ViewController (){
    NSString *selectedName;
}
 
@end
 
@implementation ViewController
 
- (void)viewDidLoad
{
    [super viewDidLoad];
 
}

//section 数の設定、今回は1つにセット

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}


//item 数、今回は10個

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return 10;
}

 

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


//dequeueReusableCellWithReuseIdentifier の働きは、再利用できるセルがあればそれを使う、再利用できるセルがなければ生成する。

    cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];


//storyboard 上の画像につけたタグに合わせて UIImageView のインスタンスを生成する。タグが一致しないと反映されない。

    UIImageView *imageView = (UIImageView *)[cell viewWithTag:1];
    NSString *imgName = [NSString stringWithFormat:@"photo%d.JPG", (int)(indexPath.row+1)];
    UIImage *image = [UIImage imageNamed:imgName];
    imageView.image = image;


//storyboard 上のラベルにつけたタグに合わせて UILabel のインスタンスを生成する。タグが一致しないと反映されない。

    UILabel *label = (UILabel *)[cell viewWithTag:2];
    label.text = [NSString stringWithFormat:@"No.%d",(int)(indexPath.row+1)];


//背景色の設定。緑。

    cell.backgroundColor = [UIColor greenColor];
    return cell;
}



//おまけ
//アイテムをセレクトした時の起こるイベント
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {

}
 
@end

storyboard に戻って Collection View を選択して右クリック。もしくは右端の Connection inspector を開く。
Outlets 欄の dataSource -> view Controller
Outlets 欄の delegate -> view Controller
New Referencing Outlet -> collectionView
とそれぞれ結ぶ。「dataSource」と「delegate」は UICollectionViewDataSource と UICollectionViewDelegate を実装したことでできたもの。

ビルドして実行。

以上。

配列内の値を表示させる場合は、以下のように変更追加する。

ViewController.m

//配列を作る

@implementation ViewController {

    NSArray *testArray;
  
}

//配列をセット

- (void)viewDidLoad {

    testArray = [NSArray arrayWithObjects:@"うさぎ",@"かめ",@"きじ", nil];

}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    
    
    //return 10;
    //配列の数だけ返す
    return [testArray count];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    UICollectionViewCell *cell;

    cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];

    UILabel *label = (UILabel *)[cell viewWithTag:1];
    //label.text = [NSString stringWithFormat:@"No.%d",(int)(indexPath.row+1)];
label.text = [testArray objectAtIndex:indexPath.row];
    return cell;

}

関連記事

タイトルとURLをコピーしました