Tag: 功能编程

功能视图

视图是iOS应用程序的基础构建块。 随着您获得更多的经验或开始从事复杂的项目,编写视图的方式将会发展,并且您将开始更加关注设计模式,可测试性和一致性。 有很多方法可以尝试! 我们在iZettle的经验使我们找到了一种有趣的实用方式来思考我们想分享的观点。 假设我们有一个视图层次结构,可以在几个地方重用。 它由一个标签和一个文本字段组成,它们看起来像这样: 我们通常将如何组织与它们相关的代码? 从熟悉的方法开始 实现此层次结构的一种流行方法是创建UIView的子类,该子类将知道如何呈现其子视图。 我们将其称为PriceView 。 如您在图像中所见,在这种情况下,两个子视图很简单,因此不需要任何特殊的渲染代码。 我们将实例化它们,将它们添加为子视图,并指定样式和布局规则。 像这样: 传递输入数据 我们的PriceView有一些输入和输出。 让我们讨论它如何接收金额更新和描述占位符。 在上例中,子视图被公开为公共属性。 这样, PriceView不会封装其实现细节,无论显示在哪里,我们都将紧密耦合。 例如,如果文本字段需要替换为文本视图,则我们将不得不在多个位置更改代码。 我们可以做得更好! 我们可以将子视图设置为私有属性,并仅公开采用输入的配置方法并将其内部传递给子视图。 这意味着在我们的实现中,我们将在一个地方创建子视图,并在另一个地方设置它们的状态。 现在让我们尝试一种更被动的方式来处理输入数据。 我们可以通过初始化程序传递所有数据源。 对于应该在外部进行更改的事情,我们可以传递一个可观察的类型。 在不同的反应式框架中对此有很多看法-在我们的示例中,我们将使用iZettle的Flow框架及其ReadSignal类型。 对于不变的东西,例如占位符文本,我们只需传递值即可。 这种方法使我们可以在一处创建子视图,对其进行订阅并对所有可观察对象做出反应。 处理用户输入 触摸事件和其他用户交互如何? 我们可以使用熟悉的委托模式 -在PriceView中配置一个可以处理事件的对象。 如果我们希望有一个对象对PriceView的输出做出反应,但不缩放到多个对象,则此方法效果很好。 另外,对于广播到多个对象,我们可以使用通知和观察模式 。 但是,实施观察者管理可能是一项繁琐的任务[1]。 与输入一样,我们也可以在此处使用反应模式 。 如果PriceView公开了一个可观察的类型,我们可以通过它广播事件,而不必关心有多少对象观察到它-零个,一个或多个。 Flow的信号类型也可以在这里为我们提供帮助。 放在一起 因此,我们已经看到将信号用于输入和输出具有一些好处,并且可以将它们放在一起。 在这一点上,我们可以质疑为什么我们应该首先继承UIView ,因为我们没有绘制任何复杂的东西。 我们可以通过将输入移至结构的属性,并将视图创建移至返回简单UIView和输出信号的函数来进行清理。 酷吧? 注意:我们将PriceView的名称更改为PriceDescriptionEntry ,因为它更清楚地表达了我们想要表示的意图。 PriceDescriptionEntry现在是一个定义,可以多次传递和实例 化以创建视图。 我们如何使用这个 iZettle的应用程序已经发展了八年,并且代码库和团队正在迅速增长。 为了保持一致,我们倾向于将类似的解决方案应用于相似的问题。 […]