gpt4 book ai didi

ios - 包含 UISwitch 的 UITableView 单元格更新不一致

转载 作者:行者123 更新时间:2023-11-28 23:41:33 25 4
gpt4 key购买 nike

我有一个 UITableView,其中每个单元格都包含一个 UISwitch。该开关应该将单元格中命名的内容切换为事件或不活动,并且当用户切换开关时它可以完美地工作。

然而,当整个表格行被选中时,我想到了也进行切换的好主意。理论上很简单吧?在更新数据模型方面确实如此。

但是,无论出于何种原因让我在过去的 2 小时内感到困惑,当我重新加载表数据时,只有单元格 #3 中的开关更新以反射(reflect)状态变化。无论表格中有多少行,始终只有第三个单元格有效。如果少于 3 个单元格,则没有单元格工作。

我已经在其中转储了大量的 NSLog 调用,它们反射(reflect)了我一直期望的正确数据状态,但它们只是没有反射(reflect)在开关之外第一次加载。如果我离开 View Controller 然后回来,开关都已正确设置...

我只知道这将是我在某个地方做过的一些愚蠢的事情,因为它只在一个实例中起作用,但在我的一生中我看不到它:(

可以吗?

-(void)viewDidLoad
{
[super viewDidLoad];

[_tableAddPeople setDelegate:self];
[_tableAddPeople setDataSource:self];
}

-(void)viewWillAppear:(BOOL)animated
{
[_tableAddPeople reloadData];
}

-(void)listSwitchChanged:(id)sender
{
UISwitch * switchControl = sender;

Person * person = [SAVE_DATA getPersonWithIndex:(int)switchControl.tag];

if (switchControl.on)
{
[SAVE_DATA activePeopleAdd:person.tag];
}
else
{
[SAVE_DATA activePeopleRemove:person.tag];
}
}


#pragma mark UITableViewDataSource Delegate

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

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * cell = [_tableAddPeople dequeueReusableCellWithIdentifier:@"AddPeopleCell"];

UILabel * nameLabel = (UILabel *)[cell.contentView viewWithTag:1];
UISwitch * activeSwitch = (UISwitch *)[cell.contentView viewWithTag:2];

Person * person = [SAVE_DATA getPersonWithIndex:(int)[indexPath row]];

[nameLabel setText:[person name]];

BOOL active = [SAVE_DATA activePeopleContains:person.tag];
NSLog(@"Row for %@ is %@", person.name, (active? @"ON" : @"OFF"));
[activeSwitch setOn:active animated:YES];
[activeSwitch addTarget:self action:@selector(listSwitchChanged:) forControlEvents:UIControlEventValueChanged];
activeSwitch.tag = (int)[indexPath row];

return cell;
}

-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}

-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}


#pragma mark UITableView Delegate

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Person * person = [SAVE_DATA getPersonWithIndex:(int)[indexPath row]];

if ([SAVE_DATA activePeopleContains:person.tag])
{
NSLog(@"Removing %@", person.name);
[SAVE_DATA activePeopleRemove:person.tag];
}
else
{
NSLog(@"Adding %@", person.name);
[SAVE_DATA activePeopleAdd:person.tag];
}

[_tableAddPeople reloadData];
//dispatch_async(dispatch_get_main_queue(), ^{[tableView reloadData];});
}

最佳答案

您的问题是您将 switch tag 属性用于两件事:

  1. 在 View 层次结构中识别它(您已分配值“2”)
  2. 确定在哪一行更改了开关

因为您正在将 indexPath.row 分配给 tag,如果索引路径不是 2(即第三行),[cell .contentView viewWithTag:2]; 将在单元格被重新使用时返回 nil

您还遇到了单元重用的问题,因为您要多次添加切换操作处理程序。

我建议您采用以下方法:

  1. 使用属性公开单元格的 subview 并将 dequeueReusableCell 的结果转换为您的 UITableViewCell 子类,以便您无需使用标签即可访问它们

  2. 将您的 UITableViewCell 子类设置为切换操作处理程序。

  3. 在单元格和 View Controller 之间实现委托(delegate)模式,以便单元格可以通知 View Controller 开关已更改。单元格可以将 self 传递给委托(delegate)方法。在委托(delegate)方法中,您可以使用 indexPathForCell 来确定受影响的行。

  4. 不要仅仅因为一行发生了变化就重新加载整个 TableView 。仅重新加载受影响的行。

关于ios - 包含 UISwitch 的 UITableView 单元格更新不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53272638/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com