質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.99%

UITableViewのcellForRowAtIndexPathが2回目から呼ばれない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,510

hirahasu

score 108

いつもお世話になっております。

表題の件ですが、一回UITableViewをviewdidlaod内で生成し、値を表示した後に別の関数でもう一度cellに表示する値を取得しなおして一回目に生成したUITableViewを削除し、もう一回UITableViewを生成したいのですが、2回目以降からUITableViewを作成しようとしてもcellForRowAtIndexPathが呼ばれず、作成することができません...

調べてみると、numberOfRowsInSectionの値は0になっているとcellForRowAtIndexPathが呼ばれないとネットに書いてありましたが、NSLogで確認してみたところ、0にはなっていませんでした。

この原因がわかる方おりましたら教えていただけると幸いです。 以上です。 よろしくお願いいたします。

*追記

下記がUITableViewを更新しようとしているコードになります。

hoge.hの中

NSMutableDictionary *m_UserListDict;
@property (retain, nonatomic)NSMutableArray *hoge;
NSString *UserCnt;
NSString *str;
NSMutableArray *val;

hoge.mの中

int iUserCnt;
CGRect listView_windowsize;
float listView_height_windowsize;
float listView_width_windowsize;

- (void)viewDidLoad {  //tableviewの生成

    listView_windowsize = [[UIScreen mainScreen] bounds];
    listView_height_windowsize = listView_windowsize.size.height;
    listView_width_windowsize =  listView_windowsize.size.width;

    listtable = [[UITableView alloc] initWithFrame:[self.view bounds]];
    listtable.frame = CGRectMake(0, 44 , listView_width_windowsize, listView_height_windowsize * 0.8);
    listtable.delegate = self;
    listtable.dataSource = self;
    listtable.allowsMultipleSelection = YES;
    [self.view addSubview:listtable];

}

- (void)OnEnterMember:(const char*)strUserId { //サーバーから通知を受け取る関数(ここも都合上、割愛させてもらってます)

   [self performSelectorOnMainThread:@selector(DisplayList) withObject:nil waitUntilDone:YES]; 

}

-(void)get_data{  //サーバーからxml形式でデータを取得し、格納する。(サーバと通信してる部分等は省略してます)

 m_UserListDict = [[NSMutableDictionary alloc]init];
        [m_UserListDict setDictionary:UserList];
        for (id key in m_UserListDict){
            NSLog(@"%@,%@", key, m_UserListDict[key]);
        }
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView   //セクションの数を返す
{
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section    //cellの数を返す
{

     return self.hoge.count;


}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell;

    static NSString *CellIdentifier = @"Cell";
    cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

    }
    cell.textLabel.text = [self.hoge objectAtIndex:indexPath.row];

    return cell;

}

-(void)DisplayList{

    [self get_data];

    NSLog(@"isMainThread=%@", NSThread.currentThread.isMainThread?@"YES":@"NO");
    str = [[NSString alloc]init];
    val = [[NSMutableArray alloc]init];
    self.userlistarray = [[NSMutableArray alloc]init];
    UserCnt = [m_UserListDict objectForKey:@"UserCnt"];
    iUserCnt      = [UserCnt intValue];

    for ( int i = 0; i < iUserCnt; i++){

        str = [NSString stringWithFormat:@"%d", i];
        val = [[m_UserListDict objectForKey:str] objectForKey:@"name"];
        [self.hoge addObject:val];

    }
     NSLog(@"reloadDataの直前のlisttable=%@", listtable);

        [listtable reloadData];

    NSLog(@"reloadDataの直後のlisttable=%@", listtable);
    userlistcnt = (int)[self.userlistarray count];
}

処理の流れとしてはm_UserListDictの中にあるnameというkeyで保存されている値をvalに入れてそれを self.hogeに入れて最後に[listtable reloadData];を行っている処理になります。 m_UserListDictの中身が空とかいう問題はありませんでした。

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

まず、UITableViewを削除するのはやめましょう。

値を取得しなおした後、

[tableView reloadData];

とすればテーブルが更新されるはずです。


【追記】

サンプルコードです。 セルをタップするとセルが増えていきます。

#import "ViewController.h"

@interface ViewController ()
{
    NSMutableDictionary *m_UserListDict;
    NSString *UserCnt;
    NSString *str;
    NSMutableArray *val;
    int iUserCnt;
    UITableView *listtable;
}
@property (retain, nonatomic)NSMutableArray *hoge;
@end

#define _REUSEID    @"hoge"

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    //テーブル生成
    listtable = [[UITableView alloc] initWithFrame:self.view.frame];
    [self.view addSubview:listtable];
    listtable.dataSource = self;
    listtable.delegate = self;
    [listtable registerClass:UITableViewCell.class forCellReuseIdentifier:_REUSEID];

    //m_UserListDict初期化
    m_UserListDict =
    @{
      @"UserCnt": @"3",
      @"0": @{@"name": @"zero"},
      @"1": @{@"name": @"one"},
      @"2": @{@"name": @"two"},
      }.mutableCopy;
    //NSLog(@"%@", m_UserListDict);

    //hoge初期化
    [self DisplayList];
}

//セル数を返す
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.hoge.count;
}

//セル生成
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //セル取得
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:_REUSEID];
    //セル設定
    cell.textLabel.text = self.hoge[indexPath.row];

    return cell;
}

//セルタップ時に呼ばれる
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //m_UserListDictに追加 (この中はあまり気にしないで下さい)
    {
        //key生成
        NSString *key = @(self.hoge.count).stringValue;
        //obj生成
        NSNumberFormatter *nf = NSNumberFormatter.new;
        nf.locale = [NSLocale localeWithLocaleIdentifier:@"en_US"];
        nf.numberStyle = NSNumberFormatterSpellOutStyle;
        NSString *name = [nf stringFromNumber:@(self.hoge.count)];
        m_UserListDict[key] = @{@"name": name};
        //UserCnt+1
        m_UserListDict[@"UserCnt"] = @([m_UserListDict[@"UserCnt"] integerValue] + 1).stringValue;
    }

    //更新
    [self DisplayList];
}

//hoge更新
//  reloadDataをループの外に出した以外は変更無しです
-(void)DisplayList
{
    str = [[NSString alloc]init];
    val = [[NSMutableArray alloc]init];
    self.hoge = [[NSMutableArray alloc]init];

    UserCnt = [m_UserListDict objectForKey:@"UserCnt"];
    iUserCnt      = [UserCnt intValue];
    NSLog(@"UserCnt=%zd", iUserCnt);

    for ( int i = 0; i < iUserCnt; i++){

        str = [NSString stringWithFormat:@"%d", i];
        val = [[m_UserListDict objectForKey:str] objectForKey:@"name"];
        [self.hoge addObject:val];
    }
    [listtable reloadData];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

@end

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/11 17:50

    viewWillAppear, viewDidAppearでは値は入ってました。
    そして確認したところviewdidloadが二回呼ばれていました....
    viewdidiloadでtableviewを生成しているのでfuzzballさんのおっしゃる通り二回生成していることになってますね...

    キャンセル

  • 2015/12/11 17:57

    2回呼ばれててもnilにはならないような気がするのですが、まぁ何かおかしいのは確かですね。とりえあず、viewDidLoadの頭に、[super viewDidLoad]; を入れておいて下さい。

    キャンセル

  • 2015/12/11 18:06

    はい。ありがとうございます。
    追記しておきます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.99%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる