【问题标题】:@ObservedObject not publishing changes to View@ObservedObject 不发布对 View 的更改
【发布时间】:2020-10-31 19:24:41
【问题描述】:

我有一个View 和一个Text,它打算根据CountDown()secondsLeft 进行更新:

struct TimerCapsule: View {
    @ObservedObject var countdown = CountDown()
    var body: some View {
        Text("\(self.countdown.secondsLeft)")
            .font(.system(size: 30))
            .foregroundColor(.white)
            .frame(width: 100, height: 40)
            .padding(EdgeInsets(top: 5, leading: 15, bottom: 5, trailing: 15))
            .background(
                Capsule()
                    .fill(Color("Exit"))
                    .opacity(0.7)
            )
            .onAppear{
                print("Start countdown")
                self.countdown.start(from: 30)
            }
            .onDisappear {
                self.countdown.stop()
            }
    }
}

这是下面的CountDown 类。 print("Seconds left: \(self.secondsLeft)") 成功打印 30、29、28 等 - 但是,这在上面的 View 中没有更新。上面的视图中只使用了 1 个实例,所以我不确定为什么它没有反映在上面的 Text("\(self.countdown.secondsLeft)") 中。

计时器:

class CountDown: ObservableObject {
    @Published var secondsLeft = 30
    @ObservedObject var block = Block()
    var timer: Timer!
    func start(from seconds: Int){
        self.secondsLeft = seconds
        print("start timer")
        self.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true){ _ in
            if (self.secondsLeft == 1){
                switch self.block.type {
                case .match:
                    self.block.pass()
                case .pass:
                    self.block.pass()
                default:
                    self.block.delete()
                }
            }
            self.secondsLeft -= 1
            print("Seconds left: \(self.secondsLeft)")
        }
    }
    func stop(){
        self.timer?.invalidate()
    }
}

有什么想法吗?

编辑:

ContentView.swift

struct ContentView: View {
    @ObservedObject var auth = UserAuth()
    var body: some View {
        Group {
            if auth.uid != nil { HomeView(auth: auth) } else { LoginView(auth: auth) }
        }
    }
}

HomeView.swift

struct HomeView: View {
    let auth: UserAuth
    @ObservedObject var block = Block()
    init(auth: UserAuth) {
        self.auth = auth
        UITabBar.appearance().barTintColor = UIColor.orange
        UITabBar.appearance().unselectedItemTintColor = UIColor.white.withAlphaComponent(0.5)
        UITabBar.appearance().autoresizesSubviews = true
    }
    @State var selectedTab = 1
    @ObservedObject var locationManager = LocationManager()
        
    var body: some View {
        ZStack {
            TabView(selection: $selectedTab) {
                Settings(auth: auth)
                .tabItem {
                        Image(systemName: "gear")
                    Text("Settings")
    
                }.tag(0)
                ZStack {
                    MapView(locationManager: locationManager)
                    Color.black.opacity(self.block.status.opacity).animation(nil)
                    VStack {
                    if self.block.type == Type.match || self.block.type == Type.pass {
                        VStack{
                            TimerCapsule()
                        }.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
                        .padding(.top, 20)
                    }
                        Spacer()
                        if self.block.type == Type.create || self.block.type == Type.delete || self.block.type == Type.pass{
                        StatusButton()
                        }
                    }.padding(40)
                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                }.edgesIgnoringSafeArea(.top)
                .tabItem {
                    Image(systemName: "location.circle.fill")
                    Text("Home")
                }.tag(1)
                ProfileView()
                .tabItem {
                    Image(systemName: "person")
                    Text("Profile")
                }.tag(2)
            }.accentColor(Color.white)
            .font(.headline)
        }
    }
}

【问题讨论】:

  • 你能告诉我Block是什么吗?我觉得原因就在那里,因为它在删除与之相关的所有内容后才起作用。
  • 当我将 TimerCapsule() 内容粘贴到 TimerCapsule() 在视图中的位置时 - 倒计时工作...... @Asperi - 所以块不相关
  • 我在视图和模型@Asperi 中删除了Block() 的所有引用

标签: ios swift swiftui


【解决方案1】:

无法重现任何问题。您没有提供足够的信息来编译整个代码,但是如果我们删除对您遗漏的所有内容的引用,我们会得到:

class CountDown: ObservableObject {
    @Published var secondsLeft = 30
    var timer: Timer!
    func start(from seconds: Int){
        self.secondsLeft = seconds
        print("start timer")
        self.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true){ _ in
            // don't know what Block is
            self.secondsLeft -= 1
            print("Seconds left: \(self.secondsLeft)")
        }
    }
    func stop(){
        self.timer?.invalidate()
    }
}

struct ContentView: View {
    @ObservedObject var countdown = CountDown()
    var body: some View {
        Text("\(self.countdown.secondsLeft)")
            .font(.system(size: 30))
            .foregroundColor(.white)
            .frame(width: 100, height: 40)
            .padding(EdgeInsets(top: 5, leading: 15, bottom: 5, trailing: 15))
            .background(
                Capsule()
                    .fill(Color(.black)) // don't know what Exit is
                    .opacity(0.7)
            )
            .onAppear{
                print("Start countdown")
                self.countdown.start(from: 30)
            }
            .onDisappear {
                self.countdown.stop()
            }
    }
}

将其复制并粘贴到一个新的 SwiftUI 项目中,您会看到文本倒计时。

因此,如果有什么东西阻止了这种情况的发生,那是你没有表现出来的东西。

【讨论】:

  • 是的,你是对的,我将 TimerCapsule() 复制粘贴到 ContentView 中,效果很好。但是我不确定问题出在我的HomeView 中(我在上面添加了完整的代码)。我删除了对block 的所有引用,它没有改变任何东西,所以不要认为是那样。
  • 是的,但我根据您提供的代码回答了您提出的问题。是否诚实对待您的代码取决于您。
  • 是的,很抱歉 - 我应该添加完整的代码。不确定是否需要。
猜你喜欢
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
  • 1970-01-01
  • 2020-05-02
  • 1970-01-01
  • 1970-01-01
  • 2020-05-02
  • 1970-01-01
相关资源
最近更新 更多