功能视图构建
在情节提要中还是在代码中创建视图? 作为iOS开发人员,我们非常清楚这个问题。 他们两个都有优点和缺点,但是最近我越来越喜欢用代码创建的视图。
什么是架构?
我曾经将MVVM与RxSwift一起使用,这基本上意味着控制器是通过结合Storyboard
, ViewController
和ViewModel
来创建的。 如果我们删除Storyboard界面,则在哪里构建视图的正确位置?
让我介绍一下ViewBuilders。
考虑一下当我们构建一个称为HomeViewController
控制器时的情况。 让我们创建一个名为HomeViewBuilder
的帮助程序结构,该结构最终返回HomeView
,该抽象使我们能够访问组件(等效于插座)。
因此,我们最终得到以下架构:
HomeViewBuilder的结构:
也许您已经猜到我们要通过管道化一些操作(例如添加/设置适当的组件)来构建此视图。 让我们定义一个简单的ViewBuilder
协议:
我们还定义实现ViewBuilder
HomeViewBuilder
。
当然,最重要的部分是buildView
函数。 我故意向您展示了此方法的最终版本 。 这是唯一可以从外部访问的公共方法,这是一种梦想,我们现在要实现。
首先 ,让我们介绍流行的管道和函数组合运算符,这些运算符允许我们组合函数和对象:
管道运算符用于buildView
函数中,其基本外观如下:
- 组成从类型
Builder
功能到Builder
- 将此转换应用于创建的构建器
好的,看起来不错,但是这些 install
/ setup
功能 如何 工作?
如果您对镜头了解不多,则一定要观看一些视频,了解这种模式的工作原理。 我在这里使用它们来编写单独的小段代码,并使它们可重用。 让我们考虑使用vertical
轴创建UIStackView
并将translatesAutoresizingMaskIntoConstraints
标志设置为false
。 我们将在项目中使用多少个? 当然很多
我创建了一些项目全局的Style
结构,该结构定义了常用的样式,这些样式是(View) -> View
类型的转换函数。 这里有些例子:
因此,让我们构建使用其中一种样式的UIStackView
。 这是典型installer
功能的实现:
多亏了镜头组成,它看起来很清晰,我们在应用程序中获得了很多可重用性。 但是,等等,我们错过了重要的约束设置……
问题
通过使用锚,我们可以很容易地通过将一个锚连接到另一个锚来生成约束。 但是在这里,我们失去了像镜头所使用的流程那样通用和通用的功能。
解决方案:让我们定义另一个构建器。
我创建了一个名为FunctionalBuilders的库,该库包装了约束构建并使其使用起来更加美观。 它的构造类似于ViewBuilder
。 这是installLabelsStackView
函数缺少的行:
它看起来又像是由流程组成的一组函数,我们曾经设置了目标视图(我们要附加约束的视图),并且只为约束生成函数传递源。 除了constant
可以传递给约束生成函数外,还有更多典型的选择,例如:
-
relation
枚举equal
,less
或greater
。 这些情况相当于名称较短的NSLayoutRelation
, -
priority
-
multiplier
(用于宽度和高度)
可以随意使用该库(但请注意,这是其开发阶段的开始😅)。
因此,在这里,我将提供安装所有组件并将其附加到HomeView
最终HomeViewBuilder
代码:
最后的笔记
- 毕竟如何使用它?
全部来自HomeViewController
。 看起来很完美!
2.在编写ViewBuilder
定义执行某些特定逻辑的简短方法,就像install
, setup
方法一样。
3.定义一个具有通用样式的Style
结构,并进行fileprivate
扩展,以在同一构建器结构中创建可重用的样式。
4.当然,也可能并建议在视图构建器中使用其他视图构建器。
5.我喜欢定义typealias Builder = ...
,这使得在特定的builder中定义更短。
随意提出一些更好的解决方案,正如我之前所说的,这是FunctionalBuilders开发的开始。