SwiftUI — Combine 实践 双向绑定和时间机器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SwiftUI — Combine 实践 双向绑定和时间机器相关的知识,希望对你有一定的参考价值。

参考技术A 学习完 苹果的教程
我们知道了通过@State 就可以实现 数据和UI的绑定
修改APP就可以直接修改数据的State 例如

当点击Button的时候会修改数据,同时SwiftUI会reload页面
做过大型一点的APP的同学都会知道 当你们公司出现数据部门的时候
APP端就会要求打点 对用户当前所做的操作做记录 那么用户的所有操作都会定义一个State 我们就可以创建一个protocol 来完成这件事

用户操作后你就要记录下来 那么通过上面你就可以知道我们可以创建一个记录操作的类 在用户操作的时候自动记录
数据部门还会有需求,把用户的操作链式表现,那么就可以用数组装下他
创建一个全局的Store,并增加一个方法记录TodoState

说到这里呢,最后把数据上报,就已经完成了数据部门的要求。
我们已经完成了View对State的绑定,学过前端的同学就知道,前端一般都会实现双向绑定,单向绑定非常简单,就是 用户修改View,也更新了State的数据。有单向绑定,就有双向绑定。如果用户更新了State时,View就会自动更新,这种情况就是双向绑定。

把UI根据当前的State绑定

那么UI绑定已经绑定State,那怎么实现State发生变化View就能变化了,那我们就可以让Store成为一个ObservableObject,绑定方法也修改,当前State需要改变时,发布change,当currentState发生变化的时候就可以让View发生变化了

最后既然我们都实现了双向绑定那么就可以手动修改currentState看一下,用一个Slider绑定currentStateIndex

当你拖动Slider的时候,是不是就有种时间机器的感觉,可以回到任意的State,看一下效果

SwiftUI/Combine 发布者是双向的吗?

【中文标题】SwiftUI/Combine 发布者是双向的吗?【英文标题】:SwiftUI/Combine Are publishers bi-directional? 【发布时间】:2021-08-01 20:08:09 【问题描述】:

这段代码的执行让我很困惑:

class RecipeListViewModel: ObservableObject 
    
    @Published var recipeList = [RecipeViewModel]()
    
    init()

        RecipeRepository.$allRecipeVMs.map  recipes in
            recipes.map  recipe in
            recipe
            
        
        .assign(to: &$recipeList)
    

我的理解是 SwiftUI 发布者是单向的,这意味着当 RecipeRepository.allRecipeVMs 被修改时,recipeList 也是如此。但是,我看到的行为是当recipeList 更新时,RecipeRepository.allRecipeVMs 也会更新。我试图找到这方面的文档,但似乎找不到任何东西。

这里是RecipeViewModel 类,不确定是否有用:

class RecipeViewModel : Identifiable, ObservableObject, Hashable
    
    var id = UUID().uuidString
    @Published var recipe: Recipe

    init(recipe: Recipe)

        self.recipe = recipe
    

【问题讨论】:

您能否附上一个minimal reproducible example 来证明您所描述的内容?例如,我想看看RecipeRepository 中的内容...我对allRecipeVMs 持怀疑态度 @jnpdx 我将致力于创建一个可重现的示例,但 allRecipeVMs 是 [RecipeViewModel]。 这是一个危险信号,你有一个由 ObservableObject 组成的 @Published 数组——这不会像你期望的那样工作。 【参考方案1】:

目前尚不清楚您所调用的“修改”是什么。 @Published 和 SwiftUI 查看不同的值类型,而您已经创建了一个引用类型数组。仅当该对象的实例发生更改时才会有差异,而不是当对象本身触发其 ObjectWillChange 发布者时。

坦率地说,这是一个非常有用的设置,因为您可以拥有在应用程序中分发和管理依赖项的容器,而不会导致根视图层次结构不断变化和重建。

如果您想要某种双向委托关系,您可以简单地将 VM 中的弱变量设置为 self。

【讨论】:

是的,这是正确的,我认为这是Combine 在幕后所做的事情,但是当recipeList 子项的属性发生更改时,RecipeRepository.allRecipeVMs 数组已更新,因为RecipeViewModel 是一个类(引用类型)。 某处的错误可能是以后的功能:) 享受

以上是关于SwiftUI — Combine 实践 双向绑定和时间机器的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI/Combine 发布者是双向的吗?

SwiftUI ObjectBinding 不会使用 combine 接收来自可绑定对象的 didchange 更新

SwiftUI/Combine 通知用不正确的值覆盖我的结构

SwiftUI 双向绑定到枚举案例中 ObservableObject 中的值

在 SwiftUI 中捕获绑定的最后一次更改 / 组合

从现有的 SwiftUI @States 派生绑定