功能视图构建

在情节提要中还是在代码中创建视图? 作为iOS开发人员,我们非常清楚这个问题。 他们两个都有优点和缺点,但是最近我越来越喜欢用代码创建的视图。

什么是架构?

我曾经将MVVM与RxSwift一起使用,这基本上意味着控制器是通过结合StoryboardViewControllerViewModel来创建的。 如果我们删除Storyboard界面,则在哪里构建视图的正确位置?

让我介绍一下ViewBuilders。

考虑一下当我们构建一个称为HomeViewController控制器时的情况。 让我们创建一个名为HomeViewBuilder的帮助程序结构,该结构最终返回HomeView ,该抽象使我们能够访问组件(等效于插座)。

因此,我们最终得到以下架构:

HomeViewBuilder的结构:

也许您已经猜到我们要通过管道化一些操作(例如添加/设置适当的组件)来构建此视图。 让我们定义一个简单的ViewBuilder协议:

我们还定义实现ViewBuilder HomeViewBuilder

当然,最重要的部分是buildView函数。 我故意向您展示了此方法的最终版本 。 这是唯一可以从外部访问的公共方法,这是一种梦想,我们现在要实现。

首先 ,让我们介绍流行的管道和函数组合运算符,这些运算符允许我们组合函数和对象:

管道运算符用于buildView函数中,其基本外观如下:

  1. 组成从类型Builder功能到Builder
  2. 将此转换应用于创建的构建器

好的,看起来不错,但是这些 install / setup 功能 如何 工作?

如果您对镜头了解不多,则一定要观看一些视频,了解这种模式的工作原理。 我在这里使用它们来编写单独的小段代码,并使它们可重用。 让我们考虑使用vertical轴创建UIStackView并将translatesAutoresizingMaskIntoConstraints标志设置为false 。 我们将在项目中使用多少个? 当然很多

我创建了一些项目全局的Style结构,该结构定义了常用的样式,这些样式是(View) -> View类型的转换函数。 这里有些例子:

因此,让我们构建使用其中一种样式的UIStackView 。 这是典型installer功能的实现:

多亏了镜头组成,它看起来很清晰,我们在应用程序中获得了很多可重用性。 但是,等等,我们错过了重要的约束设置……

问题

通过使用锚,我们可以很容易地通过将一个锚连接到另一个锚来生成约束。 但是在这里,我们失去了像镜头所使用的流程那样通用和通用的功能。

解决方案:让我们定义另一个构建器。

我创建了一个名为FunctionalBuilders的库,该库包装了约束构建并使其使用起来更加美观。 它的构造类似于ViewBuilder 。 这是installLabelsStackView函数缺少的行:

它看起来又像是由流程组成的一组函数,我们曾经设置了目标视图(我们要附加约束的视图),并且只为约束生成函数传递源。 除了constant可以传递给约束生成函数外,还有更多典型的选择,例如:

  • relation枚举equallessgreater 。 这些情况相当于名称较短的NSLayoutRelation
  • priority
  • multiplier (用于宽度和高度)

可以随意使用该库(但请注意,这是其开发阶段的开始😅)。

因此,在这里,我将提供安装所有组件并将其附加到HomeView最终HomeViewBuilder代码:

最后的笔记

  1. 毕竟如何使用它?

全部来自HomeViewController 。 看起来很完美!

2.在编写ViewBuilder定义执行某些特定逻辑的简短方法,就像installsetup方法一样。

3.定义一个具有通用样式的Style结构,并进行fileprivate扩展,以在同一构建器结构中创建可重用的样式。

4.当然,也可能并建议在视图构建器中使用其他视图构建器。

5.我喜欢定义typealias Builder = ... ,这使得在特定的builder中定义更短。

随意提出一些更好的解决方案,正如我之前所说的,这是FunctionalBuilders开发的开始。