【问题标题】:Instance method 'onReceive(_:perform:)' requires that 'CountdownTimer' conform to 'Publisher'实例方法 'onReceive(_:perform:)' 要求 'CountdownTimer' 符合 'Publisher'
【发布时间】:2022-01-23 07:47:27
【问题描述】:

我目前正在构建一个用户可以创建多个计时器的项目,但是我遇到了以下错误。 “实例方法 'onReceive(_:perform:)' 要求 'CountdownTimer' 符合 'Publisher'”。我只是不知道如何让 Countdown Timer 符合 Publisher。

这是我的计时器对象的代码:

struct CountdownTimer: Identifiable {
  let id = UUID()
  let name: String
  var minutes: Int
  var seconds: Int

  var countdown: Int  {
    let totalTime = seconds + (minutes * 60)
        return totalTime
  }
} 

func timeString(time: Int) -> String {
    return String(format: "%01i:%02i", minutes, seconds)

}
  

class CountdownTimers: ObservableObject {
  @Published var timers = [CountdownTimer]()
}

我的内容视图:

struct ContentView: View {
@Environment(\.presentationMode) var presentationMode
@ObservedObject var countdownTimers = CountdownTimers()

@State private var showingAddSheet = false


let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

var body: some View {
    NavigationView {
        GeometryReader { geometry in
            ZStack {
                Color.pastelGreen
                    .edgesIgnoringSafeArea(.all)
                VStack {
                    ScrollView {
                        ForEach(countdownTimers.timers) { timer in
                            ZStack {
                                CardView()
                                    .overlay(
                                        HStack {
                                            VStack(alignment: .leading) {
                                                Text("\(timer.countdown)")
                                                    .font(.custom("Quicksand-Bold", size: 30))
                                                Text(" \(timer.timeString(time: timer.countdown))")
                                                    .font(.custom("Quicksand-Bold", size: 40))
                                                    .onReceive(timer){ _ in
                                                        if timers.countdown > 0 {
                                                            timers.countdown -= 1
                                                        }
                                                    }

错误发生在 .OnReceive(timer) 行。分钟和秒是在不同的“AddView”上创建的,但我认为该问题与该部分无关。

任何帮助将不胜感激。

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    您正在隐藏名称 timer。它首先出现在这里:

    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    

    然后,稍后,你在这里再次使用它:

    ForEach(countdownTimers.timers) { timer in
    

    Swift 将假定您总是在最近定义的范围内表示 timer,因此当您使用 .onReceive 时,它假定您的意思是来自 ForEachtimer(类型为 @ 987654329@) 而不是前面定义的Timer

    要解决此问题,请在您的 ForEach 中使用不同的名称,并调整您的代码(例如 Text 元素)以使用新名称。

    【讨论】:

    • 谢谢!那行得通!但是我在 -= 行遇到了这个错误。 “变异运算符的左侧是不可变的:'countdown' 是一个 get-only 属性”
    • 是的,这是一个单独的问题——您需要在您的ForEach 中绑定到您的timer(我们现在称之为timerItem)。你可能会做ForEach($countdownTimers.timers) { $timerItem,但它可能需要一些调整(如果是这样,开始一个新问题来解决新问题)。你可以在这里阅读更多相关信息:swiftbysundell.com/articles/bindable-swiftui-list-elements
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-27
    • 2017-01-22
    • 1970-01-01
    相关资源
    最近更新 更多