从其他方法更新UITableViewCell

时间:2015-09-09 04:31:52

标签: ios objective-c uitableview

我在GG中搜索千万找到UITableViewCell的解决方案更新数据但是所有人都向我展示了解决方案

UITableViewCell *cell=(UITableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath];

但是对于所有可见的细胞,细胞都是零。我使用NSNotification将数据从一个方法发送到ViewController.m,而Reiever方法我希望通过indexPath将数据更新到单元格。但所有单元格都是零,无法更新。

这是我的代码 ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
@property(nonatomic, strong) IBOutlet UITableView *tableView;

@end 

ViewController.m

@implementation ViewController
{

}

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

    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(theReciever:) name:@"theSender" object:nil];

}                
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [recipes count];
}       
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleTableIdentifier = @"SimpleTableCell";
    UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
        NSLog(@"cell nil");

    }

    NSString *idgame=@"Gamexyz";
    cell.textLabel.text = idgame;
    cell.tag=indexPath.row;

    return cell;
}

-(void)theReciever:(NSNotification*)notif{

    if([notif.object isKindOfClass:[packeData class]]){

        packeData *data=[notif object];

        NSString *key=data.key;
        NSInteger *index=[key integerValue];
        NSIndexPath *indexPath=[NSIndexPath indexPathWithIndex:index];

        UITableViewCell *cell=(UITableViewCell*)[self.tableView cellForRowAtIndexPath:indexPath];

       //UITableViewCell *cell=(UITableViewCell*)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:7 inSection:0]];

        if(cell==nil)
        {
            NSLog(@"cell NULL");
        }else{
            cell.textLabel.text=data.process;
        }

    }else{
        NSLog(@"ERR: object not recognised");
    }

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

任何人都可以通过indexPath

帮助我或UITableViewCell更新数据的解决方案示例

2 个答案:

答案 0 :(得分:0)

注意:以下只是一个例子,您可以在新项目中执行此操作

您需要更改数据模型packeData,我们可以说key包含NSIntager,其中包含单元格的索引,process为{{1}将进度保存为字符串值,例如

NSString

中的

packeData.h

并在#import <Foundation/Foundation.h> @interface packeData : NSObject @property (nonatomic, assign) NSInteger key; //holds index @property (nonatomic, strong) NSString *process; //holds the progress info @end

packeData.m

@end

并在视图控制器中,你是tableview,

#import "packeData.h" @implementation packeData - (id)init //simply initialise it { self = [super init]; if(self) { } return self; }

中的

ViewController.h

in #import <UIKit/UIKit.h> #import "packeData.h" @interface ViewController : UIViewController <UI TableViewDataSource,UITableViewDelegate> @property (weak, nonatomic) IBOutlet UITableView *aTableView; @property (strong,nonatomic) NSMutableArray *recipes; //array acts as datasource @end

ViewController.m

修改

替换以下方法

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad  
{
   [super viewDidLoad];
   // Do any additional setup after loading the view, typically from a nib.
  [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(theReciever:) name:@"theSender" object:nil];

  _recipes = [[NSMutableArray alloc]init]; //initilise your datasource
  for(int j = 0 ;j< 20;j++)
   {
    // for my example i took some values
    //initially put some initial values
    packeData *data = [[packeData alloc] init];
    data.key = j;
    data.process = [NSString stringWithFormat:@"game_name_%d",j];
    [_recipes addObject:data];
  }
 }

 - (void)viewDidAppear:(BOOL)animated
 {
   [super viewDidAppear:animated];
   [NSTimer scheduledTimerWithTimeInterval:0.8 target:self selector:@selector(PostNotification) userInfo:nil repeats:YES];  //just for testing   
 } 

 - (void)PostNotification
 {
   //i am simply posting the notification with some random values
   packeData *data = [[packeData alloc]init];
   data.key = arc4random()%15;
   data.process = [NSString stringWithFormat:@"%ld",( data.key  + 20)];
   [[NSNotificationCenter defaultCenter] postNotificationName:@"theSender" object:data];
 }

- (void)theReciever:(NSNotification *)notif
{
    if([notif.object isKindOfClass:[packeData class]]){

      packeData *data=[notif object];
      NSInteger key=data.key;
      NSInteger index= key;
      //modify the datasource
      packeData *recipes_data = [_recipes objectAtIndex:index]; //get the pocket present in array
      recipes_data.process = data.process; //modify the recipes data

      NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
      UITableViewCell *cell=(UITableViewCell*)[self.aTableView cellForRowAtIndexPath:indexPath];

      if(cell==nil)
      {
         NSLog(@"cell NULL");
      }else
      {
         [self.aTableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
        //  cell.textLabel.text=data.process; no need u already mofied the content in the datasource this will call the "cellForRowAtIndexPath" method and displays the process in place of game name
     }
     }else{
       NSLog(@"ERR: object not recognised");
     }
 }

  - (void)didReceiveMemoryWarning {
     [super didReceiveMemoryWarning];
     // Dispose of any resources that can be recreated.
  }

  - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  {
    return 1;
  }

  - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 {
    return [_recipes count];
 }

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
   static NSString *simpleTableIdentifier = @"SimpleTableCell";
   UITableViewCell* cell = [self.aTableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

    if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
    NSLog(@"cell nil"); 
   }
   packeData *idgame= [_recipes objectAtIndex:indexPath.row];
   cell.textLabel.text = idgame.process; //initially contains game name
   cell.tag=indexPath.row;
   return cell;
 }

 @end

修改2

至于测试只是更改下面的方法,一旦模拟器启动应用程序滚动到下来,只有前5行只更新,等待5到10秒,滚动到顶部,你会看到所有的呼叫是更新用相同的过程5

- (void)PostNotification
 {
   //i am simply posting the notification with some random values
   packeData *data = [[packeData alloc]init];
   data.key = arc4random()%15; //15 change the number of rows
   data.process = [NSString stringWithFormat:@"%ld",( data.key  + arc4random() % 100)];
   [[NSNotificationCenter defaultCenter]      postNotificationName:@"theSender" object:data];  
 }


 - (void)theReciever:(NSNotification *)notif
 {
    if([notif.object isKindOfClass:[packeData class]]){

    packeData *data=[notif object];
    NSInteger key=data.key;
    NSInteger index= key;
    //modify the datasource
    packeData *recipes_data = [_recipes objectAtIndex:index]; //get the pocket present in array
    recipes_data.process = data.process; //modify the recipes data

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
    UITableViewCell *cell=(UITableViewCell*)[self.aTableView cellForRowAtIndexPath:indexPath];

    if(cell==nil)
    {
        NSLog(@"cell NULL");
        [self.aTableView reloadData]; //if cell is not visible then reload the whole table
    }else
    {
        [self.aTableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
      //  cell.textLabel.text=data.process; no need u already mofied the content in the datasource this will call the "cellForRowAtIndexPath" method and displays the process in place of game name
    }
    }else{
      NSLog(@"ERR: object not recognised");
   }

 }

形成上述测试你将看到前5个单元格即使不可见也会更新

答案 1 :(得分:0)

只需指定行的索引路径并重新加载...

NSIndexPath* path = [NSIndexPath indexPathForRow:3 inSection:0];
NSArray* rowsToReload = [NSArray arrayWithObjects:path, nil];
[tableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationNone];