【问题标题】:How can I get UNNotificationRequest array using for loop to populate SwiftUI List view?如何使用 for 循环获取 UNNotificationRequest 数组以填充 SwiftUI 列表视图?
【发布时间】:2021-02-08 05:48:02
【问题描述】:

我想简单地获取计划的本地通知列表并使用forEach 填充 SwiftUI 列表。我相信它应该像我在下面所做的那样工作,但是数组总是空的,因为它似乎是在 for 循环完成之前使用的。我尝试了带有完成处理程序的getNotifications() 函数,也作为返回函数,但两种方法仍然不起作用。我怎样才能等到 for 循环完成来填充我的列表?或者如果有其他方法可以做到这一点,请告诉我,谢谢。

var notificationArray = [UNNotificationRequest]()

func getNotifications() {
        
print("getNotifications")
        center.getPendingNotificationRequests(completionHandler: { requests in
            for request in requests {
                print(request.content.title)
                notificationArray.append(request)
            }
        })

}

struct ListView: View {

var body: some View {
    
    NavigationView {
    List {
        ForEach(notificationArray, id: \.content) { notification in

            HStack {
                VStack(alignment: .leading, spacing: 10) {
                    let notif = notification.content
                    Text(notif.title)
                    Text(notif.subtitle)
                    .opacity(0.5)
            }
                    }
        
    }

}
 .onAppear() {
        getNotifications()
    }
}
}

更新:

这是我如何添加新通知并再次致电getNotifications。我希望列表在创建新数组时动态更新。打印到控制台显示getNotifications 工作正常,并且新数组包含添加的通知。

Section {
                Button(action: {
                    print("Adding Notification: ", title, bodyText, timeIntValue[previewIndex])
                    addNotification(title: title, bodyText: bodyText, timeInt: timeIntValue[previewIndex])
                    showDetail = false
                    self.vm.getNotifications()
                }) {
                    Text("Save Notification")
                }
            }.disabled(title.isEmpty || bodyText.isEmpty)

【问题讨论】:

  • 我试过了,还使用了 group.enter .leave 等,但这些都没有用

标签: ios swiftui unnotificationrequest


【解决方案1】:

视图未观察到您的全局notificationArray。它应该是动态属性...可能的解决方案是将其包装到 ObservableObject 视图模型中。

这是一个解决方案的演示:

class ViewModel: ObservableObject {
  @Published var notificationArray = [UNNotificationRequest]()

  func getNotifications() {
        
    print("getNotifications")
        center.getPendingNotificationRequests(completionHandler: { requests in
            var newArray = [UNNotificationRequest]()
            for request in requests {
                print(request.content.title)
                newArray.append(request)
            }
            DispatchQueue.main.async {
              self.notificationArray = newArray
            }
        })
  }
}

struct ListView: View {
  @ObservedObject var vm = ViewModel()
//@StateObject var vm = ViewModel()    // << for SwiftUI 2.0

  var body: some View {
    
    NavigationView {
      List {
        ForEach(vm.notificationArray, id: \.content) { notification in
            HStack {
                VStack(alignment: .leading, spacing: 10) {
                    let notif = notification.content
                    Text(notif.title)
                    Text(notif.subtitle)
                    .opacity(0.5)
                }
            }
      }
   }
   .onAppear() {
        self.vm.getNotifications()
    }
 }
}

【讨论】:

  • 这效果更好,并在我打开应用程序时显示列表,但不幸的是,当我添加新通知并再次调用 self.vm.getNotifications() 时,它不会更新我的列表以反映这一点。我错过了什么吗?我将@StateObject var vm = ViewModel() 添加到每个需要它的View 中。添加我如何向问题添加通知。
  • 不,如果它是同一个视图模型,那么它应该在某个根视图中创建一次,并注入层次结构子视图作为环境对象。然后所有人都将使用相同的实例并在一个地方更新将更新所有依赖视图。
  • 我将 stateObject 更改为环境对象,如下所示:@EnvironmentObject var vm: ViewModel 但现在当列表填充Thread 1: Fatal error: No ObservableObject of type ViewModel found. A View.environmentObject(_:) for ViewModel may be missing as an ancestor of this view. atm 时出现错误,层次结构的工作原理是我的主要ContentView 包含ListView 但是仅当getNotifications 返回非空notificationsArray 时才显示它,然后我希望ListView 使用数组并填充列表。在此之后我希望我应该能够更新数组和列表 shld
  • 好的,我现在明白了,并且开始工作了。在我的子视图中,我添加了environmentObject 变量:@EnvironmentObject var vm: ViewModel,然后在我调用子视图时在我的主视图中这样做:ListView().environmentObject(vm) 现在我可以调用vm.getNotifications(),并且列表会相应更新。
猜你喜欢
  • 2021-12-25
  • 1970-01-01
  • 2014-04-09
  • 2016-02-23
  • 1970-01-01
  • 2023-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多