swift 如何在每天午夜重置Bool值

sxissh06  于 2024-01-05  发布在  Swift
关注(0)|答案(2)|浏览(195)

我想要一个布尔值,每天午夜都变成真,有人知道我怎么能做到这一点。这是我到目前为止尝试的代码。我一直得到这些错误:
类型“()”不能符合“View”

泛型结构“ObservedObject”要求"ContentView.Daily“符合”ObservableObject“

  1. import SwiftUI
  2. import Foundation
  3. struct ContentView: View {
  4. class Daily: ObservableObject {
  5. @Published var timedbool: Bool = false
  6. private var timer: Timer?
  7. init(){
  8. scheduleDailyReset()
  9. }
  10. private func scheduleDailyReset(){
  11. let calendar = Calendar.current
  12. if let tomorrow = calendar.date(byAdding: .day, value: 1, to: calendar.startOfDay(for: Date())) {
  13. let timeInterval = tomorrow.timeIntervalSinceNow
  14. timer = Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(setBool), userInfo: nil, repeats: false)
  15. }
  16. }
  17. @objc func setBool() {
  18. timedbool = true
  19. scheduleDailyReset()
  20. }
  21. func getBool() -> Bool {
  22. return timedbool
  23. }
  24. }
  25. @State var daily = Daily()
  26. @State var dailyreset: Bool = daily.getBool()
  27. var body: some View {
  28. NavigationView {
  29. VStack{
  30. if dailyreset{
  31. navig2 = true
  32. }

字符串
我试着用一个函数来做每日重置,然后用另一个函数来返回重置bool值,但它不符合View。

n3h0vuf2

n3h0vuf21#

首先,你的代码有几个问题:
1.对于daily,使用@StateObject而不是@State,因为它是一个可观察的对象,而不是结构。
1.你不能像这样把不产生视图的swift代码放在你的body函数中。如果你想做一些计算,根据你的需要把它们放在onAppearonChange(of:)视图修饰符或类似的东西中。
但实际的问题是,你需要安排一个后台任务,以便在应用程序可能不运行时运行代码,在你的情况下是在午夜。
以下是相关文档的指针:
https://developer.apple.com/documentation/backgroundtasks
最后一点:
我建议你审查你的要求,你真的需要在那个时候运行代码,或者它是足够的重新评估,如果它是一个新的一天,一旦应用程序被用户再次启动,这将是简单得多。

mf98qq94

mf98qq942#

你的计时器没问题。
你的代码中有几个问题:
1.将class Daily代码移到顶层。这将删除@ObservableObject错误。
1.将@State var daily更改为@StateObject。这将使@ObservableObject正确更新。
1.不要将函数getBool()@State一起使用。直接使用@Published var timedbool,就像使用daily.timedbool一样。
1.在body navig2 = true的行中,你返回了一个Bool,而你应该返回一个View。你需要在这里放一个view。
这将是我的改变:

  1. import SwiftUI
  2. class Daily: ObservableObject {
  3. @Published var timedbool: Bool = false
  4. private var timer: Timer?
  5. init() {
  6. scheduleDailyReset()
  7. }
  8. private func scheduleDailyReset() {
  9. let calendar = Calendar.current
  10. guard let tomorrow = calendar.date(byAdding: .day, value: 1, to: calendar.startOfDay(for: .now)) else {
  11. // guard let tomorrow = calendar.date(byAdding: .second, value: 5, to: .now) else { // use this instead to test
  12. print("There's no tomorrow.")
  13. return
  14. }
  15. let timeInterval = tomorrow.timeIntervalSinceNow
  16. timer = Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(setBool), userInfo: nil, repeats: false)
  17. print("timer: \(timer?.fireDate)")
  18. }
  19. @objc func setBool() {
  20. timedbool = true
  21. scheduleDailyReset()
  22. }
  23. }
  24. struct ContentView: View {
  25. @StateObject var daily = Daily()
  26. var body: some View {
  27. VStack {
  28. Button("Confirm") {
  29. daily.timedbool = false // set @Published var
  30. }
  31. .disabled(!daily.timedbool) // use @Published var
  32. }
  33. .padding()
  34. .onChange(of: daily.timedbool) { bool in // use @Published var
  35. print("timed bool set to \(bool)")
  36. }
  37. }
  38. }

字符串
请注意,带有按钮的视图只是如何在视图中获取和设置timedbool的示例。
有一个替代的fireDate定义,所以你不必熬夜看它是否有效。
我更喜欢在这里使用guard语句来展开可选的Date,以避免缩进。

展开查看全部

相关问题