【问题标题】:How to put JSON response to a tableview如何将 JSON 响应放入 tableview
【发布时间】:2020-11-23 13:16:16
【问题描述】:

我有一个模型用户并且在那个模型中

    static func getUsers() -> Single<[Users]> {
    let path = API.Path.users.details
    let params: [String: Any] = [
        "utcOffset": TimeZone.current.utcOffset
    ]

    return API.requestMany(path: path, method: .get, parameters: params)
    }

我这样声明

    let sus = [Users]()

在我的 cellForRowAt 我有这个

        Users
        .getUsers()
        .do(onError: { [weak self] error in
            print(error.localizedDescription)
        })
        .do(onSuccess: { [weak self] userNames in
            print(userNames)
            cell.name.text = userNames[indexPath.row].name
        })
        .subscribe()
        .disposed(by: rx.disposeBag)

没有调用该代码,因此我的 tableview 是空的,但是当我尝试将其放入 ViewDidLoad 时,它被调用并触发了我的打印语句 print(userNames)

【问题讨论】:

  • 我正在正确映射数组,我可以在控制台中看到它。
  • 不要在cellForRow 内调用getUsers() 等。相反,在显示您的表格之前,请确保您的数据已准备就绪。准备好数据后,请致电tableView.reloadData()
  • @koen 我应该在哪里调用 getUsers() 我正在练习 MVVM。
  • 可能在viewDidLoad()内。
  • @koen 我试过了,但还是没有出现。是否可以在 tableviewCell 内部调用?

标签: arrays json swift uitableview rx-swift


【解决方案1】:

您的代码没有被调用,因为没有任何东西在调用您放入代码的函数。它在 viewDidLoad 中有效,因为正在调用该函数。

根据您的描述,我希望您的 viewDidLoad() 中的代码看起来像这样

    Users.getUsers()
        .asObservable()
        .bind(to: tableView.rx.items) { tableView, index, user in
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: IndexPath(index: index)) as! MyTableViewCell
            cell.configure(for: user)
            return cell
        }
        .disposed(by: disposeBag)

根据您的 cmets,我了解到您只想将 Rx 用于您的网络调用。在这种情况下,解决方案应如下所示:

final class ExampleViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var tableView: UITableView!

    private var users: [User] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self

        _ = User.getUsers()
            .subscribe(
                onSuccess: { [weak self] in
                    self?.users = $0
                    self?.tableView.reloadData()
                },
                onError: { error in
                    print("handle network error here")
                }
            )
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 44
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        users.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! MyTableViewCell
        cell.configure(for: users[indexPath.row])
        return cell
    }
}

final class MyTableViewCell: UITableViewCell {
    func configure(for user: User) { 
        print("configure your cell here")
    }

}

struct User {
    static func getUsers() -> Single<[User]> { fatalError("Implement me") }
}

【讨论】:

  • 是否可以在tableviewCell内部进行API调用?
  • 当然可以,但是对于生成数据的 api 调用没有意义,这些数据仅在其中一个单元格内提供表格视图。
  • 是的,这是有道理的。如何在 cellForRowAt 中渲染数据我不想删除 extension ViewController: UITableViewDelegate, UITableViewDataSource {...} 以便于设置。
  • 我非常不同意您的“简单设置”评论,但我还是回答了这个问题。
  • 我在这个.bind(to: tableView.rx.items(dataSource: self))有一个错误,错误是Cannot invoke 'items' with an argument list of type '(dataSource: ViewController)'
猜你喜欢
  • 2021-08-30
  • 1970-01-01
  • 2011-08-09
  • 2016-12-24
  • 2020-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-29
相关资源
最近更新 更多