我有一个只有一个单元格的表视图。当我调用一个方法时,我尝试刷新它,文本标签的文本应该改变。但事实并非如此,只有在视图重新出现时才会改变。
我在很多地方添加了NSLog()
,并且正确的方法和条件被称为
我尝试了一些事情:
reloadData
setNeedsDisplay
setNeedsLayout
reloadCell
reloadRowsAtIndexPaths: withRowAnimation:
但是没有有效,我知道我的UITableViewDataSource
代码没有问题,因为它被正确调用了。
这是我能给你的最合适的代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
tableView.scrollEnabled = NO;
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier: @"cell"];
if (cell) {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if ([[TravelLogViewController locationArray] count]) {
NSDictionary *flight = [NSDictionary dictionaryWithObjectsAndKeys:[[TravelLogViewController locationArray] lastObject], @"name", [[TravelLogViewController dateArray] lastObject], @"date", [[TravelLogViewController milesGainedIndex] lastObject], @"miles", nil];
cell.detailTextLabel.textColor = [UIColor blackColor];
cell.textLabel.numberOfLines = 2;
cell.detailTextLabel.numberOfLines = 2;
cell.textLabel.font = [UIFont fontWithName:@"Avenir" size: 14.0];
cell.detailTextLabel.font = [UIFont fontWithName:@"Avenir" size: 12.0];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.text = [flight objectForKey: @"name"];
cell.detailTextLabel.text = [NSString stringWithFormat:@"Flight Date: %@, Miles Gained: %.1f", [flight objectForKey: @"date"], [[flight objectForKey: @"miles"] doubleValue]];
cell.backgroundColor = [UIColor colorWithWhite:0.92 alpha:1];
// cell.backgroundColor = [UIColor clearColor];
}
else {
// This gets called when I want it to, but the textLabel text or detailTextLabel text is not changed
cell.detailTextLabel.text = nil;
cell.textLabel.text = nil;
cell.textLabel.font = [UIFont fontWithName:@"Arial Rounded MT Bold" size: 18.0];
cell.textLabel.text = @"\n\n No Flights";
}
}
return cell;
}
更新:
我正在使用ARC,并且我发现在我尝试更新单元格时表格视图为零,但我修改了我的单元格并且不知道为什么!?
我不会在任何地方发送或发布我的表视图,它仍然应该被分配
顺便说一下,我有一个标签栏控制器
更新:
我现在已经开始了赏金,一个多星期后我真的觉得这个问题需要更多的关注和答案,我已经多次检查了我的代码而我不能看看为什么表格查看没有更新/是nil
。
更新:
好的,我忘了提到用户可以滑动删除单元格。当他这样做时,它实际上删除单元格,它只是更改其文本(即它不更新的部分)。我将日志放入viewDidLoad
和viewDidAppear
,并且一旦用户滑动删除,表格视图就会显示有效...这是我的代码:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
TravelLogViewController *travel = [[TravelLogViewController alloc] init];
[travel manuallyDeleteTopCellData]; // Deletes some data in other view controller and calls the method `proceedWithDeletion`
}
}
- (void)proceedWithDeletion {
// Method is called from another view controller
NSLog(@"%@", mostRecentFlight.description); // NIL HERE
[mostRecentFlight reloadData];
[mostRecentFlight setNeedsDisplay];
[mostRecentFlight setNeedsLayout];
}
TravelLogViewController
- (void)manuallyDeleteTopCell {
[TheMileIndexViewController deductDesiredMilesToIndex: [[milesGainedIndex lastObject] floatValue]];
[locationArray removeLastObject];
[milesGainedIndex removeLastObject];
[dateArray removeLastObject];
MenuMileIndexViewController *menu = [[MenuMileIndexViewController alloc] init];
[menu proceedWithDeletion];
}
总而言之,一个视图加载/出现,表视图有效。当用户滑动删除时,它不会实际删除它只调用另一个名为TravelLogViewController
方法的名为manuallyDeleteTopCellData
的视图控制器,在那里删除一些数据,然后该方法调用我的原始视图控制器中的另一个方法叫proceedWithDeletion
,它应该重新加载表视图,但不会(问题)。这是因为在proceedWithDeletion
中,表视图为零,但为什么!?
答案 0 :(得分:3)
这是一个没有任何代码的盲目镜头,但是,如果你使用dequeueReusableCellWithIdentifier
,它可能会导致问题。如果您有一个单元格,则可以每次在cellForRowAtIndexPath
中创建单元格,而不是重新使用已创建的单元格。用这么小的表不会影响性能
答案 1 :(得分:2)
我几乎可以确认问题不在你正在寻找或描述的领域。
我已经从头开始创建了一个示例项目,非常简单地只需要UITableView
和UIButton
来触发[table reloadData]
并翻转一个布尔值:
BOOL toggle = NO;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier: @"cell"];
if (cell) {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if (toggle )
{
NSDictionary *flight = @{@"name" : @"Bob",
@"date" : @"Yesterday",
@"miles" : @"3" };
cell.textLabel.text = [flight objectForKey: @"name"];
cell.textLabel.numberOfLines = 2;
cell.detailTextLabel.numberOfLines = 2;
cell.detailTextLabel.textColor = [UIColor blackColor];
cell.detailTextLabel.text = [NSString stringWithFormat:@"Flight Date: %@, Miles Gained: %.1f", [flight objectForKey: @"date"], [[flight objectForKey: @"miles"] doubleValue]];
} else {
cell.textLabel.text = @"blank label";
cell.detailTextLabel.text = @"blank detail";
}
}
return cell;
}
- (IBAction)toggleValue:(id)sender
{
toggle = !toggle;
NSLog( @"toggle is now %@", (toggle) ? @"YES" : @"NO" );
[tv reloadData];
}
通过引用tableView:cellForRowAtIndexPath:
中的布尔值并使用您提供的代码,您可以看到在调用[table reloadData]
时,行实际上按预期更新。
您可以在此处下载示例项目(35KB):http://rdas.me/SampleProject.zip
我希望这能帮到你。如果没有别的,它应该可以帮助你找出事实上可能存在的地方。
祝你好运!答案 2 :(得分:1)
在manuallyDeleteTopCell
的{{1}}实施中,此时您实例化了一个新的TravelLogViewController
:
MenuMileIndexViewController
这是一个不同的控制器,既没有正确初始化也没有对屏幕上的视图负责。特别是,它没有相同的MenuMileIndexViewController *menu = [[MenuMileIndexViewController alloc] init];
[menu proceedWithDeletion];
属性。为了让mostRecentFlight
调用您的原始控制器,您需要将其作为参数传递给TravelLogViewController
并将其调回来,例如如下
manuallyDeleteTopCell
并按如下方式重写调用代码:
- (void)manuallyDeleteTopCell:(MenuMileIndexViewController *)origin {
[TheMileIndexViewController deductDesiredMilesToIndex: [[milesGainedIndex lastObject] floatValue]];
[locationArray removeLastObject];
[milesGainedIndex removeLastObject];
[dateArray removeLastObject];
[origin proceedWithDeletion];
}
以前的建议:
确保在Interface Builder中正确设置了插座。你在评论中说你做到了这一点,但在另一点你说你正在使用标签栏控制器。确保在常规视图控制器(即- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
TravelLogViewController *travel = [[TravelLogViewController alloc] init];
[travel manuallyDeleteTopCellData:self];
}
的子类)上设置插座,该控制器当前可见并包含在您正在使用的UIViewController
实例的viewControllers
属性中。 不要继承UITabBarController
(请参阅明确禁止它的Apple documentation)。的 [选中] 强>
在调用此方法时,实施常规视图控制器的UITabBarController
方法和viewDidLoad
NSLog
属性以验证它是非self.tableView
。的 [选中] 强>
在nil
的{{1}}中写一个@synthesize mostRecentFlight = _mostRecentFlight;
语句,并在@implementation
的属性上设置断点。或者,手动实现TravelLogViewController
属性的@interface
方法,并在此方法中设置断点。如果调用setter,将触发此断点,这将帮助您找到属性设置为setMostRecentFlight:
的时间。
假设在步骤2的mostRecentFlight
方法中该属性为非零,请查看对象的地址(说明的开头是{{1以nil
为地址)。在代码中稍后设置要在其中使用对象的断点(当属性为nil时)。在调试器viewDidLoad
处键入(使用上面的相应地址)。你得到的回应是什么?
答案 3 :(得分:1)
此代码可能是您问题的根源:
MenuMileIndexViewController *menu = [[MenuMileIndexViewController alloc] init];
[menu proceedWithDeletion];
你正在创建一个全新的MenuMileIndexViewController
,而不是访问已经存在的实例,这是我认为你想要做的事情。此新实例将无法访问mostRecentFlight
中存储的原始表视图。在-manuallyDeleteTopCell
内,您需要引用调用MenuMileIndexViewController
实例。
可能就像将self
传递给-manuallyDeleteTopCellData
并使用该变量随后调用-proceedWithDeletion
一样简单。例如:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
TravelLogViewController *travel = [[TravelLogViewController alloc] init];
[travel manuallyDeleteTopCellData:self];
}
}
- (void)manuallyDeleteTopCell:(id)sender {
[TheMileIndexViewController deductDesiredMilesToIndex: [[milesGainedIndex lastObject] floatValue]];
[locationArray removeLastObject];
[milesGainedIndex removeLastObject];
[dateArray removeLastObject];
// MenuMileIndexViewController *menu = [[MenuMileIndexViewController alloc] init];
[sender proceedWithDeletion];
}
答案 4 :(得分:0)
我通常使用此代码:
[_myTable beginUpdates];
[... update my cell, adding / removing / changing them ...];
[_myTable endUpdates];
自5.0版以来,它适用于我的项目。
答案 5 :(得分:0)
根据您的评论,您致电tableView
的{{1}}变量为reloadData
。
这种情况的常见原因是,在使用笔尖,使用ARC的弱ivars或使用同名的局部变量屏蔽ivar时,缺少指向IBOutlet的链接。
答案 6 :(得分:0)
我在代码中找不到任何错误。但是,请确保您设置了表视图数据源并委托了(应该在viewDidLoad / viewDidAppear / viewWillAppear中的某处设置):
[tableView setDelegate:self];
[tableView setDataSource:self];
在此之后,请确保从委托方法返回需要显示的行数:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [yourDataSource count];
}
祝你好运!
答案 7 :(得分:0)
我想注意一下。如果您正在使用故事板,则无需分配您的单元格。这段代码就足够了:
- (UITableViewCell *)tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath)indexPath
{
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:@"PlayerCell"];
Player *player = [self.players objectAtIndex:indexPath.row];
cell.textLabel.text = player.name;
cell.detailTextLabel.text = player.game;
return cell;
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:@"PlayerCell"];
Player *player = [self.players objectAtIndex:indexPath.row];
cell.textLabel.text = player.name;
cell.detailTextLabel.text = player.game;
return cell;