2012-06-04 17 views
51

解析されたデータをセルに読み込もうとしていますが、同期が起こっていて、データのロードが完了するまでUitableViewが表示されません。 performSelectorInBackgroundを使用して問題を解決しようとしましたが、スクロールを開始するまでデータはセルにロードされません。ここに私のコードは次のとおりです。スクロールするまでデータがUITableViewにロードされない

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 

    [self performSelectorInBackground:@selector(fethchData) withObject:nil]; 


} 


- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
self.listData = nil; 
    self.plot=nil; 
} 


-(void) fethchData 

{ 
    NSError *error = nil; 
    NSURL *url=[[NSURL alloc] initWithString:@"http://www.website.com/"]; 
    NSString *strin=[[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil]; 

    HTMLParser *parser = [[HTMLParser alloc] initWithString:strin error:&error]; 

    if (error) { 
     NSLog(@"Error: %@", error); 
     return; 
    } 

    listData =[[NSMutableArray alloc] init]; 
    plot=[[NSMutableArray alloc] init]; 

    HTMLNode *bodyNode = [parser body]; 
    NSArray *contentNodes = [bodyNode findChildTags:@"p"]; 


    for (HTMLNode *inputNode in contentNodes) { 
      [plot addObject:[[inputNode allContents] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];  
     } 


    NSArray *divNodes = [bodyNode findChildTags:@"h2"]; 

    for (HTMLNode *inputNode in divNodes) { 

      [listData addObject:[[inputNode allContents] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];   

     } 
    } 


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

    static NSString *CellIdentifier = @"Cell"; 
    //here you check for PreCreated cell. 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 
     cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 

    } 

    //Fill the cells... 


    cell.textLabel.text = [listData objectAtIndex:indexPath.row]; 
    cell.textLabel.font = [UIFont boldSystemFontOfSize:14]; 
    cell.textLabel.numberOfLines=6; 
    cell.textLabel.textColor=[UIColor colorWithHue:0.7 saturation:1 brightness:0.4 alpha:1]; 


    cell.detailTextLabel.text=[plot objectAtIndex:indexPath.row]; 
    cell.detailTextLabel.font=[UIFont systemFontOfSize:11]; 
    cell.detailTextLabel.numberOfLines=6; 

    return cell; 


} 
+0

、残りの細胞はになりますスクロールした後に表示されると読み込まれます。 – rishi

答えて

123

データが正常にロードされた後にどこかこれを置く:

dispatch_async(dispatch_get_main_queue(), ^{ 
    [self.tableView reloadData]; 
}); 

これは、あなたがメインスレッドではありませんしている間、GUIの更新を呼び出すの問題を修正。

このコードでは、AppleのGCD Technologyを使用して、リロードデータ関数をメインスレッドで実行するようにしています。 Concurrency Programming Guideをもっと理解してください(コメントで説明するのはかなり大きなフィールドです) とにかく、まれにプログラムがクラッシュするので、よく理解していないとお勧めできません。

+0

ありがとうございます。私は急いでいくつかのものを移動し、データの読み込みが別のスレッドであったことに気がつかず、したがって私のreloadDataも同様です。私が戻って物事を分析するのを助けてくれてありがとう。 – chadbag

+0

ありがとうございました!これはちょうど私が持っていた本当に迷惑なバグを解決しました。 –

+1

大ヘルプありがとう – Greg

9

あなたが本当にする必要があるすべては、あなたのバックエンドデータへの更新を持っている任意の時間が、これは同期起こっているので、あなたはおそらく持つべき

[tableView reloadData]; 

を呼んで

-(void) updateTable 
{ 
    [tableView reloadData]; 
} 

とあなたのダウンロードのコール

[self performSelectorOnMainThread:@selector(updateTable) withObject:nil waitUntilDone:NO]; 
にデータを追加した後のような関数
+0

これは、コードは例として意図されて、私はあなたのクラスやビュー、レイアウトの正確な構造を知らない – Benjamen

+0

「未知の受信機のtableViewを」と言います。ポイントである、あなたは、テーブルビューへの参照を手に入れる(あなたのクラスはのUITableViewControllerのインスタンスまたはサブクラスであるならば、あなたはself.tableViewをちょうど持っていなければならない)とUITabbleviewControllerでそれ –

+0

に 'reloadData'メソッドを呼び出す必要がありますそれは** self.tableView ** – LavaSlider

1

私はまったく同じ問題を抱えていました!私は、ビューコントローラが登場する前に、UITableViewを完全に配置したかったのです。 Envilのポストは私に必要な情報を私に与えましたが、私の解決策は異なったものになりました。

私は何をしましたか(質問者の文脈に合わせて改造されました)。

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [self performSelectorInBackground:@selector(fethchData) withObject:nil]; 
} 

- (void)viewWillAppear { 
    [tableView reloadData]; 
} 
2

[cell setNeedsDisplay];を使用できます。例えば :

dispatch_async(dispatch_get_main_queue(), ^{ 
      [cell setNeedsDisplay]; 
      [cell.contentView addSubview:yourView]; 
     }); 
1

私はこの問題を抱えていたし、私は一日中、それを扱いました。

スタティックセルを使用していますが、reloadDataが間違った読み込みを引き起こしています。表示されているセルのみが表示され、他のセルは削除されます。 私が気づいたのは、正しくロードされたセルをスクロール(負の値でy)すると、このコードを書いたので、このようにするのは嫌いですが、うまくいきました。

解決策が見つかった場合は、これを実行してください。迅速な3については

-(void)reloadTableView{ 
     CGPoint point = self.tableSettings.tableView.contentOffset; 
     [self.tableSettings.tableView reloadData]; 

     [UIView animateWithDuration:.001f animations:^{ 
      [self.tableSettings.tableView setContentOffset:CGPointMake(point.x, -10)]; 
     } completion:^(BOOL finished) { 
      [UIView animateWithDuration:.001f animations:^{ 
       [self.tableSettings.tableView setContentOffset:point]; 
      } completion:^(BOOL finished) { 

      }]; 
     }]; 
} 
+0

これは私のために働いた。私はよく、あなたが実際の問題 –

13

DispatchQueue.main.async(execute: {() -> Void in 
       self.tableView.reloadData() 
      }) 

SWIFT 2の場合:

dispatch_async(dispatch_get_main_queue(), {() -> Void in 
       self.tableView.reloadData() 
      }) 
+0

仲間の迅速を考え出した場合に3つの作品を教えてください!! ...おかげ –

+0

どういたしまして:) – Hamid

0

まず、この半解く私の関連の問題。私はテーブルのセル内の画像の角を丸めたい。非同期的にディスパッチすると、一部の画像では問題は解決されましたが、すべての画像では問題は解決されませんでした。何か案は?

第二に、私はあなたがこのような閉鎖キャプチャリストを使って、強い参照サイクルを作成しないようになっていると思う:

DispatchQueue.main.async(execute: { [weak weakSelf = self]() -> Void in 
      weakSelf!.tableView.reloadData() 
     }) 

を参照してください:のみ可視セルがロードされているhttps://developer.apple.com/library/prerelease/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-ID52

+0

だ@MayPhyuこれは私の問題を修正:DispatchQueue.main.async(実行:{[弱いweakCell =セル]() - > Void in weakCell!.imageView!.layer.cornerRadius = cell.imageView!.frame.width/4.0 weakCell!.imageView!.clipsToBounds = true }) – user3590685

関連する問題