#swift #swiftui #timer #uiappearance
#быстрый #свифтуи #таймер #внешний вид
Вопрос:
У меня есть представление, в котором я показываю документ (в основном фоновое изображение с несколькими смайликами на нем). В моем представлении навигации есть несколько документов, и всякий раз, когда я загружаю документ (создается представление документа), я хотел бы запустить таймер (загрузить сохраненное время из пользовательских настроек, если оно существует), чтобы измерить, сколько времени я потратил на работу. Когда я перехожу на другой документ, я хотел бы отменить таймер предыдущих документов (и сохранить время в настройках пользователя) и запустить новый из текущего документа.
Вид:
struct DocumentView: View { @ObservedObject var document: DocumentViewModel init(documentViewModel: DocumentViewModel) { self.document = documentViewModel } var body: some View { VStack { //some UI code here createTimeTracker() }.onAppear{ //not called every time view is shown :( document.startTimeTracker() } .onDisappear{ document.stopTimeTracker() } } private func createTimeTracker() -gt; some View { return HStack{ Label("(document.timeSpent) s", systemImage: "timer") } }
Документ:
class DocumentViewModel: ObservableObject, Equatable, Hashable, Identifiable { let id: UUID @Published var timeSpent: Int = 0 init(id:UUID = UUID()) { self.id = id //some code here } func startTimeTracker(){ timeSpent = UserDefaults.standard.integer(forKey: "DocumentViewModel.(id).timeSpent") print("Starting/Resuming timer at (timeSpent) s") timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect() subscription = timer?.sink(receiveValue: { _ in self.updateTimeSpent() }) } func stopTimeTracker(){ print("Stopping timer at (timeSpent) s") UserDefaults.standard.set(timeSpent, forKey: "DocumentViewModel.(id).timeSpent") self.timer?.upstream.connect().cancel() } func updateTimeSpent(){ timeSpent = 1 }
Создание представления
NavigationLink(destination: DocumentView(documentViewModel: document))
Проблема Я понял, что onAppear вызывается не каждый раз, когда отображается представление документа. Поэтому у меня есть несоответствия в отношении моего таймера при переключении с одного документа на другой(onAppear, похоже, не вызывается). Есть ли лучший способ реализовать поведение onAppear/onDisappear? Использование TimerPublisher является обязательным требованием, проблема заключается в вызове вызовов методов, определенных в onAppear/onDisappear, а не в измерении времени или чем-то еще.
Любой вклад очень ценится!
Комментарии:
1. Не используйте его в представлении (срок службы SwiftUI не подходит для этого)-переосмыслите его использование на уровне модели/представления-модели.
2. что вы имеете в виду под «этим»? Не могли бы вы описать это немного яснее? Спасибо!
3. Почему бы просто не отслеживать время начала и окончания как текущую дату? продолжительность затраченного времени-это просто «интервал времени» между двумя датами. Вам не понадобится таймер, и это будет гораздо более простая реализация. Таймеры больше предназначены для того, чтобы что-то происходило относительно регулярно, и не очень хорошо подходят для чего-то подобного.
4. К сожалению, использование TimerPublisher является обязательным требованием. Использование таймера также не является проблемой здесь, это больше для того, чтобы действовать при появлении/исчезновении представления.