Как возобновить опубликованный таймер в SwiftUI после перехода на другую страницу? - PullRequest
0 голосов
/ 27 марта 2020

В следующем примере Playground пользовательский интерфейс корректно обновляется с текущей датой, однако при переходе от страницы и при возврате таймер не возобновляет тиканье:

  import SwiftUI
  import PlaygroundSupport

  struct MainTabView: View {
    let timer = Timer.publish(every: 1, on: .main, in: .common)

    @State var time = Date()

    var body: some View {
        TabView {
            VStack {
                Text("\(time)").onReceive(self.timer) { self.time = $0 }
            }
            .onAppear { _ = self.timer.connect() }
            .tabItem {
                Text("Page 1")
            }

            Text("Page 2").tabItem {
                Text("Page 2")
            }

            Text("Page 3").tabItem {
                Text("Page 3")
            }
        }
    }
}

PlaygroundPage.current.setLiveView(MainTabView())

Как мне установить таймер начать обновление, когда страница начнет показываться?

Я видел решения, которые включают обертывание Timer в другом классе, но ничего, что нельзя сделать в View.

Я думал, что вызов в connect() в onAppear {} сделает это.

Ответы [ 2 ]

2 голосов
/ 27 марта 2020

Таймер отменяется, когда подписчиков больше нет, а если таймер отменен, его нельзя запустить снова ... поэтому вам нужно либо не отменять таймер, либо заново создавать таймер при каждом выборе первой вкладки.

Здесь возможное решение (случай 1, протестировано с Xcode 11.4)

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

    @State var time = Date()

    var body: some View {
        TabView {
            VStack {
                Text("\(time)")
            }
                .tabItem {
                    Text("Page 1")
            }

            Text("Page 2").tabItem {
                Text("Page 2")
            }

            Text("Page 3").tabItem {
                Text("Page 3")
            }
        }.onReceive(self.timer) { self.time = $0 } // here !!
    }
}
1 голос
/ 27 марта 2020

Реинициализация вашего таймера и даты внутри onAppear будет работать:

struct ContentView: View {
    @State private var timer = Timer.publish(every: 1, on: .main, in: .common)
    @State var time = Date()

    var body: some View {
        TabView {
            VStack {
                Text("\(time)").onReceive(self.timer) { self.time = $0 }
            }
            .onAppear(perform: {
                self.time = Date()
                self.timer = Timer.publish(every: 1, on: .main, in: .common)
                _ = self.timer.connect()
            })
            .tabItem {
                Text("Page 1")
            }

            Text("Page 2").tabItem {
                Text("Page 2")
            }

            Text("Page 3").tabItem {
                Text("Page 3")
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...