【问题标题】:How can I make view to update when current time passes the threshold in SwiftUI?当当前时间超过 SwiftUI 中的阈值时,如何更新视图?
【发布时间】:2020-12-06 17:53:00
【问题描述】:

我的应用从远程服务器获取模型数据。这个模型有一个带有 epoch 值的字段,SwiftUI 视图应该根据当前时间是否已经过了 epoch 来显示不同的视图。

模型如下所示。

struct Order: Decodable {
    var expireAt : Int
    
    func isExpired() -> Bool {
        let epoch = Int(Date().timeIntervalSince1970)
        return expireAt < epoch
    }
}

视图如下所示。

struct OrderView: View {
    @EnvironmentObject var rs : RemoteService
    var body: some View {
        if rs.hasOrder() {
            NavigationView {
                VStack {
                    if rs.Order != nil &&  rs.Order!.isExpired() {
                        Text("Your order has expired")
                    } else {
                        Text("Your order has not expired.")
                    }
                }
            }
        } else {
            Text("You don't have order yet!")
        }
        
    }
}

我想要实现的是,只要当前纪元时间超过模型的expireAt 阈值,视图就会自动更新。

实现这一目标的最佳方法是什么?我应该使用Timer 还是ObservableObject,还是两者都用?例如,使用ObservableObject 似乎需要对模型使用Class 而不是Struct,我不确定这是否是我想要实现的目标。

【问题讨论】:

  • 您需要一个ObservableObject 来响应该事件并更新其@Published 属性;使您的视图依赖于该属性。 如何捕获此事件取决于您的特定应用设计。可能是应用程序启动/恢复时设置的计时器

标签: swiftui


【解决方案1】:

例如,您可以创建一个每 1 秒运行一次的计时器,并使用 onReceive 方法更新您的私有状态,如下所示:

class AppConfig: ObservableObject {
    @Published var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
}

struct OrderView: View {
    @EnvironmentObject var rs : RemoteService
    @EnvironmentObject var appConfig : AppConfig

    @State private var showExpiredText: Bool = false

    var body: some View {
        if rs.hasOrder() {
            NavigationView {
                VStack {
                    if showExpiredText {
                        Text("Your order has expired")
                    } else {
                        Text("Your order has not expired.")
                    }
                }
            }
            .onReceive(appConfig.timer) { _ in
               if rs.Order != nil &&  rs.Order!.isExpired() {
                 showExpiredText = true
               } else {
                 showExpiredText = false
               }
            }

        } else {
            Text("You don't have order yet!")
        }
        
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-17
    • 1970-01-01
    • 2023-02-06
    相关资源
    最近更新 更多