TableView 重新加载不适用于 SwiftUI 中的 UIViewRepresentable
Posted
技术标签:
【中文标题】TableView 重新加载不适用于 SwiftUI 中的 UIViewRepresentable【英文标题】:TableView Reload Not working with UIViewRepresentable in SwiftUI 【发布时间】:2020-08-06 14:09:26 【问题描述】:在收到 API 响应后,我正在尝试重新加载 tableView。
TableView 重新加载不会调用cellForRowAt
,因为它最初是用空项目初始化的。我添加了复制问题所需的最少代码。
UIViewRepresentable
的代码
import SwiftUI
import UIKit
struct UIListView: UIViewRepresentable
@Binding var reload: Bool
var items: [String]
private let tableView = UITableView()
func makeUIView(context: Context) -> UITableView
print("*************** make")
tableView.dataSource = context.coordinator
return tableView
func updateUIView(_ uiView: UITableView, context: Context)
print("*************** update", items.count)
print("********* RELOAD", reload)
if reload
DispatchQueue.main.async
// uiView.reloadData()
// tableView.reloadData()
context.coordinator.reload()
func makeCoordinator() -> Coordinator
Coordinator(self)
extension UIListView
final class Coordinator: NSObject, UITableViewDataSource, UITableViewDelegate
private var parent: UIListView
init(_ parent: UIListView)
self.parent = parent
func reload()
parent.tableView.reloadData()
//MARK: UITableViewDataSource Methods
func numberOfSections(in tableView: UITableView) -> Int
return 1
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return parent.items.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
print("*********Cell for row at")
let cell = UITableViewCell()
cell.textLabel?.text = parent.items[indexPath.row]
return cell
CustomListView 和 ViewModel 的代码
struct CustomListView: View
@ObservedObject var model = VM()
var body: some View
print("******* BODY")
return UIListView(reload: $model.reload, items: model.items)
.onAppear
model.fetchData()
class VM: ObservableObject
@Published var reload = false
var items = [String]()
func fetchData()
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0)
self.items = ["asdas", "asdasdas"]
self.reload.toggle()
【问题讨论】:
【参考方案1】:我假设 UITableView
成员刚刚重新创建,因为它是成员,而是如下使用
使用 Xcode 12 / ios 14 测试
struct CustomListView: View
@StateObject var model = VM()
var body: some View
print("******* BODY")
return UIListView(reload: $model.reload, items: $model.items)
.onAppear
model.fetchData()
class VM: ObservableObject
@Published var reload = false
var items = [String]()
func fetchData()
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0)
self.items = ["asdas", "asdasdas"]
self.reload.toggle()
struct UIListView: UIViewRepresentable
@Binding var reload: Bool
@Binding var items: [String]
func makeUIView(context: Context) -> UITableView
print("*************** make")
let tableView = UITableView()
tableView.dataSource = context.coordinator
return tableView
func updateUIView(_ tableView: UITableView, context: Context)
print("*************** update", items.count)
print("********* RELOAD", reload)
if reload
DispatchQueue.main.async
tableView.reloadData()
func makeCoordinator() -> Coordinator
Coordinator(self)
extension UIListView
final class Coordinator: NSObject, UITableViewDataSource, UITableViewDelegate
private var parent: UIListView
init(_ parent: UIListView)
self.parent = parent
//MARK: UITableViewDataSource Methods
func numberOfSections(in tableView: UITableView) -> Int
return 1
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return parent.items.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
print("*********Cell for row at")
let cell = UITableViewCell()
cell.textLabel?.text = parent.items[indexPath.row]
return cell
【讨论】:
它对你有用吗?它在 Xcode beta 3 上对我不起作用,已经尝试过你提到的方式。 很好用。你有什么解释为什么只使用 reload as Binding 不起作用?items
是值和结构的一部分,所以Coordinator
init 只是复制空并存储它。绑定允许访问可更新的数据存储。
现在这对我来说很有意义,这意味着如果我删除重新加载绑定,它应该仍然可以工作。以上是关于TableView 重新加载不适用于 SwiftUI 中的 UIViewRepresentable的主要内容,如果未能解决你的问题,请参考以下文章
使用 DirtiesContext 注释重新加载 Spring 应用程序不适用于嵌套类
然后在 Promisekit 中重新加载 tableview