SwiftUI:具有计时器样式的文本在提供的日期更改后不会更新

Posted

技术标签:

【中文标题】SwiftUI:具有计时器样式的文本在提供的日期更改后不会更新【英文标题】:SwiftUI: Text with timer style doesn't update after provided date changes 【发布时间】:2021-02-16 09:41:11 【问题描述】:

我正在使用 SwiftUI 中在 WWDC 2020 中引入的新计时器样式 (Text.DateStyle) 来显示倒计时计时器。这最初有效。但是,只要我的视图模型提供的日期发生更改(例如单击重置),视图就不会更新。计时器确实获得了新日期,但未显示。您可以通过旋转设备/模拟器或按住重置按钮来查看更新的计时器是否正常工作。所以它必须是与视图生命周期相关的东西。

代码:

import SwiftUI
import Combine

class ViewModel: ObservableObject 
    @Published var date: Date = Date().addingTimeInterval(1000)

    func reload() 
        date = Date().addingTimeInterval(1000)
    


struct ContentView: View 
    @StateObject var viewModel = ViewModel()

    var body: some View 
        VStack 
            Text(viewModel.date, style: .timer)
            .padding()
            
            Button("Reset") 
                NotificationCenter.default.post(name: NSNotification.Name("TEST"), object: nil)
            
            Spacer()
        
        .frame(width: 500.0)
        .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("TEST")), perform:  _ in
            viewModel.reload()
        )
    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

这是一个已知问题(如果是,是否有解决方法?)还是我在这里做错了什么?

感谢您的帮助!

【问题讨论】:

【参考方案1】:

似乎是按钮按下效果的错误。您可以使用Text 并添加一个轻击手势并将其设置为按钮,然后它就可以正常工作了。

struct ContentViewTimer: View 
    @StateObject var viewModel = ViewModel()
    
    var body: some View 
        VStack 
            Text(viewModel.date, style: .timer)
                .padding()
            
            Text("Reset") //<-- Here
                .onTapGesture 
                    NotificationCenter.default.post(name: NSNotification.Name("TEST"), object: nil)
                
            
            Spacer()
        
        .frame(width: 500.0)
        .onReceive(NotificationCenter.default.publisher(for: NSNotification.Name("TEST")), perform:  _ in
            viewModel.reload()
        )
    

【讨论】:

【参考方案2】:

只需将.id(UUID()) 修饰符添加到您的VStack,它就会按预期工作。使视图可识别使其在代理值(在您的情况下为日期)更改时重置其状态。

【讨论】:

好吧,我不同意,因为它适用于 macOS,并且当您在 ios 上手动旋转屏幕或执行其他一些视图更新时(就像我写的:点击并打孔重置按钮)。日期更改后似乎只是缺少一次视图刷新。 @JanApotheker 做了更多研究,更新了我的答案。

以上是关于SwiftUI:具有计时器样式的文本在提供的日期更改后不会更新的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - 适合多行文本宽度的内联样式文本背景颜色 SwiftUI

当达到零时停止 SwiftUI 小部件的相对文本字段计数器?

SwiftUI DatePicker 在更改日期时在短日期格式和中日期格式之间跳转

如何在 SwiftUI 中制作斜体圆形样式系统文本?

如何在 SwiftUI 中的文本末尾实现“阅读更多”样式按钮

导航到其他页面后,如何在 SwiftUI 中恢复已发布的计时器?