目次

プロパティ

編集中も選択可能にする

  • IBを使う場合は"Allow Selection While Editing"にチェックを入れる。

セパレータのスタイルを設定する

セパレータを表示しない

	self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

行の更新

個別の行/セルを更新する方法

cell.textLabel.textにセットする

[cell setNeedsLayout]する

  • カスタムセルで、layoutSubviewsを使ってレイアウトしている場合、setNeedsLayoutを呼び出せばlayoutSubviewsが呼ばれることになり結果として行が更新される。

reloadRowsAtIndexPaths:withRowAnimation:を使う

  • これが正式?
  • 複数行をいっぺんに更新するときはこれが簡単

UIViewControllerで使う

  • UITableViewだけじゃなくボタンなども表示したい場合、UITableViewControllerじゃなく、UIViewController+UITableViewという構成になる。
  • UITableViewControllerを使わないでテーブルビューを使うとき実装すべきメソッド - 24/7 twenty-four seven」にあるように単にUITableViewDelegateを実装するだけじゃだめでさらにメソッドを追加しないとだめ。その辺はAppleのガイドラインに書かれている(https://developer.apple.com/jp/devcenter/ios/library/documentation/TableView_iPhone.pdf)。画面が表示されたときにスクロールバーをフラッシュさせるなどの動作が必要らしい。
    注: 管理対象のビューが複数のサブビューで構成されており、その中の1つがTableViewの場合は、
    Table Viewを管理するためにはUITableViewControllerのサブクラスではなく、UIViewController
    のサブクラスを使用すべきです。UITableViewControllerクラスのデフォルトの動作では、Navigation
    BarとTab Barの間の(これら両方が存在する場合)画面一杯にTable Viewを表示します。
    UITableViewControllerのサブクラスではなくUIViewControllerのサブクラスを使用してTable
    Viewを管理することにした場合は、ヒューマンインターフェイスガイドラインに適合するように、
    前述のいくつかのタスクを実行する必要があります。Table Viewを表示する前にTable View内の選択
    をクリアするために、deselectRowAtIndexPath:animated:を呼び出して選択中の行(存在する場
    合)をクリアするviewWillAppear:メソッドを実装します。Table Viewの表示が完了したら、Table
    ViewにflashScrollIndicatorsメッセージを送信することでScroll Viewのスクロールインジケータ
    を点滅させなければなりません。それには、UIViewControllerのviewDidAppear:メソッドをオー
    バーライドします。
    
  • 具体的には以下のメソッドを追加する。
    // The following three methods must be implented in a UIViewController
    // that manages a UITableView but which isn't a UITableViewController
    //	==============================================================
    //	setEditing:animated:
    //	==============================================================
    
    - (void)setEditing:(BOOL)editing animated:(BOOL)animated
    {
    	[super setEditing:editing animated:animated];
    	[self.tableView setEditing:editing animated:animated];
    }
    
    //	==============================================================
    //	viewWillAppear:
    //	==============================================================
    
    - (void)viewWillAppear:(BOOL)animated
    {
    	// Unselect the selected row if any
    	NSIndexPath*	selection = [self.tableView indexPathForSelectedRow];
    	if (selection)
    		[self.tableView deselectRowAtIndexPath:selection animated:YES];
    
    	[self.tableView reloadData];
    }
    
    //	==============================================================
    //	viewDidAppear:
    //	==============================================================
    
    - (void)viewDidAppear:(BOOL)animated
    {
    	//	The scrollbars won't flash unless the tableview is long enough.
    	[self.tableView flashScrollIndicators];
    }
    
    - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
    {
    	[self.tableView flashScrollIndicators];
    }
    
  • ただviewWillAppearで常にreloadしているので、UITableViewControllerは何をやっているか « Programmer’s Highで描かれているようにreloadしたかどうかをフラグで判定するようにしたほうがいいかもしれない。

Tips

キーボードを閉じる

UITextFieldを使っている場合

  • セルにUITextFieldをのせているときは、textFieldShouldReturnで処理することができる。
    - (BOOL)textFieldShouldReturn:(UITextField *)textField {
        [textField resignFirstResponder];
        return YES;
    }
    
    
  • 背景をタッチして閉じる
  • iphone - Dismiss keyboard by touching background of UITableView - Stack Overflow
    UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
    [self.tableView addGestureRecognizer:gestureRecognizer];
    - (void) hideKeyboard {
        [textField1 resignFirstResponder];
        [textField2 resignFirstResponder];
        ...
        ...
    }
    

トラブルシューティング

NSRangeExceptionが発生する

tableViewでinsertRowsAtIndexPathsとdeleteRowAtIndexPathsを実行。

		[self.tableView beginUpdates];
		[self.tableView insertRowsAtIndexPaths:insertPaths withRowAnimation:UITableViewRowAnimationTop];
		[self.tableView deleteRowsAtIndexPaths:deletePaths withRowAnimation:UITableViewRowAnimationNone];
		[self.tableView endUpdates];			

エラーが発生。

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSMutableIndexSet addIndexesInRange:]: Range {2147483647, 1} exceeds maximum index value of NSNotFound - 1' [#vc4d76e4]

エラーメッセージの意味が分かりづらいが、indexPathがおかしいことが原因だった。beginUpdateとendUpdateで囲んで実行する場合、追加・削除前に存在するセクション、行を指定してNSIndexPathをつくらないといけない。そこを間違えていないか確認する。

行を更新しようとしてNSInternalInconsistencyExceptionが発生。

  • 行を追加後VisibleCellsを更新するコードでエラーが発生する。更新前と更新後で行数が一致してないとだめらしい。
    - (void)updateVisibleCells
    {
        NSMutableArray *indexPathes = [NSMutableArray arrayWithObjects:nil];
        for (UITableViewCell *cell in self.tableView.visibleCells)
        {
            NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
            [indexPathes addObject:indexPath];
        }
        [self.tableView reloadRowsAtIndexPaths:indexPathes withRowAnimation:UITableViewRowAnimationNone];
    }
    
    
  • エラーメッセージは以下のようなもの。
    *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (3) must be equal to the number of rows contained in that section before the update (2), plus or minus the number of rows inserted or deleted from that section (2 inserted, 2 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
    
  • reloadDataするかinsertRowsAtIndexPathとかしないとだめぽい。

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-04-13 (水) 16:48:05