@ObservedObject не публикует изменения в представлении - PullRequest
0 голосов
/ 11 июля 2020

У меня есть 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 и т.д. c - однако это не обновляется в 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)
        }
    }
}

1 Ответ

0 голосов
/ 11 июля 2020

Невозможно воспроизвести проблему. Вы не предоставили достаточно информации, чтобы позволить скомпилировать весь код, но если мы удалим ссылки на все, что вы упустили, мы получим следующее:

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 и вы увидите, что текст идет в обратном порядке.

Так что, если что-то мешает этому, то вы этого не показали.

...