【问题标题】:SwiftUI Timer.publish causing whole screen to refreshSwiftUI Timer.publish 导致整个屏幕刷新
【发布时间】:2020-09-20 02:21:18
【问题描述】:

GIF of Entire Screen Refreshing

我目前正在学习 combine 和 MVVM。我的问题是当我尝试使用 timer.publish 时,最终我要创建一个停止按钮,它会导致整个屏幕刷新而不是我拥有的文本 .onReceive。

我希望有人能给我一些关于我如何错误地使用发布者和观察者的见解。

查看:

import SwiftUI
import Combine

struct ApptCardView: View {

    @ObservedObject var apptCardVM: ApptCardViewModel
    @State var currentDate = Date()
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    var body: some View {
        VStack {
            Text("\(currentDate)")
                .onReceive(timer) { input in
                    self.currentDate = input
                   }
            Picker("Seizure Type", selection: $apptCardVM.typeIndex) {
            ForEach(0..<apptCardVM.typeChoice.count) {
                Text(self.apptCardVM.typeChoice[$0])
            }
        }.pickerStyle(SegmentedPickerStyle())

        }

    }
}

查看模型:

import Foundation
import Combine


class ApptCardViewModel: ObservableObject, Identifiable {

    @Published var appt: ApptEvent
    @Published var typeChoice = ["Quick", "Long", "FullService"]
    @Published var typeIndex: Int = 0



    private var cancellables = Set<AnyCancellable>()

    init(appt: ApptEvent) {
        self.appt = appt
    }

}

【问题讨论】:

    标签: swiftui swiftui-environment


    【解决方案1】:

    如果您只想刷新body的一部分,则将该部分分离到专用的子视图中,例如:

    struct ApptCardView: View {
    
        @ObservedObject var apptCardVM: ApptCardViewModel
    
        var body: some View {
            VStack {
                CurrentDateView()  // << here !!
    
                Picker("Seizure Type", selection: $apptCardVM.typeIndex) {
                ForEach(0..<apptCardVM.typeChoice.count) {
                    Text(self.apptCardVM.typeChoice[$0])
                }
            }.pickerStyle(SegmentedPickerStyle())
    
            }
    
        }
    }
    
    struct CurrentDateView: View {
        @State private var currentDate = Date()
        let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
        var body: some View {
            Text("\(currentDate)")
                .onReceive(timer) { input in
                    self.currentDate = input // << refresh only own body !!
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多