【问题标题】:SwiftUI : onAppear method doesn't update StateSwiftUI:onAppear 方法不更新状态
【发布时间】:2021-06-12 18:22:26
【问题描述】:

我是 SwiftUI 的初学者。我在获取一些数据和更新我的状态时遇到问题。我该怎么做?

import SwiftUI

struct ContentView: View {
   @State var todos : TodoListViewModel
        var body: some View {
            NavigationView {
                TodoList(todos: todos)
            }.onAppear(){
                DispatchQueue.main.async {
                    getTodos()
                }
                print(todos.todolist)
            }
       
        }
    
    func getTodos(){
        let url = URL(string:"https://xxx.xxx.xxx/xxx/xx/xxxx")!
        
        TodoWebService().fetchTodos(url: url) { (todoList) in
            self.todos = TodoListViewModel(todolist: todoList!)
            print(todos.todolist)
        }
       
    }
   
}

它只显示我传递给 ContentView 的内容

@main
struct SwiftUITodoAppApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView(todos: TodoListViewModel(todolist: [Todo(id: 1, title: "Title", description: "Description")]))
        }
    }
}

我的 TodoWebService 正在运行。我可以成功打印数据了

TodoWebService.swift

import Foundation

class TodoWebService {
    func fetchTodos(url:URL,completion: @escaping ([Todo]?) -> ()){
        URLSession.shared.dataTask(with: url) { (data,response,error) in
            if let error = error {
                print(error.localizedDescription)
                completion(nil)
            } else if let data = data {
               let todoList = try? JSONDecoder().decode([Todo].self, from: data)
                completion(todoList)
            }
        }.resume()
    }
}

TodoListViewModel.swift

struct TodoListViewModel{
    var todolist : [Todo]
    
    func numberOfRows() -> Int {
        return self.todolist.count
    }
    
    func todoAtIndex(_ index:Int) -> TodoViewModel {
        let todo = self.todolist[index]
        return TodoViewModel(todo: todo)
    }
}

【问题讨论】:

  • 是 TodoListViewModel 类还是结构?
  • TodoListViewModel 是一个结构
  • 分享到ListViewModel
  • 我分享了 TodolistViewModel

标签: ios swift swiftui


【解决方案1】:

我通过将@State 更改为@ObservedObject

TodoListViewModel

class TodoListViewModel : ObservableObject{
   @Published var todolist = [Todo]()
   
    init() {
        getAllTodos()
       }

    
    func numberOfRows() -> Int {
        return self.todolist.count
    }
    
    func todoAtIndex(_ index:Int) -> TodoViewModel {
        let todo = self.todolist[index]
        return TodoViewModel(todo: todo)
    }
    
    func getAllTodos(){
        let url = URL(string:"https://xxx.xxx.xxx/xxx/xxx/xxx")!

         
        URLSession.shared.dataTaskPublisher(for: url)
                    .map { $0.data }
                    .decode(type: [Todo].self, decoder: JSONDecoder())
                    .replaceError(with: [])
                    .eraseToAnyPublisher()
                    .receive(on: DispatchQueue.main)
                    .assign(to: &$todolist)
    }
}

内容视图

struct ContentView: View {
   @ObservedObject var todos : TodoListViewModel
        var body: some View {
            NavigationView {
                TodoList(todos: todos)
            }.onAppear(){
                todos.getAllTodos()
                print(todos.todolist)
            }
       
        }
    
    func getTodos(){
        let url = URL(string:"https://xxx.xxx.xxx/xxx/xx/xxxx")!
        
        TodoWebService().fetchTodos(url: url) { (todoList) in
            self.todos = TodoListViewModel(todolist: todoList!)
            print(todos.todolist)
        }
       
    }
   
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 2021-11-13
    • 2020-06-01
    • 2019-08-07
    • 2017-07-21
    相关资源
    最近更新 更多