如何更优雅地在表格视图中添加/删除单元格?

Posted

技术标签:

【中文标题】如何更优雅地在表格视图中添加/删除单元格?【英文标题】:How can I add/remove cells in a table view more elegantly? 【发布时间】:2016-05-17 14:10:44 【问题描述】:

我认为这可能是一个 X Y 问题,所以我先提供一些背景信息。

我正在构建一个可以显示“表单”的应用程序。用户可以用一些东西填写表单并创建一些自定义的东西。

我认为最合适的做法是为表单使用表格视图。我可以在每个表格单元格中显示所有需要填写的文本框。

截图如下:

点击“添加新输入”按钮时,它会在底部插入一个新单元格。如果你向左滑动其中一个输入,你会得到一个“删除”按钮。您可以使用它来删除输入。

如您所见,这个表格视图需要添加和删除行。

最初,我使用的是一个名为“TableViewModel”的 cocoapod,这让这变得超级简单。但后来我在图书馆里找到了a really severe bug,所以我不想再使用它了。

我尝试使用表格视图的deleteRowsAtIndexPathsinsertRowsAtIndexPaths 方法。但如果我这样做:

override func numberOfSectionsInTableView(tableView: UITableView) -> Int 
    return 1


override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return 1


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    let cell = UITableViewCell()
    cell.textLabel?.text = "Hello"
    return cell


// I use motionEnded here because I don't want to add a button or anything just to test this
override func motionEnded(motion: UIEventSubtype, withEvent event: UIEvent?) 
    tableView.deleteRowsAtIndexPaths([NSIndexPath(forRow: 0, inSection: 0)], withRowAnimation: .Fade)

我删除一行后会出现表视图与数据源不一致的异常。这意味着我必须有代码来处理这种不一致。这肯定会让我的代码更难阅读。

插入方法也是如此。

另外,我需要跟踪每个部分中有多少行。而且我的代码变得非常混乱且无法维护。

我也搜索了其他库,但它们都很奇怪,不像“tableViewModel”那么简单。他们似乎都要求我为表格视图创建一个模型。在我的情况下,我不明白该怎么做。我只想显示一堆文本字段!

如何更优雅地插入或删除行?我想我要么需要为表格视图编写extension,要么学习为我的表格视图编写模型。但是这两种方法我都做不到。

【问题讨论】:

因为您没有任何数据源。另请参见逻辑:假设您使用 insertRowsAtIndexPaths 添加新行。所以现在你有 2 行。但是你的 numberOfRowsInSection 总是返回 1。所以它会崩溃,反之亦然删除。表格视图应该与集合(NSArray、NSDictionary、NSSet 等)一起使用。 问题是,当您添加或删除一行时,您总是说该部分中只有 1 行。您必须使用数组或字典来跟踪每行和每个部分中有多少数据(以及哪些数据),并在 numberOfSectionsInTableView:tableView:numberOfRowsInSection:` 中返回该值。 你的意思是我不应该使用表格视图来做这种表格?那我能用什么做呢? @Alok @Larme 是的,我知道。这就是为什么我说它不优雅。我需要添加这么多样板。它使代码更难阅读和维护。我在问如何以一种使我的代码更易于阅读的方式来做到这一点。 【参考方案1】:

因为您没有任何data source。另请参阅logically:假设您使用 insertRowsAtIndexPaths 添加新行。所以现在你有2 rows。但是你的numberOfRowsInSection 总是返回 1。所以它会崩溃,反之亦然删除。表格视图应该与collectionNSArrayNSDictionaryNSSet 等)一起使用。 为了您的帮助:

Already they have nade a form as yours

obj-c easy to understand how table view with data source work

Adding, Updating, Deleting and Moving records using Swift.

【讨论】:

【参考方案2】:

您可以使用TableView 创建表单,但您必须设计适当的数据源来跟踪这些数据。现在dataSource方法必须修改为

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return yourDataSourceForSection.count

您可以在执行删除操作时编辑此数据源,如下所示

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) 
    if editingStyle == .Delete 
        //Delete the row from the data source to ensure consistency
        self.array.removeAtIndex(indexPath.row)
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
    

您可以使用模型类作为dataSource

class NewCustomOperation: NSObject 
   var name: String?
   var rejectFloatingPoints: Bool?
   var inputs: AvailableInputs?
   var results: Results?


class AvailableInputs: NSObject 
   var name: [String]?
   var description: [String]?


class Results: NSObject 
   var name: [String]?
   var formula: [String]?

【讨论】:

是的,我知道,但是如果我有一堆文本字段供用户填写,而不是显示一堆数据,那么数据源会是什么? 您考虑过使用堆栈视图吗?也许需要做很多工作,但他们会为您管理界面超级流畅。 @user3069232 但我使用的是 ios8,但我认为堆栈视图不可用。 不知道有什么计划或要求,但是 IOS 10.0 指日可待,你应该至少升级到 IOS 9.x,是什么让你 @ IOS 8.0 ? 我已经添加了一个模型类作为您的数据源的示例【参考方案3】:

我找到了解决办法!

我基本上保留了一组单元格数组以供表格视图显示:

var cells: [[UITableViewCell]] = [[], [], []] // I have 3 sections, so 3 empty arrays

然后我添加了这些数据源方法:

override func numberOfSectionsInTableView(tableView: UITableView) -> Int 
    return cells.count


override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return cells[section].count


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    return cells[indexPath.section][indexPath.row]

现在,我可以超级轻松地添加和删除单元格了:

func addCellToSection(section: Int, index: Int, cell: UITableViewCell) 
    cells[section].insert(cell, atIndex: index)
    tableView.insertRowsAtIndexPaths([NSIndexPath(forRow: index, inSection: section)], withRowAnimation: .Left)


func removeCellFromSection(section: Int, index: Int) 
    cells[section].removeAtIndex(index)
    tableView.deleteRowsAtIndexPaths([NSIndexPath(forRow: index, inSection: section)], withRowAnimation: .Left)

只需两行,我就可以添加/删除带有动画的单元格!

【讨论】:

以上是关于如何更优雅地在表格视图中添加/删除单元格?的主要内容,如果未能解决你的问题,请参考以下文章

如何从表格视图单元格中的图像手势获取 indexPath

表格视图单元格的按钮与其他单元格混淆?

重新排序单元格时如何在 UITableViewcell 内容视图中添加图像?

如何在一个表格视图中添加三个表格视图单元格作为子视图?

如何动画从表格视图(rxswift)中删除单元格?

以编程方式将按钮添加到表格视图单元格[关闭]