将ObservedObject放入列表

时间:2020-01-13 20:00:40

标签: swiftui swiftui-list

我从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 个答案:

答案 0 :(得分:0)

我认为您对@State@ObservebableObject的角色感到困惑;它不像MVC,而是用SwiftUI.View替换ViewController,因为在您的示例中您试图这样做。相反,该视图应该是某些本地@State和/或外部@ObservedObject的功能。这更接近MVVM,其中您的@ObservedObject与ViewModel类似,并且视图将根据@PublishedObservableObject属性的更改而重建自身。

TLDR:将获取逻辑移至ObservableObject并使用@Published允许视图订阅结果。我在这里有一个示例:https://github.com/joshuajhomann/TVMaze-SwiftUI-Navigation