Tôi đã đưa ra một cách giải quyết để khắc phục vấn đề này. Một cảnh báo, trong khi nó sửa sự thay đổi trong bảng, nó đưa ra một độ trễ trong hoạt hình Tiêu đề Thanh điều hướng, vì vậy bạn được cảnh báo.
Bạn có thể sử dụng TableViewControll của UIKit trong thời gian này cho đến khi Apple sửa đối tượng Danh sách của SwiftUI.
Tóm lại, bạn cần tạo TableViewControll và bọc nó trong UIViewControllRepftimeable để sau đó đưa nó vào chế độ xem SwiftUI của bạn. Hành động điều hướng được thực hiện tốt nhất thông qua phương thức ủy nhiệm didSelectRowAt.
Cập nhật: có vẻ như sự cố đã được giải quyết trong XCode 11.4 mới nhất (tuy nhiên hiện tại có nhiều vấn đề hơn trong môi trường giả lập)
Tôi có một mã đầy đủ ở đây: https://gist.github.com/Rep0se/97d7a97cfd05f42aa597904e6a2cfd3d
//
// UIKitSwiftUITableView.swift
// Table Test
//
// Created on 2020-02-19.
// Note: While this solution fixes Table shifting bug, it introduces Navigation Bar Title bug for a Large Title. Beware.
// LBTATools can be downloaded using Swift Package Manager from: https://github.com/bhlvoong/LBTATools
//
import SwiftUI
import LBTATools
struct UIKitSwiftUITableView: View {
var body: some View {
NavigationView {
UIKitSwiftUIContainer()
}
}
}
struct Restaurante: Hashable {
let name: String
let image: String
}
struct UIKitSwiftUIContainer: View {
let restaurants = [
Restaurante(name: "Joe's Original", image: "house"),
Restaurante(name: "Pheasant Plucker", image: "house.fill"),
Restaurante(name: "Radius", image: "music.house"),
Restaurante(name: "The Ship", image: "music.house.fill")
]
var body: some View {
UIKitTableViewRepresentable(restaurants: restaurants)
.navigationBarTitle("Select a restaurant") // <- UI bug exests for Navigation Bar Title
.edgesIgnoringSafeArea(.all)
}
}
struct UIKitTableViewRepresentable: UIViewControllerRepresentable {
typealias UIViewControllerType = UIViewController
let restaurants: [Restaurante]
init(restaurants: [Restaurante]) {
self.restaurants = restaurants
}
func makeUIViewController(context: UIViewControllerRepresentableContext<UIKitTableViewRepresentable>) -> UIViewController {
UIKitComboTableViewController(restaurants: restaurants)
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<UIKitTableViewRepresentable>) {
}
}
class UIKitComboTableViewController: UITableViewController {
let reuseIdentifier = "reuseIdentifier"
var restaurants: [Restaurante]
init(restaurants: [Restaurante]) {
self.restaurants = restaurants
super.init(style: .insetGrouped)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(TableCell.self, forCellReuseIdentifier: reuseIdentifier)
}
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return restaurants.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as? TableCell {
cell.viewModel.name = restaurants[indexPath.row].name
cell.viewModel.image = restaurants[indexPath.row].image
cell.accessoryType = .disclosureIndicator
return cell
} else {
return UITableViewCell()
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let hostingController = UIHostingController(rootView: UIKitSwiftUIContainer())
show(hostingController, sender: self)
}
}
class TableCell: UITableViewCell {
let viewModel = RestaurantViewModel()
lazy var row = ListRowView(viewModel: viewModel)
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
let hostingController = UIHostingController(rootView: row)
addSubview(hostingController.view)
hostingController.view.fillSuperview()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
struct ListRowView: View {
@ObservedObject var viewModel: RestaurantViewModel
var body: some View {
HStack{
Image("Avatar").renderingMode(.original).padding()
Text(viewModel.name)
.foregroundColor(.black)
Spacer()
}.frame(minHeight: 44)
}
}
class RestaurantViewModel: ObservableObject {
@Published var name = ""
@Published var image = ""
}
struct UIKitSwiftUITableView_Previews: PreviewProvider {
static var previews: some View {
UIKitSwiftUITableView()
}
}