将observedObject放入List
Posted
技术标签:
【中文标题】将observedObject放入List【英文标题】:put observedObject in List 【发布时间】:2020-01-13 20:00:40 【问题描述】:我从我的 api 获取数据并为它们创建一个类。我可以使用 swifyJSON 正确初始化它们。问题是当我将observedObject 放入List 时,它只能正确显示一次。我改变视图后它会崩溃。它非常强大,因为我的其他具有类似数据结构的列表可以工作。(此视图位于 tabView 中)有人知道我的 getAllNotification() 应该将 view.onAppear() 或 List.onAppear() 放在哪里吗?谢谢!!
class ManagerNotification : Identifiable, ObservableObject
@Published var id = UUID()
var notifyId : Int = 0
var requestId : Int = 0
var requestName: String = ""
var groupName : String = ""
// var imageName: String return name
init(jsonData:JSON)
notifyId = jsonData["notifyId"].intValue
requestId = jsonData["requestId"].intValue
requestName = jsonData["requestName"].stringValue
groupName = jsonData["groupName"].stringValue
import SwiftUI
import SwiftyJSON
struct NotificationView: View
var roles = ["userNotification", "managerNotification"]
@EnvironmentObject var userToken:UserToken
@State var show = false
@State private var selectedIndex = 0
@State var userNotifications : [UserNotification] = [UserNotification]()
@State var managerNotifications : [ManagerNotification] = [ManagerNotification]()
var body: some View
VStack
Picker(selection: $selectedIndex, label: Text(" "))
ForEach(0..<roles.count) (index) in
Text(self.roles[index])
.pickerStyle(SegmentedPickerStyle())
containedView()
Spacer()
.onAppear(perform: getAllNotification)
func containedView() -> AnyView
switch selectedIndex
case 0:
return AnyView(
List(userNotifications) userNotification in
UserNotificationCellView(userNotification: userNotification)
)
case 1:
return AnyView(
List(managerNotifications) managernotification in
ManagerNotificationCellView(managerNotification : managernotification)
.onAppear(perform: getManagerNotification)
)
default:
return AnyView(Text("22").padding(40))
func getAllNotification()
// if (self.userNotifications.count != 0)
// self.userNotifications.removeAll()
//
// I think the crash was in here, because when i don't use removeAll().
// It works fine, but i don't want every times i change to this view. my array will be longer and
// longer
if (self.managerNotifications.count != 0)
self.managerNotifications.removeAll()
NetWorkController.sharedInstance.connectApiByPost(api: "/User/email", params: ["token": "\(self.userToken.token)"])
(jsonData) in
if let result = jsonData["msg"].string
print("eeee: \(result)")
if(result == "you dont have any email")
else if(result == "success get email")
if let searchResults = jsonData["mail"].array
for notification in searchResults
self.userNotifications.append(UserNotification(jsonData: notification))
NetWorkController.sharedInstance.connectApiByPost(api: "/Manager/email", params: ["token": "\(self.userToken.token)"])
(jsonData) in
if let result = jsonData["msg"].string
print("eeee: \(result)")
if(result == "you dont have any email")
else if(result == "success get email")
if let searchResults = jsonData["mail"].array
for notification in searchResults
self.managerNotifications.append(ManagerNotification(jsonData: notification))
func getManagerNotification()
// if (self.managerNotifications.count != 0)
// self.managerNotifications.removeAll()
//
print(self.managerNotifications.count)
NetWorkController.sharedInstance.connectApiByPost(api: "/Manager/email", params: ["token": "\(self.userToken.token)"])
(jsonData) in
if let result = jsonData["msg"].string
print("eeee: \(result)")
if(result == "you dont have any email")
else if(result == "success get email")
if let searchResults = jsonData["mail"].array
for notification in searchResults
self.managerNotifications.append(ManagerNotification(jsonData: notification))
错误信息
仅警告一次:UITableView 被告知要在视图层次结构中布局其可见单元格和其他内容(表格视图或其超级视图之一尚未添加到窗口中)。这可能会在没有准确信息的情况下强制表视图内的视图加载和执行布局(例如,表视图边界、特征集合、布局边距、安全区域插入等),从而导致错误,并且还会由于额外的布局传递而导致不必要的性能开销.在 UITableViewAlertForLayoutOutsideViewHierarchy 处创建一个符号断点,以便在调试器中捕获此问题并查看导致此问题发生的原因,因此如果可能,您可以完全避免此操作,或者将其推迟到表格视图添加到窗口中。原因:'尝试删除第0节,但更新前只有0节'
【问题讨论】:
【参考方案1】:我想你对@State
和@ObservebableObject
的作用感到困惑;它不像 MVC,你用 SwiftUI.View 替换 ViewController,因为它看起来你正在尝试在你的示例中做。相反,视图应该是某个本地@State
和/或外部@ObservedObject
的函数。这更接近于 MVVM,您的 @ObservedObject
类似于 ViewModel,并且视图将重建自身以响应 ObservableObject
上 @Published
属性的变化。
TLDR:将您的获取逻辑移动到 ObservableObject 并使用 @Published 允许视图订阅结果。我这里有一个例子:https://github.com/joshuajhomann/TVMaze-SwiftUI-Navigation
【讨论】:
感谢您的评论,我是 SwiftUI 初学者。我通过将 getAllNotivfication() 放在 NotificationView 的 var body onAppear 中得到了解决方法。它不会再崩溃了。谢谢以上是关于将observedObject放入List的主要内容,如果未能解决你的问题,请参考以下文章
@ObservedObject 更改后 SwiftUI 视图未更新
SwiftUI 不会将状态更新为 @ObservedObject cameraViewModel 对象
核心数据 NSManagedObject - ObservedObjects 未更新