TableView 重新加载在 SwiftUI 中不使用 UIViewRepresentable
TableView Reload Not working with UIViewRepresentable in SwiftUI
收到 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()
}
}
}
我假设 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
}
}
}
收到 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()
}
}
}
我假设 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
}
}
}