【问题标题】:How to do a sharedViewModel in iOS like we have in Android?如何像我们在 Android 中一样在 iOS 中执行 sharedViewModel?
【发布时间】:2021-06-30 23:26:37
【问题描述】:

我主要开发 Android 应用程序,现在开始涉足 iOS 应用程序开发。我正在构建的应用程序用于学习目的,用于订购咖啡。流程是:

  • 屏幕 1 选择混合 (MainViewController)
  • 屏幕2选择尺寸(SizeViewController)
  • 屏幕 3 选择风味 (FlavorViewController)
  • 屏幕 4 显示总计和支付 (FinalViewController)

我从一个屏幕转到下一个屏幕。根据大小和口味更新总价,我想在每个屏幕上显示更新后的总价(屏幕 1 除外)。在最后的屏幕上,我想显示大小、味道,当然还有总的。我有一个在 sizeViewController 中实例化的 CoffeeModel。模型计算总价如下:

mutating func updateTotal() {
    let coffeePrice = getPrice(for: selectedCup)
    let flavorPrice = getFlavorPrice(for : selectedFavor)
    
    total = coffeePrice + flavorPrice
    
    delegate?.updateTotal(to: total)
}

然后 SizeViewController 可以通过委托获取价格。

现在的问题是当用户点击下一步并导航到 FlavorViewController 时,我如何使用相同的 CoffeeModal。我是否需要将此模型传递给准备功能中的下一个控制器? 如果我创建一个新的,那么我将失去总数,它将是一个单独的咖啡模型实例。

在 Android 中,我可以执行 sharedViewModel 之类的操作。 iOS中是否有类似的东西?有人可以指导我正确的方向,我应该遵循什么样的架构?

有趣的是我在写这个问题的时候实际上是在喝咖啡:)

【问题讨论】:

  • 使用的是 uikit 还是 SwiftUI?您管理状态和模型的方式在这两个框架之间有所不同。无论如何,基本实现是您在视图之间传递的模型对象。而不是程序 updateTotal 我将有一个计算变量,它根据模型的属性返回当前价格;大小、混合、风味等。计算总数的工作量并不是特别大。
  • 我注意到您指的是视图控制器,因此您可能正在使用 uikit。如果您正在使用情节提要场景,那么您可以简单地将模型传递给 prepareForSegue。委托可能不是这里最好的方法,因为您有多个视图控制器对更新的价格感兴趣。 UiKit 没有内置绑定,因此使用程序代码在用户进行选择时简单地更新每个屏幕中的价格标签可能是最简单的。
  • 我正在使用 UIKit。 SwiftUI 中有没有更好的方法。顺便说一句,我喜欢 SwiftUI 只是因为它很容易在其中制作 UI。

标签: ios swift architecture


【解决方案1】:

你最好使用singleton:

例如为 Total 类创建 singleton

class Total {
    static let shared =  Total()
    var currentTotal = 0
}

每次我想更新时说 300:

func update () {
    Total.shared.currentTotal = Total.shared.currentTotal + 300
}

每次我想得到总成本:

func getTotalCost() -> Int {
    return Total.shared.currentTotal
}

【讨论】:

  • 我是否必须同时制作风味、混合和大小,因为我希望能够在最终屏幕上显示它们?
  • 您可以使用单例,但通常不鼓励使用单例,因为它们会导致测试能力出现问题。在场景之间切换时,您可以简单地传递对模型的引用。
  • 我同意你关于单例和可测试性的问题。但是回到你的答案,如果用户从屏幕 3 到 2 到 1 导航回来怎么办。我是否必须将模型(参考)传回?
  • 不,因为你会回到之前的实例。不过,我会为您的模型使用类而不是结构,以便获得引用而不是值语义。
  • @Paulw11,我喜欢你的回答,但我不能接受评论作为答案。我还研究了 SwiftUI 和状态管理。我也会尝试这样做,因为这很有意义。
【解决方案2】:

正如 Paulw11 所建议的,我可以将引用传递给下一个视图控制器。但我认为我不会使用 UIKit,而是使用 SwiftUI,因为它提供状态管理等等。

作为一名 Reactjs 开发人员,我发现 SwiftUI 是完成这项任务的更好解决方案。

【讨论】:

    猜你喜欢
    • 2019-07-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    • 2015-10-16
    • 1970-01-01
    • 2021-12-05
    相关资源
    最近更新 更多