UITableView 未刷新

发布于 2024-12-29 22:59:17 字数 2718 浏览 2 评论 0原文

我有一个由 TabBar 和一些 TabBarController 组成的应用程序。一个控制器包含一个非常简单的表,该表应该显示 NSMutableDictionary 的内容。当您点击相应的按钮时,字典将在单独的控制器中更新,并且视图切换到 UITableViewController ,显示新更新的表。

我可以看到词典正在更新。但 TableView 永远不会反映这些变化。事实上,它似乎只在我第一次进入该屏幕时才显示更改。

我尝试过 [self table.reloadData],当它被调用时,更改不会反映到 UITableView 中。

有人有什么建议吗?我很高兴发布代码,但不确定要发布什么。

更新:表格仅在第一次显示时才正确更新和刷新。后续显示仅显示原始内容。

背景: 表视图从字典中填充:appDelegate.currentFave。每次 TabBarController 调用 ViewController 时,表视图都应该刷新。

- (void)viewWillAppear:(BOOL)animated
{
    NSLog(@"in viewWillAppear");

    [super viewWillAppear:animated];

    [self loadFavesFile];
    [self.tableView reloadData];
}

// load the Favorites file from disk
- (void) loadFavesFile 
{   
// get location of file
NSString *path = [self getFavesFilePath];

// The Favorites .plist data is different from the Affirmations in that it will never be stored in the bundle. Instead,
// if it exists, then use it. If not, no problem.
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {

    // read Faves file and store it for later use...
    NSMutableDictionary *tempDict = [NSMutableDictionary dictionaryWithContentsOfFile:path];
    appDelegate.sharedData.dictFaves = tempDict;    

    // grab the latest quote. Append it to the list of existing favorites
    NSString *key = [NSString stringWithFormat:@"%d", appDelegate.sharedData.dictFaves.count + 1];

    NSString *newFave = [NSString stringWithFormat:@"%@", appDelegate.currentFave];
    [appDelegate.sharedData.dictFaves setObject:newFave forKey:key];

} else {
    NSLog(@"Favorites file doesn't exist");
    appDelegate.sharedData.dictFaves = nil;     
}
}


// this gets invoked the very first call. Only once per running of the App.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// reuse or create the cell
static NSString *cellID = @"cellId";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellID];  
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}

// allow longer lines to wrap
cell.textLabel.numberOfLines = 0; // Multiline
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.font = [UIFont fontWithName:@"Chalkduster" size:(16)];
cell.textLabel.textColor = [UIColor yellowColor];   

// NOTE: for reasons unknown, I cannot set either the cell- or table- background color. So it must be done using the Label.

// set the text for the cell
NSString *row = [NSString stringWithFormat:@"%d", indexPath.row + 1];
cell.textLabel.text = [appDelegate.sharedData.dictFaves objectForKey:row];
return cell;    
}

I have an app consisting of a TabBar with a few TabBarControllers. One Controller contains a very simple table, which is supposed to display the contents of a NSMutableDictionary. When you hit the appropriate button, the Dictionary is updated in a separate Controller and the view switches to the UITableViewController, displaying the newly updated table.

I can see the Dictionary being updated. But the TableView never reflects the changes. In fact, it seems to display the changes only the 1st time I enter that screen.

I have tried [self table.reloadData] and while it gets called, the changes aren't reflected to the UITableView.

Does anyone have any suggestions? I am happy to post code, but am unsure what to post.

Update: the table is updated and refreshed properly only the 1st time it is displayed. Subsequent displays simply show the original contents.

Background:
The tableview gets filled from a dictionary: appDelegate.currentFave. The tableview should get refreshed each time the ViewController is invoked by the TabBarController.

- (void)viewWillAppear:(BOOL)animated
{
    NSLog(@"in viewWillAppear");

    [super viewWillAppear:animated];

    [self loadFavesFile];
    [self.tableView reloadData];
}

// load the Favorites file from disk
- (void) loadFavesFile 
{   
// get location of file
NSString *path = [self getFavesFilePath];

// The Favorites .plist data is different from the Affirmations in that it will never be stored in the bundle. Instead,
// if it exists, then use it. If not, no problem.
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {

    // read Faves file and store it for later use...
    NSMutableDictionary *tempDict = [NSMutableDictionary dictionaryWithContentsOfFile:path];
    appDelegate.sharedData.dictFaves = tempDict;    

    // grab the latest quote. Append it to the list of existing favorites
    NSString *key = [NSString stringWithFormat:@"%d", appDelegate.sharedData.dictFaves.count + 1];

    NSString *newFave = [NSString stringWithFormat:@"%@", appDelegate.currentFave];
    [appDelegate.sharedData.dictFaves setObject:newFave forKey:key];

} else {
    NSLog(@"Favorites file doesn't exist");
    appDelegate.sharedData.dictFaves = nil;     
}
}


