为什么我的 UITableCellView 中的 UIView 中的 UILabel 在正确的数据库调用后没有更新(似乎与单元格重用相关)?
我有一个 UITableview 单元格,它从核心数据数据库中获取计数。 tallyTable 位于 UITab 视图内的视图控制器中。我有一个 NSLog 语句,每当更新时都会打印出计数值。另一个选项卡有一个列表,用于更改计数的来源(不同的日期)。我正在使用 iOS5 和针对 iOS 4.2 的 ARC。
问题就在这里。当我加载应用程序时,最后选定日期的正确计数会显示在表格选项卡中。如果我然后转到“日期”选项卡并更改日期并返回到“计数”选项卡,则显示不会发生任何变化。但是,计数选项卡上的 viewWillAppear 会运行,并且当表在 cellForIndexPath 中循环时,我的 NSLog 语句会打印出所有正确的新值。如果我然后将顶部标签滚动出屏幕并将标签更新为新值。
我已经在 UILabel、UITableViewCell、UITableView 和加载表格的视图控制器上尝试了 setNeedsLayout 和 setNeedsDisplay。我尝试更改 CellReuse 标识符,以便它永远不会重用单元格。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
CollectionItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CollectionItemTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [[self.collectionKeys objectAtIndex:row] valueForKey:@"collectionTitle"];
NSInteger test1 = indexPath.row + 150;
NSLog(@"tag = %i", test1);
cell.tallyButton.tag = test1;
NSNumber * questionID = [[self.collectionKeys objectAtIndex:row] valueForKey:@"answerID"];
cell.tallyLabel.text = [NSString stringWithFormat:@"%i",[self updatePointTotal:questionID]];
NSLog(@"Collection text should be = %@", [NSString stringWithFormat:@"%i",[self updatePointTotal:questionID]]);
[cell setNeedsLayout];
return cell;
}
我读过六个其他类似的问题。到目前为止,我们投入了大约三个小时来尝试解决这个问题。
编辑:我想我通过使用导航控制器将顶级视图控制器再次推到视图上来修复它。我现在承认,这在各方面都感觉像是一个典型的笨拙黑客。当视图被推送时,所有内容都会更新并且是无缝的。然而,为了有一个固定的页脚来对表格按钮进行选择设置,我使用了一个带有两个子视图的 UIView,一个位于顶部的 UITableView 和一个带有四个按钮的简单 UIView,位于下面。
按钮上的标题需要随数据源而变化。现在,当视图控制器被推到视图上时,它会遮挡我的固定页脚视图。因此,我将固定页脚插入 UITableview 中,一切看起来都很好,直到我滚动 UITableView 并且页脚随之向上滚动。该表基本上是一个统计表,每个项目旁边都有按钮,页脚中有四个按钮用于记录统计项目的颜色。假设下一个项目是绿色乐高,您可以点击页脚中的“绿色”和表格中“乐高”旁边的按钮。当我用两个子视图推送视图控制器时,UITableview 标签不会更新。因此,表视图需要自行推送(据我所知)。
答案:请参阅下面的评论,但最终我需要重新加载可见的 UITableView 数据及其背后的委托 UITableView 控制器数据。
I have a UITableview cell that gets a tally from a core data database. The tallyTable is in a view controller inside a UITab view. I have an NSLog statement that prints out the tally value whenever it gets updated. Another tab has a list to change the source (different day) for the tallies. I am using iOS5 with ARC targeting iOS 4.2.
Here's the problem. When I load the application, the correct tallies for whatever the last selected day show up in the table tab. If I then go to the day tab and change the day and return to the tally tab there is no change in the display. However, the viewWillAppear on the tally tab runs and as the table cycles through cellForIndexPath, my NSLog statement prints out all the correct new values. If I then scroll the top label off the screen and back the label updates to the new value.
I've tried setNeedsLayout and setNeedsDisplay on the UILabel, the UITableViewCell, the UITableView and the view controller loading the table. I tried changing the CellReuse identifier so that it would never reuse a cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
CollectionItemTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CollectionItemTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [[self.collectionKeys objectAtIndex:row] valueForKey:@"collectionTitle"];
NSInteger test1 = indexPath.row + 150;
NSLog(@"tag = %i", test1);
cell.tallyButton.tag = test1;
NSNumber * questionID = [[self.collectionKeys objectAtIndex:row] valueForKey:@"answerID"];
cell.tallyLabel.text = [NSString stringWithFormat:@"%i",[self updatePointTotal:questionID]];
NSLog(@"Collection text should be = %@", [NSString stringWithFormat:@"%i",[self updatePointTotal:questionID]]);
[cell setNeedsLayout];
return cell;
}
I've read over a half dozen other similar questions. Got about three hours invested so far in trying to solve this.
EDIT: I thought I fixed it by using the navigation controller to repush the top level view controller on to the view again. I'll admit now this feels like a classically kludgy hack in every way. When the view is PUSHED everything updates and it is seamless. However, in order to have a fixed footer to make selection settings for the table buttons, I used a UIView with two subviews, a UITableView on top and a simple UIView with four buttons below.
The captions on the buttons need to change with the data source. Now when the view controller is pushed onto the view it obscures my fixed footer view. So, I inserted the fixed footer into the UITableview and everything appeared fine until I scrolled the UITableView and the footer scrolled up with it. The table is basically a tally sheet with buttons next to each item and in the footer is four buttons to note the color of the tallied item. Say the next item was a green lego, you would tap "green" in the footer and the button next to "lego" in the table. When I push the view controller with the two subviews the UITableview labels do not update. Thus the tableview needs to be pushed itself (as far as I can tell).
ANSWER: see comment below but ultimately I needed to reload both the visible UITableView data and the delegate UITableView controller data behind it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我会尝试一下。首先,你使用ARC吗?如果没有,您需要在分配/初始化新单元时添加
autorelease
。否则的话,就这样就好了。如果我正确理解您的问题:
tableView 在应用程序启动时显示正确的数据
您从带有 tableView 的选项卡切换并更改 tableView dataSource
您切换回带有 tableView 的选项卡,您会看到(通过 NSLog)表格单元格重新加载了正确的数据,但旧数据仍然可见cells
如果您滚动单元格显示并返回强制其刷新它包含正确的数据
一些想法:
tableView 在以下情况下不会自动重新加载它的视图出现了。每当数据源发生变化时,您都需要调用
[tableView reloadData]
。这与 tableView 当前是否显示无关。我的猜测是,仅此一项就可以解决您的问题。您不需要在单元格上调用
setNeedsLayout
,除非您希望单元格根据数据重新布局其子视图。您也不需要setNeedsDisplay
。我假设没有其他复杂的因素(例如多个 tableView 显示相同的数据)可能会造成混乱。
I'll give it a shot. First, are you using ARC? If not, you need to add
autorelease
when you alloc/init a new cell. Otherwise, it's fine as is.If I'm understanding your question correctly:
The tableView displays the correct data at app launch
You switch away from the tab with the tableView and change the tableView dataSource
You switch back to the tab with the tableView and you see (via NSLog) that the table cells are reloaded with the correct data yet the old data is still visible in the cells
If you scroll a cell off the display and back forcing it to refresh it contains the correct data
Some thoughts:
the tableView will not reload itself automatically when it's view appears. You need to call
[tableView reloadData]
whenever the dataSource changes. This is independent of whether the tableView is currently displayed or not. My guess is this alone will solve your problem.You don't need to call
setNeedsLayout
on the cell unless you want the cell to relayout its subviews based on the data. You also don't needsetNeedsDisplay
.I'm assuming there aren't other complicating factors (such as multiple tableViews displaying the same data) that could confuse things.
如果你使用prepare forreuse方法,记得用[superprepareForReuse]覆盖原来的方法;
如果上述方法不起作用,另一种方法是重新设置单元格,如此处所述。
我使用与我的一些集合视图相同的方法:我们应该删除/重置您在单元格内容中创建/添加子视图的位置。这意味着我们需要为每行的每个单元格完全设置数据。
我将代码重置数据值从准备重用移动到我设置值的位置,我的工作很简单!
在我的 CustomCell.m 中:
记住也要适当地更改您的数据源。
If you use prepare for reuse method, remember to over the original method with [super prepareForReuse];
Another method if the above way does not work is re setup cell as describe here.
I use the same method i applied for some of my collection view : we should remove/reset your subview where you create/add it to cell 's content. That mean we need set up data each cell completely for each row.
I move the code reset data value from prepare reuse to where i set value and I worked simply !
In my CustomCell.m :
Remember to change your data source appropriately too.