gpt4 book ai didi

ios - UISwitch 和 viewWithTag 在 numberOfRowsInSection 中为 nil

转载 作者:行者123 更新时间:2023-11-29 13:24:03 25 4
gpt4 key购买 nike

我正在尝试找出向我的 UITableView 的 header 添加和管理 UISwitch 的最佳方法,到目前为止,我已经阅读了几个关于如何最好地在表中使用 UISwitch 的链接:here , herehere .这些链接演示了在单元格中使用 UISwitch,而我在标题的自定义 UIView 中使用它们。也就是说,我更愿意使用标签来管理这些对象,但我无法弄清楚为什么 viewWithTag 方法不起作用。

旁注:我能够在运行时将 UISwitch 放入 NSMutableArray 中并以这种方式管理它们,但我不想那么冗长,管理数组上的边界违规/索引或检查 nil 列表等... 我也不清楚如何使用 IBOutlets 执行此操作。这就是我尝试标签方法的原因。

我的目标是使用开关折叠/展开每个部分中的行,这就是为什么我想标记 UISwitches 并将其作为 subview 添加到我在 viewForHeaderInSection 中返回的 UIView。然后当我需要执行一些逻辑来折叠单元格时重新引用它们。此外,在运行时我可能有 1 个或多个部分,因此硬编码标签号是不切实际的。这是该方法的代码:

假设:

#define kSwitchTagRange 2000
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, 44)];

// Add UISwitches and ensure that UISwitch doesn't already exist for this section...
UISwitch *switchView = (UISwitch*)[self.tableView viewWithTag:(kLayerSwitchTagRange + section)];

if (switchView == nil) {

// Create switch
switchView = [[UISwitch alloc] init];
double xOffset = self.tableView.bounds.size.width - switchView.frame.size.width;
switchView.frame = CGRectMake(xOffset,
7,
switchView.frame.size.width,
switchView.frame.size.height);

[switchView addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];

// Should we tag the switch view?
switchView.tag = kSwitchTagRange + section;
}

// Add switch as subview
[view addSubview:switchView];

return view;
}

在 switchChanged 中:我只是重新加载表的数据:

- (void)switchChanged:(id)sender {

[self.tableView reloadData];
}

最后,当重新创建表的数据时,我尝试检索 UISwitch 并确定它的开/关状态,然后如果关闭则返回 0 作为该部分中的行数,如果打开则返回其他一些数字:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

NSInteger rowCount = 0;

UISwitch *switchView = (UISwitch*)[self.view viewWithTag:(kSwitchTagRange + section)];

if (switchView != nil && switchView.isOn == NO)
{
rowCount = 0;

}
else
{
// Row count is something other than 0
rowCount = 3;
}

return rowCount;
}

不幸的是,这个 switchView 总是 nil。

我有一些猜测,但无法确定为什么会这样。

  • 猜测 1:我想要添加开关的 UIView 在重新加载表数据时被释放。它不存在于内存中,因此无法通过标签搜索找到。
  • 猜测 2:我错误地将 UISwitch 添加到 View 对象(在许多示例中,我看到对象添加到 UITableViewCell 的 contentView,但是由于我在 viewForHeaderInSection: 方法中发回 UIView,我不确定这些示例是否适用于此处。addSubview 应将任何对象添加到树中。

谁能告诉我为什么上面的 viewWithTag 方法会返回 nil?我倾向于猜测 #1,但没有找到任何文档告诉我自定义 header UIView 随时被释放。单元格被重复使用,但节标题呢?

最后,我阅读了 this post虽然关于标签使用的建议是有道理的,但它似乎根本不喜欢标签方法。如果您不觉得标签的使用很麻烦而且标签的使用很巧妙,为什么不使用标签呢?为什么标签功能可用?

真的,我只是想知道为什么 viewWithTag 方法在我的例子中返回 nil。

干杯!

最佳答案

我不确定为什么您的 viewWithTag 总是返回 nil,我认为这可能与 View 在某个时候被释放有关。

然而,标签仍然可以做你想做的事,但你需要在你的模型对象中有一个属性或键来跟踪开关的值。您可以使用标签在其操作方法中告知开关位于哪个部分,并适本地更新模型。这就是我所做的。我的模型是一个字典数组,其中键“rowData”的值是一个包含该部分所有数据的数组,键“switchValue”的值是一个 NSNumber,0 或 1,代表开关的状态.因此,我的数据如下所示:

2012-11-28 22:50:03.104 TableWithSwitchesInHeaderView[3592:c07] (
{
rowData = (
One,
Two,
Three,
Four
);
switchValue = 1;
},
{
rowData = (
Red,
Orange,
Yellow,
Green,
Blue,
Violet
);
switchValue = 1;
},
)

这是我在相关 TableView 委托(delegate)和数据源方法中的内容:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.theData.count;
}

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, 44)];
UISwitch *switchView = [[UISwitch alloc] init];
double xOffset = self.tableView.bounds.size.width - switchView.frame.size.width;
switchView.frame = CGRectMake(xOffset,7,switchView.frame.size.width,switchView.frame.size.height);
[switchView addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
switchView.tag = kSwitchTagRange + section;
switchView.on = [[[self.theData objectAtIndex:switchView.tag - 101] valueForKey:@"switchValue"] boolValue];
[view addSubview:switchView];
return view;
}

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 50;
}

- (void)switchChanged:(UISwitch *)sender {
NSMutableDictionary *dict = [self.theData objectAtIndex:sender.tag - 101];
[dict setValue:[NSNumber numberWithBool:sender.isOn] forKey:@"switchValue"];
[self.tableView reloadData];
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
BOOL switchValue = [[self.theData[section] valueForKey:@"switchValue"] boolValue];
if (switchValue) {
return [[self.theData[section] valueForKey:@"rowData"] count];
}else{
return 0;
}

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
cell.textLabel.text = [[self.theData[indexPath.section]valueForKey:@"rowData"]objectAtIndex:indexPath.row] ;
return cell;
}

我的 kSwitchTagRange #defined 为 101。此代码用于折叠开关关闭的任何部分中的行(实际上摆脱所有行)。

关于ios - UISwitch 和 viewWithTag 在 numberOfRowsInSection 中为 nil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13617329/

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