// this gets invoked the very first call. Only once per running of the App.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// reuse or create the cell
static NSString *cellID = @"cellId";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellID];  
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}

// allow longer lines to wrap
cell.textLabel.numberOfLines = 0; // Multiline
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.font = [UIFont fontWithName:@"Chalkduster" size:(16)];
cell.textLabel.textColor = [UIColor yellowColor];   

// NOTE: for reasons unknown, I cannot set either the cell- or table- background color. So it must be done using the Label.

// set the text for the cell
NSString *row = [NSString stringWithFormat:@"%d", indexPath.row + 1];
cell.textLabel.text = [appDelegate.sharedData.dictFaves objectForKey:row];
return cell;    
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我为君王 2025-01-05 22:59:17

我发现了问题。我没有在视图控制器中正确初始化和分配 TableView。见下文

- (void)viewDidLoad
{
   [super viewDidLoad];

   tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]     style:UITableViewStylePlain];

   tableView.dataSource = self;
   tableView.delegate = self; 
   tableView.backgroundColor=[UIColor blackColor];
   self.view = tableView;
}

I found the problem. I was not properly initializing and assignng the TableView in my view controller. See below

- (void)viewDidLoad
{
   [super viewDidLoad];

   tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]     style:UITableViewStylePlain];

   tableView.dataSource = self;
   tableView.delegate = self; 
   tableView.backgroundColor=[UIColor blackColor];
   self.view = tableView;
}
清浅ˋ旧时光 2025-01-05 22:59:17

假设您提供的代码是正确的,您想要使用[self.table reloadData]。您的 . 位于错误的位置。

Assuming the code you have put up is correct, you want to use [self.table reloadData]. You have the . in the wrong place.

冬天的雪花 2025-01-05 22:59:17

我昨天遇到了同样的问题,对我来说,事实证明我在界面生成器中设置了错误的文件所有者,并且没有正确设置表视图的数据源和委托。

尝试进入界面生成器并右键单击文件所有者,这应该会显示是否有任何内容未正确连接。

I had this same problem yesterday, for me it turned out I had set the wrong file owner in interface builder and hadn't set up the data source and delegates for the table view properly.

Try going into interface builder and right-clicking on the file owner, this should show you if anything isn't connected up properly.

从﹋此江山别 2025-01-05 22:59:17

您应该确保您的 Interface Builder 连接设置正确,但这个问题实际上听起来像是您的 cellForRowAtIndexPath: 中的 UITableViewCell 设置代码>if(cell == nil) 语句。事实不应该是这样。让我解释一下。如果您有一个单元格列表,并且想要将每个单元格的标题设置为名为 myArray 的数组中的字符串,那么现在您的(不正确的)代码如下所示:

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellIdentifier"];
    if (cell == nil) {
        // No cell to reuse => create a new one
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cellIdentifier"] autorelease];

        [[cell textLabel] setText:[myArray objectAtIndex:[indexPath row]]];
    }
    return cell;
}

你能看到问题吗用这个逻辑?如果找不到可重用的单元格,则该单元格只会获得更新的标题,在您的情况下,这听起来像是这种情况。 Apple 表示,每次调用 cellForRowAtIndexPath: 时,您都应该创建一个“新”单元格,这意味着您将所有设置代码放在 if( 的外部) cell == nil) 检查。

继续这个例子,正确的代码将如下所示:

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellIdentifier"];
    if (cell == nil) {
        // No cell to reuse => create a new one
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cellIdentifier"] autorelease];
    }

    [[cell textLabel] setText:[myArray objectAtIndex:[indexPath row]]];
    return cell;
}

这样,单元格就会被分配正确的字符串无论是否找到可重用的单元格,因此调用reloadData将达到了预期的效果。

You should make sure that your Interface Builder connections are set up properly, but what this problem really sounds like is that you have your UITableViewCell setup code in cellForRowAtIndexPath: inside your if(cell == nil) statement. Which it shouldn't be. Let me explain. If you have a list of cells, and you want to set the titles to each cell to a string in an array called myArray, right now your (incorrect) code looks like this:

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellIdentifier"];
    if (cell == nil) {
        // No cell to reuse => create a new one
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cellIdentifier"] autorelease];

        [[cell textLabel] setText:[myArray objectAtIndex:[indexPath row]]];
    }
    return cell;
}

Can you see the problem with that logic? The cell will only get an updated title if no reusable cell can be found, which, in your case, sounds like the situation. Apple says that you should create a 'new' cell each time cellForRowAtIndexPath: is called, which means that you put all of your setup code outside of the if(cell == nil) check.

Continuing with this example, the proper code would look like this:

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellIdentifier"];
    if (cell == nil) {
        // No cell to reuse => create a new one
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cellIdentifier"] autorelease];
    }

    [[cell textLabel] setText:[myArray objectAtIndex:[indexPath row]]];
    return cell;
}

This way, the cell gets assigned the proper string whether or not a reusable cell is found and so calling reloadData will have the desired effect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文