我在这里的设置是我在故事板中定义了一个UITableView
静态单元格。在一个静态单元格中,我有一个动态的嵌套UITableView
,并以编程方式填充其内容。我已经研究了这个,并假设这是一个完全有效的配置,因为你可以在UIView
内拥有任何类型的UITableViewCell
子类(即表格视图)。
但是,无论何时加载视图,我都会获得超出边界异常的索引,即使我的后台数据结构有效并且我确保所有内部表视图的委托方法都返回正确的值。我在我的cellForRowAtIndexPath:
方法中放置了断点,但这没有结果,因为在调用该方法之间会抛出异常。所以我不确定我做错了什么,或者暗地说这是一个无效的配置。
此界面的目标是在同一屏幕上显示发票及其所有关联的订单项(嵌套/嵌入的表格视图),而不是我之前点击以查看订单上的订单项的方式。单独UITableViewController
视图。
请参阅下面的屏幕截图和代码。
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSInteger count = 0;
if (tableView == self.tableView) {
count = [super numberOfSectionsInTableView:tableView];
} else if (tableView == itemsTable) {
count = 3;
}
return count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger count = 0;
if (tableView == self.tableView) {
count = [super tableView:tableView numberOfRowsInSection:section];
} else if (tableView == itemsTable) {
switch (section) {
case 0:
// Header
count = 1;
break;
case 1:
// Items
count = assoicatedInvoice.items.count;
break;
case 2:
// Add item
count = 1;
break;
default:
break;
}
}
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * cell;
if (tableView == self.tableView) {
cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
} else if (tableView == itemsTable) {
InvoiceDetailEmbeddedLineItemViewCell * iCell;
switch (indexPath.section) {
case 0:
// Header section
iCell = (InvoiceDetailEmbeddedLineItemViewCell *) [tableView dequeueReusableCellWithIdentifier:invoiceDetailLineItemHeadersViewCellIdentifier];
break;
case 1: {
// Item
InvoiceItem * associatedItem = [assoicatedInvoice.items objectAtIndex:indexPath.row];
iCell = (InvoiceDetailEmbeddedLineItemViewCell *) [tableView dequeueReusableCellWithIdentifier:invoiceDetailEmbeddedLineItemViewCellIdentifier];
iCell.nameLabel.text = associatedItem.name;
iCell.qtyLabel.text = [UtilityFunctions decimalFormatForInput:associatedItem.quantity minDecimalPlaces:0 maxDecimalPlaces:2];
iCell.priceLabel.text = [UtilityFunctions currencyFormatForInput:associatedItem.price];
iCell.taxLabel.text = [UtilityFunctions percentageFormatForInput:associatedItem.tax minDecimalPlaces:0 maxDecimalPlaces:2];
break;
}
case 2:
// Add new item
iCell = (InvoiceDetailEmbeddedLineItemViewCell *) [tableView dequeueReusableCellWithIdentifier:invoiceDetailLineItemAddItemCellIdentifier];
break;
default:
break;
}
cell = iCell;
}
return cell;
}
- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString * title = nil;
if (tableView == self.tableView) {
if (section != 0) {
title = [super tableView:tableView titleForHeaderInSection:section];
} else {
title = [Invoice friendlyNameForInvoiceType:assoicatedInvoice.invoiceType];
}
}
return title;
}
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
if (tableView == self.tableView) {
return [super tableView:tableView viewForHeaderInSection:section];
} else if (tableView == itemsTable) {
return nil;
}
return nil;
}
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat height = 0.0;
if (tableView == self.tableView) {
if (indexPath.section != 1) {
height = [super tableView:tableView heightForRowAtIndexPath:indexPath];
} else {
height = itemsTable.contentSize.height;
}
} else if (tableView == itemsTable) {
height = 30.0;
}
// height = [super tableView:tableView heightForRowAtIndexPath:indexPath];
return height;
}
运行后,这是我得到的堆栈跟踪。
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(
0 CoreFoundation 0x041dc1e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x0303a8e5 objc_exception_throw + 44
2 CoreFoundation 0x041908b2 -[__NSArrayI objectAtIndex:] + 210
3 UIKit 0x0244935f -[UITableViewDataSource tableView:indentationLevelForRowAtIndexPath:] + 127
4 UIKit 0x021c2f34 -[UITableViewController tableView:indentationLevelForRowAtIndexPath:] + 61
5 UIKit 0x01fe02cf __53-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 1786
6 UIKit 0x01f5481f +[UIView(Animation) performWithoutAnimation:] + 82
7 UIKit 0x01f54868 +[UIView(Animation) _performWithoutAnimation:] + 40
8 UIKit 0x01fdfbd0 -[UITableView _configureCellForDisplay:forIndexPath:] + 108
9 UIKit 0x01fe713d -[UITableView _createPreparedCellForGlobalRow:withIndexPath:] + 442
10 UIKit 0x01fe71f3 -[UITableView _createPreparedCellForGlobalRow:] + 69
11 UIKit 0x01fc8ece -[UITableView _updateVisibleCellsNow:] + 2428
12 UIKit 0x01fdd6a5 -[UITableView layoutSubviews] + 213
13 UIKit 0x01f5d964 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
14 libobjc.A.dylib 0x0304c82b -[NSObject performSelector:withObject:] + 70
15 QuartzCore 0x02f2345a -[CALayer layoutSublayers] + 148
16 QuartzCore 0x02f17244 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
17 QuartzCore 0x02f170b0 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26
18 QuartzCore 0x02e7d7fa _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 294
19 QuartzCore 0x02e7eb85 _ZN2CA11Transaction6commitEv + 393
20 QuartzCore 0x02f3c5b0 +[CATransaction flush] + 52
21 UIKit 0x01eec9bb _UIApplicationHandleEventQueue + 13095
22 CoreFoundation 0x0416577f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
23 CoreFoundation 0x0416510b __CFRunLoopDoSources0 + 235
24 CoreFoundation 0x041821ae __CFRunLoopRun + 910
25 CoreFoundation 0x041819d3 CFRunLoopRunSpecific + 467
26 CoreFoundation 0x041817eb CFRunLoopRunInMode + 123
27 GraphicsServices 0x044395ee GSEventRunModal + 192
28 GraphicsServices 0x0443942b GSEventRun + 104
29 UIKit 0x01eeef9b UIApplicationMain + 1225
30 Field Manage 0x000aae7d main + 141
31 libdyld.dylib 0x0355d701 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
答案 0 :(得分:2)
赞赏将动态原型单元放入静态表的创新方法:)
静态单元格表视图实现了许多与大小相关的方法(在本例中为indentationLevelForRowAtIndexPath
)并从内部数组返回值。由于您尝试对两个tableviews使用相同的委托和dataSource,因此您需要为几乎所有与大小调整有关的委托方法提供覆盖。更好的解决方案可能是使用不同的数据源并完全委托嵌入式表。
答案 1 :(得分:1)
我在我的应用程序中使用嵌套的UICollectionView
执行类似的操作。我找到了最简单的方法,使其中的每个 CELL dataSource
和delegate
嵌入其中。因此,您必须总共创建2个UITableViewCell的自定义子类,将静态单元格设置为第一个子类的实例,然后在.m中为第一个UITableViewCell实现cellForRowAtIndexPath:
之类的内容子类,让它创建并返回第二个子类的实例。