【发布时间】:2014-09-15 16:36:12
【问题描述】:
我有一个TableView“cannedTv”。每个单元格包含另一个TableView“valuesTv”。 cannedTv 的datasource 的结构是{ NSString *name, NSArray *valuesArr }。对于valuesTv,valuesArr 设置为 datasource。 cannedTv 是一个可扩展的表格视图。最初只显示名称,当展开 valuesTv tableView 时显示。这是我的表格视图的didSelectRowAtIndexPath 和cellForRowAtIndexPath 委托方法的代码。
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"ROW Selected...TAG = %d", tableView.tag);
selectedValueIndex = -1;
if (tableView == self.cannedTV) {
// USer taps expanded row
if (selectedIndex == indexPath.row) {
selectedIndex = -1;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath ] withRowAnimation:UITableViewRowAnimationFade];
return;
}
// USer taps differnt row
if (selectedIndex != -1) {
NSIndexPath *prevPath = [NSIndexPath indexPathForRow:selectedIndex inSection:0];
selectedIndex = indexPath.row;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:prevPath] withRowAnimation:UITableViewRowAnimationFade];
}
// User taps new row with none expanded
selectedIndex = indexPath.row;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
return;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"Table View TAG = %d ROW = %d", tableView.tag, indexPath.row);
if (tableView.tag == 10) { // cell.valuesTv
CannedValueCell *ccell = (CannedValueCell *) [tableView dequeueReusableCellWithIdentifier:@"cannedValueCell"];
if (ccell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CannedValueCell" owner:self options:nil];
ccell = [nib objectAtIndex:0];
}
// Populate valuesTv
ccell.valueTextView.text = [valuesArray objectAtIndex:indexPath.row];
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(valueTextViewTapped)];
[ccell.valueTextView addGestureRecognizer:gestureRecognizer];
//[ccell.valueTextView sizeToFit];
return ccell;
} else {
// cannedTv
static NSString *cellIdentifier = @"CannedCell";
cell = (CannedCell *) [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CannedCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
// Set Datasource & Delegate for valuesTv tableview
cell.valuesTv.dataSource = self;
cell.valuesTv.delegate = self;
if (selectedIndex == indexPath.row) {
// Do expanded cell stuff
[cell.tapInsertLbl setFont:[UIFont fontWithName:@"OpenSans" size:8.0]];
cell.tapInsertLbl.hidden = FALSE;
[cell.contentView setBackgroundColor:[UIColor lightGrayColor]];
[cell.contentView.layer setBorderColor: (__bridge CGColorRef)([UIColor redColor])];
[cell.contentView.layer setBorderWidth:1.0f];
} else {
// Do closed cell stuff
cell.tapInsertLbl.hidden = TRUE;
cell.contentView.backgroundColor = [UIColor whiteColor];
}
if (tableView == self.cannedTV) {
valuesArray = nil;
CannedItem *ci = [candRespList objectAtIndex:indexPath.row];
cell.tagLbl.text = ci.name;
// Set the valuesArray so it be used in populating the valuesTv
valuesArray = [NSMutableArray arrayWithArray: ci.valuesArr];
ci = nil;
} else if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.tagLbl.text = [searchResults objectAtIndex:indexPath.row];
}
[cell.tagLbl sizeToFit];
return cell;
}
}
我面临的问题是,每次正确的datasource 显示在valuesTv 中。此时我在 valuesArray 中有 2 个数组,第 0 个元素有 1 个对象,第一个元素有 3 个对象(NSString)。 Datasource 的 cannedTv 也有 2 行。有时,有一次canndTv 的两行都显示正确的数据源,然后都显示相同的数据源。有时,两行都显示相同的数据源。我不明白为什么valuesArray 无法获得正确的数据源。在调试的同时,我发现有时valuesArray 具有正确的数据源但表格视图显示错误,有时控件不会转到// Populates valuesTv 行,因此仅显示先前设置的valuesArray。我尝试了很多方法,但无法获得预期的结果。在设置selectedIndex 之后,还尝试在didSelectRowAtIndexPath 中设置valuesArray,但这也没有帮助。
从昨天开始我就被困在这个问题上,无法通过。由于表格视图上未显示/反映正确的数据源,我在哪里出错了。你能不能帮帮我。非常感谢任何帮助。非常感谢。
更新:-
在 CannedCell 对象本身中创建了新的数据源和委托 - 它包含 valuesTv。
@interface CannedCell : UITableViewCell <UITableViewDataSource, UITableViewDelegate>
@property NSArray *valuesDataSource; // Contains the valuesArray contents
在我的 VC 中,删除了 cell.values.datasource 和 cell.valuesTv.delegate 行的数据源。在顶表的cellForRowAtIndexPath 方法中,像这样设置数据源:-
if (tableView == self.cannedTV) {
valuesArray = nil;
CannedItem *ci = [candRespList objectAtIndex:indexPath.row];
cell.tagLbl.text = ci.name; //[tagsArray objectAtIndex:indexPath.row];
//valuesArray = [NSMutableArray arrayWithArray: ci.valuesArr];
cell.valuesDataSource = ci.valuesArr; // SET DATASOURCE
// This is setting proper array always
ci = nil;
}
在cellForRowAtIndexPath 方法中注释了整个if (tableView.tag == 10) {。
在 CannedCell 中:-
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (valuesDataSource != nil)
return valuesDataSource.count;
else
return 0;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CannedValueCell *ccell = (CannedValueCell *) [tableView dequeueReusableCellWithIdentifier:@"cannedValueCell"];
if (ccell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CannedValueCell" owner:self options:nil];
ccell = [nib objectAtIndex:0];
}
// Populate valuesTv
ccell.valueTextView.text = [valuesDataSource objectAtIndex:indexPath.row];
ccell.valueTextView.tag = indexPath.row;
return ccell;
}
但结果与之前一样。我的意思是即使 3 个对象的数组设置为 valuedDataSource,子表也只显示单个对象数组。现在的想法可能是什么原因?
【问题讨论】:
-
您的问题是,在
cellForRowAtIndexPath中,您不知道子表视图请求哪个单元格。您似乎假设在为顶级表视图单元格调用该方法后将立即为子表视图调用该方法(因此您正在设置valuesArray),但这不是一个有效的假设。我将创建另一个对象类作为子表视图的数据源和委托 -
在一个函数中,您正在检查
if (tableView == self.cannedTV)和另一个您正在检查if (tableView.tag == 10),两者都意味着它是cannedTv?为什么那些不一致?标签检查真的正确吗? -
@ansible, tableview.tag == 10 表示 valuesTv 即子表视图。而cannedTv 是主tableview,其单元格包含valuesTv。
-
@Paulw11,那么在我的情况下,您将如何将数据传递给另一个对象类来管理子表的数据源和委托。那会有什么帮助?
-
我不清楚您是否希望能够一次扩展多行或仅扩展一个,但无论哪种方式实现都是相似的。创建一个类作为子表的数据源和委托。此类还将存储其扩展状态。在
cellForRowAtIndexPath中,您将为每个单元格创建这个新类的实例,分配适当的子数组并将其设置为单元格中表格视图的数据源和委托。然后,您不必在一组代码中检查所有这些来尝试确定您正在处理哪个表
标签: ios objective-c uitableview datasource