我尝试使用以下结构实现uitableview:
它应该像这个截图(1-2-3-4)一样: http://dl.dropbox.com/u/2213241/uitableview.png
所以总是可以看到两个部分。
我该如何实现?或者有人已经实现了这个吗?
谢谢:)
答案 0 :(得分:3)
嵌套部分的技巧是在表视图中有两种行。一个用于表示第二级节,另一个用于表示tableview中的正常行。假设您有一个两级数组(比如部分)来表示表视图中的项目。
然后,我们拥有的部分总数只是顶级部分的数量。每个顶级部分中的行数将是子部分的数量+每个子部分中的行数。
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.sections.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *sectionItems = self.sections[(NSUInteger) section];
NSUInteger numberOfRows = sectionItems.count; // For second level section headers
for (NSArray *rowItems in sectionItems) {
numberOfRows += rowItems.count; // For actual table rows
}
return numberOfRows;
}
现在,我们需要考虑的是如何为表视图创建行。在故事板中设置两个原型,使用不同的重用标识符,一个用于节头,另一个用于行项,并根据数据源方法中的询问索引实例化正确的原型。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSMutableArray *sectionItems = self.sections[(NSUInteger) indexPath.section];
NSMutableArray *sectionHeaders = self.sectionHeaders[(NSUInteger) indexPath.section];
NSIndexPath *itemAndSubsectionIndex = [self computeItemAndSubsectionIndexForIndexPath:indexPath];
NSUInteger subsectionIndex = (NSUInteger) itemAndSubsectionIndex.section;
NSInteger itemIndex = itemAndSubsectionIndex.row;
if (itemIndex < 0) {
// Section header
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"SECTION_HEADER_CELL" forIndexPath:indexPath];
cell.textLabel.text = sectionHeaders[subsectionIndex];
return cell;
} else {
// Row Item
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ROW_CONTENT_CELL" forIndexPath:indexPath];
cell.textLabel.text = sectionItems[subsectionIndex][itemIndex];
return cell;
}
}
- (NSIndexPath *)computeItemAndSubsectionIndexForIndexPath:(NSIndexPath *)indexPath {
NSMutableArray *sectionItems = self.sections[(NSUInteger) indexPath.section];
NSInteger itemIndex = indexPath.row;
NSUInteger subsectionIndex = 0;
for (NSUInteger i = 0; i < sectionItems.count; ++i) {
// First row for each section item is header
--itemIndex;
// Check if the item index is within this subsection's items
NSArray *subsectionItems = sectionItems[i];
if (itemIndex < (NSInteger) subsectionItems.count) {
subsectionIndex = i;
break;
} else {
itemIndex -= subsectionItems.count;
}
}
return [NSIndexPath indexPathForRow:itemIndex inSection:subsectionIndex];
}
Here's a detailed post如何做到这一点。
答案 1 :(得分:2)
像robin建议的那样,子类化UITableView
将是一个不错的选择。我自己也做了类似的事情,但是我将UITableViewCell
子类化,并将UITableView
置于其中。在这种情况下,您将拥有一个基表tableView,其中每个部分都是一个组。因为你子类UITableViewCell
,每一行都是它自己的UITableView
,它有自己的部分和行。这应该为您提供您正在寻找的外观和功能。如果您在使用它时遇到困难,我很乐意帮助您进行设置,但这并不难。 This tutorial提供了一个很好的示例,如何创建UITableViewCell
的子类,并且是一个开始的好地方
答案 2 :(得分:0)
如果有人对上述代码的Swift 4.2版本感兴趣,那就在这里。
为了具有嵌套的节,您需要在tableView中包含几种类型的行。首先代表第二级部分,其次代表tableView中的标准行。假设您有一个两级数组(节)来表示tableView中的项目。
然后,我们拥有的部分总数仅是顶级部分的数目。每个顶级部分中的行数将是子部分数+每个子部分中的行数。
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionItems = sections[section]
var numberOfRows: Int = sectionItems.count // For second level section headers
for rowItems: [Any] in sectionItems as? [[Any]] ?? [] {
numberOfRows += rowItems.count // For actual table rows
}
return numberOfRows
}
现在,您需要考虑的就是如何为tableView创建行。在情节提要中设置两个具有不同重用标识符的原型,一个用于节标题,另一个用于行项目,然后根据数据源方法中的要求实例化正确的原型。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var sectionItems = sections[indexPath.section]
var sectionHeaders = self.sectionHeaders[indexPath.section]
let itemAndSubsectionIndex: IndexPath? = computeItemAndSubsectionIndex(for: indexPath)
let subsectionIndex = Int(itemAndSubsectionIndex?.section ?? 0)
let itemIndex: Int? = itemAndSubsectionIndex?.row
if (itemIndex ?? 0) < 0 {
// Section header
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "SECTION_HEADER_CELL", for: indexPath)
cell.textLabel?.text = sectionHeaders[subsectionIndex] as? String
return cell
} else {
// Row Item
let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "ROW_CONTENT_CELL", for: indexPath)
cell.textLabel?.text = sectionItems[subsectionIndex][itemIndex ?? 0] as? String
return cell
}
}
func computeItemAndSubsectionIndex(for indexPath: IndexPath?) -> IndexPath? {
var sectionItems = sections[Int(indexPath?.section ?? 0)]
var itemIndex: Int? = indexPath?.row
var subsectionIndex: Int = 0
for i in 0..<sectionItems.count {
// First row for each section item is header
itemIndex = (itemIndex ?? 0) - 1
// Check if the item index is within this subsection's items
let subsectionItems = sectionItems[i] as? [Any]
if (itemIndex ?? 0) < Int(subsectionItems?.count ?? 0) {
subsectionIndex = i
break
} else {
itemIndex -= subsectionItems?.count
}
}
return IndexPath(row: itemIndex ?? 0, section: subsectionIndex)
}