侧边栏壁纸
  • 累计撰写 28 篇文章
  • 累计创建 10 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Observable objects, environment objects, and @Published

Jserv
2025-04-28 / 0 评论 / 0 点赞 / 4 阅读 / 2584 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2025-04-28,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

[本文翻译自hackingwithswift,点击链接阅读原文]

我们希望人们通过选择物品并将其添加到购物车来下订单取货。我已经给了你一个专门的Order类,它包含一系列项目,因此我们将向该类添加项目,然后在专用订单视图中显示它们。

但有一个陷阱:如果我们在ItemDetail中添加内容,我们如何在完全独立的OrderView中显示它们?更重要的是,随着事情的变化,我们如何确保这两个人相互更新?

嗯,SwiftUI有一个非常棒的解决方案,叫做环境对象。这些对象是我们的观点可以自由使用,但不能创建或管理——它们在其他地方创建,并在观点消失后继续存在。

在这个应用程序中,我们将在应用程序启动时创建一个订单实例,然后将其传递到我们的内容视图中。该内容视图中的任何视图——任何可以将内容视图称为其祖先的视图——都将自动访问该环境对象。更好的是,当任何视图更改它时,所有其他地点都会自动更新。

我们现在试试吧。打开您的iDineApp.swift,这是我们创建ContentView初始实例的地方。现在给它这个属性:

@StateObject var order = Order()

提示:当您添加该行时,Xcode将显示错误,没关系——我们一会儿就会修复它。

当应用程序启动时,这会创建一个新的顺序,并保持它活跃,无论我们显示什么视图。@StateObject属性包装器负责在我们应用程序的整个生命周期内保持对象的活力。

现在,我们可以在创建ContentView结构时将其传递到我们的ContentView结构中——查找以下内容:

WindowGroup {
    ContentView()
}

并用这个替换它:

WindowGroup {
    ContentView()
        .environmentObject(order)
}

现在,我说,当我们使用@StateObject属性时,Xcode会抛出一个错误——类似“参数类型'Order'不符合预期类型'ObservableObject'”。

这意味着SwiftUI不了解其用户界面应该如何监视我们的Order类的更改——它不了解如何发送和接收数据更改的通知。

想一想:如果我们从菜单中选择一些食物并将其添加到我们的订单中,我们希望它立即出现在订单页面上——我们不想点击刷新,或者等待几秒钟,我们希望立即。为了发挥作用,SwiftUI需要一种标准方式,让像Order这样的对象说“嘿,如果有人在看着我,你应该知道我的数据刚刚更改了。”

这个标准已经存在,它是ObservableObject协议。任何符合ObservableObject的东西都可以在SwiftUI中使用,并在其值发生变化时发布公告,以便更新用户界面。

苹果提供了几种不同的发布更改公告的方式,但最简单的是在任何应该触发更改通知的属性之前使用@Published属性包装器。在这种情况下,只需在属性之前放置@Published就足以让它更新任何正在关注更改的SwiftUI视图——它真的很强大!

因此,打开Order.swift,并将items属性更改为:

@Published var items = [MenuItem]()

就是这样!现在我们的类配置正确,我们可以让它符合ObservableObject,如下:

class Order: ObservableObject {

...我们的代码又恢复了编译。总体而言,我们已经更新了Order,以便它知道如何宣布对任何正在观看的视图的更改,我们已经告诉items组,每当它发生变化时,它都应该发送这样的公告,我们在主应用程序中创建了Order对象的实例,并将其放置在SwiftUI环境中供其他视图使用——很好!

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区