UITableViewの使い方

テーブルデータの再読み込み

データの更新などを行った後、スレッド内で単に

tableView.reloadData()
[(UITableView)tableView reloadData]

とやると落ちてしまう。そこで以下のようなコードを記述することによって、データの再読み込み処理をメインスレッドに戻して処理させるようにする。

dispatch_async(dispatch_get_main_queue(), { () -> Void in
    self.tableView.reloadData()
})
[(UITableView)tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];

また、下記のようにUserDefaultのデータをCellにデータを反映させる場合に、

@IBOutlet weak var label: UILabel!

override func viewWillAppear(animated: Bool) {
        let defaults = NSUserDefaults.standardUserDefaults()
        label.text = defaults.valueForKey("label")! as? String
}

viewWillAppear()でreloadData()しただけでは、うまくテーブルが更新されないので、

override func viewWillAppear(animated: Bool) {
        let defaults = NSUserDefaults.standardUserDefaults()
        label.text = defaults.valueForKey("label")! as? String
        tableView.reloadData()
}

viewDidAppear()でもreloadData()する必要がある。

    override func viewDidAppear(animated: Bool) {
        tableView.reloadData()
    }

セルのハイライトを解除する

UITableViewControllerを使用しない場合、View遷移時のセルハイライトの解除を自分で記述する必要がある

tableView.deselectRowAtIndexPath(tableView.indexPathForSelectedRow, animated: true)
[(UITableView)tableView deselectRowAtIndexPath:[(UITableView)tableView indexPathForSelectedRow] animated:YES];

セル選択時にハイライト表示しない

セルを選択した場合もハイライト表示としない

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
        cell.selectionStyle = UITableViewCellSelectionStyle.None
        return cell
    }

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
	// セル選択時のスタイルを無表示スタイルに設定する
	cell.selectionStyle = UITableViewCellSelectionStyleNone;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
	// セル選択時も非選択状態とする
	[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

セル選択不可

UITableView内全てのセルを選択不可にする

tableView.allowsSelection = false
[(UITableView)tableview setAllowsSelection:NO];

ヘッダビューを追加する

UITableView上部にヘッダビューを追加する

tableView.tableHeaderView = view
(UITableView)tableView.tableHeaderView = (UIView)view;

追加するViewは、ViewcontrollerのサブViewにしない。
文字数に合わせたセルの高さを設定する

セルの高さを設定する

  • テーブル内のUILabelの文字数に合わせてセルの高さを指定する
    - (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath  
    {
    	// セルの取得
    	UITableViewCell *cell = [self tableView:_tableView cellForRowAtIndexPath:indexPath];  
    	// 最大サイズ
    	CGSize bounds = CGSizeMake(_tableView.frame.size.width, _tableView.frame.size.height);
    	// ラベルサイズ
    	CGSize size = [cell.textLabel.text sizeWithFont: cell.textLabel.font
    	constrainedToSize: bounds
    	lineBreakMode: UILineBreakModeCharacterWrap];
    	return size.height;
    }
    

  • セルの高さを自動設定する

    // とりあえず高さを指定
    tableView.estimatedRowHeight = 100
    // 高さを自動指定
    tableView.rowHeight = UITableViewAutomaticDimension
    

プロトタイプセルに含まれる子ビューを指定する

Storyboard上で設定したPrototypeCellに含まれるUIImageViewやUILabelをコード上から指定する場合、それぞれのViewにラベルを付与しておくことで、ラベル番号を指定してViewを取得することが可能である。

Prototype Cells

プロトタイプセル上にUIImageViewを作成し、Tag=1を指定している。

Prototype Cells Property

上記の例で、UIImageViewにSwift上からアクセスする場合は、

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
        let imageView: UIImageView = cell.viewWithTag(1) as! UIImageView
        return cell
    }

とすれば良い。

Pocket