カスタムセルを使ったTableViewで画像とラベルを並べて表示

この記事について

環境Xcode、Objective-C、Storyboard
目的画像の高さはそのままで、ラベルだけ文字量に応じて高さを変えるセルを作る
結果viewWithTagで画像とラベルを設定し、sizeToFit+heightForRowAtIndexPathで実現

つまずきポイント要約

  • sizeToFitはAutoLayoutが有効だと機能しない。セルのAutoLayoutをオフにする
  • 「Need constraints for: Y position」エラーは制約未設定。add missing constraintsで解消できる

TableViewCellに画像とラベルを単純に並べて表示するだけなら、Object libraryからImage view と Label をドラッグ&ドロップするだけでいい。

(↑これをして「Need constraints for. Y position」のようなエラーが出たら、「制約」が設定されていないということなので、Auto Layout を解除するか、シーンの右下にある「Resolve Auto Layout Issues」から「add missing constraints」を実行するといい)

ただし、これだと画像とラベルの高さは同じになる。ラベルに複数行の渡る文字列を表示しようとすると、セルの高さが高くなって、画像の高さまで変わってしまう。

今回自分がやりたいことは、画像の高さはそのままで、ラベルのみ文字列の量に比例して高さを上げるという表示の仕方。

以下はその手順。

1.TableView を使うための下準備をする

1.ストーリーボードで、 Table View を ViewController にドラッグして、プロトコルの実装先である ViewController に dataSource と delegate を設定する。

2.プロトコルを実装する。

ViewController.m (h) 内に記述

//プロトコルを実装
@interface ViewController () <UITableViewDataSource, UITableViewDelegate>

@end

3.セルの表示以外のプログラムをいろいろ記述する

2.テーブルビューにテーブルビューセルを追加し、ID を設定する

1.ストーリーボードで、テーブルビューに UITableViewCell をドラッグ&ドロップする。

2.追加したセルにセルIDを「myCell」と設定する。

3.追加したセルの中にImage View と Label を追加する

1.Object Library 内になる Image View と Label をセルの中に並べて配置する。各オブジェクトのサイズ調整も行う。

2.それぞれの tag に、「1」「2」と設定する。

3.Label の numberOfLines を「0」にして、複数行表示を有効にする。

4.プログラムを作る

ViewController.m 内に記述

//セクション数
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return  2;
}


//行数
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 5;
}


//表示するセル
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    //セルIDを myCell と設定したセルを使う
    NSString *cellIdentifier = @"myCell";
    
    //カスタムセルを準備する
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    
    if (cell == nil) {
        cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    }
        
        //tag番号1のImagaViewに画像を設定する
        UIImageView *imgView = (UIImageView *)[cell viewWithTag:1];
        //Supporting Files に sample.jpg という画像データを入れておく
        UIImage *img = [UIImage imageNamed:@"sample.jpg"];
        imgView.image = img;

    
        //tag番号2のラベルに文字を設定する
        UILabel *label2 = (UILabel *)[cell viewWithTag:2];
        label2.text = [NSString stringWithFormat:@"%ld行目", (long)indexPath.row];

        //表示する文字列にフィットするようにラベルを伸縮させる
        [label2 sizeToFit];

        return cell;
    
}

sizeToFit を有効にするために、セルの AutoLayout をオフにすること!

5.各行の高さを個別に計算して決める

//各行の高さを決めるメソッド
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    //表示したい文字列。この文字列が表示できるだけ、セルの高さを確保する
    NSString * text = [NSString stringWithFormat:@"%ld行目", (long)indexPath.row];
    
    //表示最大幅と高さ
    CGSize maxSize = CGSizeMake(200, CGFLOAT_MAX);
    
    //表示するフォントのサイズ
    NSDictionary *attr = @{NSFontAttributeName: [UIFont boldSystemFontOfSize:17.0]};
    
    //以上を踏まえた上で、表示に必要なサイズ
    CGSize modifiedSize = [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attr context:nil].size;
    
    //上下10pxずつの余白を加えたものと70pxのうち、大きい方を返す
    return MAX(modifiedSize.height + 20, 70);
}

UITableViewAutomaticDimension を使えばもっと簡単にセルの高さは決められるらしい。

以上。

実行して動作を確認。セルの高さが伸縮しない場合は、AutoLayout がオフになっているか確認する。sizeToFit は、AutoLayout が有効だと機能しないよう。

参考:こちらおよび、iPhoneアプリ開発の教科書 P.364~

関連記事

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