【Objective-C】tableView reloadData後に行いたい処理を行う方法【Xcode10.1】
こういう人に向けて発信しています。
・reloadData後に行いたい処理がある人
・特定の処理の後に行いたい処理がある人
・Objective-C初心者
私はこういう問題に直面しました。
テーブルリストでフォルダ名を並べており、
tableViewの編集モードをYESにして、
既にお気に入り追加されているフォルダに関しては、
セルを押下しておいてあげるという処理を記載しようと思い、
最初は下記メソッド内に記載しておりました。
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
}
しかし、こちらはセルの再利用時に何度も呼び出される
(初回のみではない)ので、セルが見えなくなると、
再度押下状況をリセットしたにもかかわらず、
描画されておりました。
CODE:Objective-C
#import "ViewController.h"
@interface ViewController ()<UITableViewDelegate,UITableViewDataSource>
@end
@implementation ViewController{
//インスタンス変数の宣言 //これにより、このインスタンスのインスタンスメソッドからアクセスが可能になる。
//各インスタンスメソッドでアクセスする時は tableViewでアクセス可能。
UITableView *tableView;
NSBlockOperation *completionLayoutSubViews; // 終了処理ブロック
}
- (void)viewDidLoad {
[super viewDidLoad];
//tableViewの初期化
//initWithFrame(初期化しつつFrame指定している)
tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height) style:UITableViewStylePlain];
/*
tableViewにはUITableViewDelegate,UITableViewDataSource 2つのデリゲートが存在しており、
「delegateを処理するのはこのインスタンス(self)ですよ」と宣言する必要がある。
*/
tableView.delegate = self;
tableView.dataSource = self;
//このインスタンスのViewにtabelViewを描画する。
[self.view addSubview:tableView];
//編集モードを有効にする。
[tableView setEditing:YES animated:YES];
//編集モードにして複数選択にする。
//左側にチェックマークが出てくる
tableView.allowsMultipleSelectionDuringEditing = YES;
// Viewの更新はメインスレッドで実行
NSLog(@"検証用:tableView reloadData直前");
[tableView reloadData];
//補足:上記をメインスレッドで実行した場合、処理の順番に前後が生じた。
// 終了処理ブロックに、再ロード終了後処理を格納
completionLayoutSubViews = [NSBlockOperation blockOperationWithBlock:^{
/* やりたい処理 */
//編集モード、押下した状況にする。
NSLog(@"検証用:行いたい処理直前");
[tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionNone];
}];
}
// レイアウト後処理
-(void)viewDidLayoutSubviews
{
// 処理ブロックがあれば、実行
if (completionLayoutSubViews) {
[completionLayoutSubViews start];
// 実行後はクリア
completionLayoutSubViews = nil;
}
}
#pragma #UITableView Datasource(実装必須)
//row = 行数を指定するデリゲートメソッド
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//必ずNSInteger型を返してあげている。
NSLog(@"検証用:tableView 描画デリゲートメソッド");
return 30;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//標準で用意されているTableViewを利用する場合。
NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [NSString stringWithFormat:@"このセルは%ld番目のセルになります!", (long)indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"検証用:tableView 謳歌されたrowは %ld",(long)indexPath.row);
}
@end
行いたい処理について
[tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionNone];
本当はfor構文で複雑な処理式書いてますが、
今回は簡略化して2番めのセルを押下させてくことに。
ビルド後の結果
実機でもbuildして確認しましたけど、
問題なかったですね。
スクロールしても再描画される事はありませんでした。
まとめ
TableView編集モードで選択状況をコード側で処理する場合は、
reloadData後に処理してあげた方が良さそう。