如何使用静态单元支持重新创建 UITableViewController?

Posted

技术标签:

【中文标题】如何使用静态单元支持重新创建 UITableViewController?【英文标题】:How to recreate UITableViewController with static cells support? 【发布时间】:2015-05-24 07:20:30 【问题描述】:

我有很多共同的逻辑,因此我所有的 viewController 都继承自 BaseViewController、BaseDetailsViewController 或 BaseWebViewController。最后两个继承自从 UIViewController 继承的 BaseViewController。问题是我不能将 tableViews 与静态单元格一起使用,因为我的 BaseDetailsViewController 不是从 UITableViewController 继承的。

我从来没有使用和继承过 UITableViewController,因为同样可以通过从 UIViewController 继承、将其与添加的 UITableView 连接并实现数据源和委托方法来实现。因此,对于表单类型屏幕(SignUp 或其他数据输入屏幕),我使用自己的 BaseDetailsViewController,它添加了一些不错且方便的方法(输入验证、自定义样式、滚动键盘、处理输入字段导航等)

使用 UITableViewController 有两个真正的好处:1)键盘滚动(如果您使用文本字段)和 2)在屏幕上轻松创建表单 UI 元素。第一个好处对我来说无关紧要,因为我已经在 BaseDetailsViewController 中实现了这些东西。关于第二个好处,我在 scrollView 中创建了我的表单,它提供了很大的灵活性,但需要更多的努力(尤其是在需要更新屏幕时)。因此我听说有些人实现了他们自己的 UITableViewController,然后让它继承自他们的 BaseViewController。因此我开始深入研究这种方法。

到目前为止,我遇到了这两种方法:

    Recreate your own tableVC。不清楚如何使其适用于静态单元格。目前,如果我的 ReplaceTableViewController 没有实现 numberOfRows 和 cellForRow,我的演示应用程序会崩溃,如果我使用虚拟内容实现它们,则不会显示静态单元格。 method-swizzling。不清楚如何通过为 UITableViewController 注入 baseViewController 继承来改变类继承,目前还不清楚需要添加哪些方法。

有人尝试过并想分享吗?

更新我没有使用故事板,因为我提倡干净的 MVC - 作为组件的每个屏幕都应该有自己的模型、视图 (Xib) 和控制器,所有这些都存储在单独的文件中以消除合并冲突大型应用项目(30 多个屏幕)中的多个开发人员。因此,带有嵌入到 tableViewController 的 segue 的容器视图也不是一种选择。

UPDATE2 如果有人想看看我为什么以及如何这样做,这里是我最近开始发布的开源template based new project generator framework 的链接。

【问题讨论】:

那你为什么不用电视呢?你的问题很长,你问的不是很清楚。 那么您真的想使用您的自定义 VC 并在情节提要中设计您的表格,并使用最少的代码吗? @Schemetrical。我所有的 viewController 都直接或间接地从继承自 UIViewController 的 BaseViewController 继承。这不允许将 tableView 与静态单元格一起使用。我不想使用 tvc,因为那样我将无法在所有 viewController 上拥有通用功能(BaseViewController)(无代码重复)。问题是如何在不使用 tvc 和故事板的情况下使静态单元工作。 您应该为通用功能 (MVC) 使用单独的类,这是一种很好的做法,并且比从父级继承方法要好得多。如果它只是您正在寻找的通用功能,则不应从一个类继承,除非通用功能包括 UI 处理和自定义。 @Schemetrical 非常细化的组合有其自身的缺点,比如过度复杂的代码。所以这个世界有时候也有传承的地方。如果您不同意,那么您应该编写自己的关于 OOP 的理论,其中根本不包括继承。无论如何,问题更多是关于如何去做,而不是为什么,因为所有的论点都给出了,而且总是有相反的论点。是的,我的常用功能包括 UI 处理。 【参考方案1】:

静态单元格需要一个 UITableViewController。您现在无法更改此设置。

但是要在 UITableViewController 之外的 UITableView 中使用静态单元格,您可以在 Non-Table-UIViewController 中使用 ContainerView,您可以在其中放置一个真实的、单独创建的 UITableViewController 来处理这些静态单元格。

要在多个视图控制器之间共享公共代码,继承并不是您在继承 UIViewController 和 UITableViewController 时自己发现的最佳解决方案。您可以使用某种组合来共享代码或 - 特别是对于 Objective-c - 类别。

类别不允许有自己的属性,但有workarounds possible with objc_setAssociatedObject。

另一种方法是不使用静态单元格,而是使用带有 DataSource-Delegate 的 UITableView 中的动态单元格:)

正如您在我的屏幕截图中看到的,为了重用具有静态单元格的特殊 TableView,我将其放置在 ContainerView 中的其他 ViewController 中。由于您没有使用情节提要,我很确定这也可以通过没有情节提要的代码来完成。

【讨论】:

我同意组合,但是正如我在评论中所写的,您可能知道非常精细的分解会使代码复杂化,有时是不必要的。我所有的公共代码都已经解耦成单独的类并通过接口访问,但是 viewController UI 特定的公共代码很好地位于这些 BaseViewController 中。强迫改变这一点不会有任何真正的好处。同时,我更关心大量故事板的兴奋,因为它确实阻碍了关注点分离和干净的 MVC 方法,并引入了不必要的合并冲突。 是的,故事板真的会搞砸,尤其是当不止一个人在做的时候。正是您的情况,也无法使用 UITableViewController 重用自定义 UIViewController-Subclasses,这阻止了我在这里进行子类化。我的 Databindings 来自基于 ReactiveCocoa 的 DataModels,所以我不需要巨大的 ViewControllers。确实,它们很小 如果您有兴趣发表评论,我已经开始推送我的基于开源模板的项目生成器框架 (github.com/GitTennis/SuccessFramework/tree/master/Templates/…),它实现了我正在谈论的所有这些事情。我想到了 ReactiveCocoa,尽管我通常会尽量避免使用 KVO,可能是因为广播通知过多导致堆栈跟踪泛滥并且难以调试。相反,我使用老式的模型和数据对象分离类型并手动进行视图模型绑定。无论如何,有很多不同的方法要怎么走..

以上是关于如何使用静态单元支持重新创建 UITableViewController?的主要内容,如果未能解决你的问题,请参考以下文章

swift4中的UITextfield验证 - 动态单元格

如何仅使用静态单元格创建集合视图? [复制]

通过单击更改单元格中的颜色和内容(静态)并在重新加载后保持更改

如何在嵌入 UIViewController 的 UITableView 中直观地创建和使用静态单元格

重新加载表格视图后出现最后一个静态单元格分隔线

如何在 .xib 文件中使用自定义 UITableView 和 UITableViewCell?