0

我正在尝试将 UITableView 与 UIViewRepresantable 一起使用,它有点工作,但不是真的。某些行放置在错误的位置,或者与其他行重叠,或者添加了额外的填充。即使我设置了自动维度,它似乎也没有使行高适应行的内容。

这是演示:

在此处输入图像描述

这是代码:

import SwiftUI

struct ContentView: View {
    @State var rows : [String] = []
    var listData = ListData()
    
    var body: some View {
        VStack {
            Button(action: {
                self.getDataFromTheServer()
            }) {
               Text("Get 100 entries from the server")
            }
            UIList(rows: $rows)
        }
    }
    
    func getDataFromTheServer() {
        for _ in 1...100 {
            self.rows.append(self.listData.data)
            self.listData.data.append("a")
        }
    }

}

class ListData {
    var data: String = ""
}

class HostingCell: UITableViewCell {
    var host: UIHostingController<AnyView>?
}

struct UIList: UIViewRepresentable {

    @Binding var rows: [String]

    func makeUIView(context: Context) -> UITableView {
        let tableView = UITableView(frame: .zero, style: .plain)
        tableView.dataSource = context.coordinator
        tableView.delegate = context.coordinator
        tableView.register(HostingCell.self, forCellReuseIdentifier: "Cell")
        tableView.rowHeight = UITableView.automaticDimension
        tableView.estimatedRowHeight = UITableView.automaticDimension
        return tableView
    }

    func updateUIView(_ uiView: UITableView, context: Context) {
        DispatchQueue.main.async {
            uiView.reloadData()
        }
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(rows: $rows)
    }

    class Coordinator: NSObject, UITableViewDataSource, UITableViewDelegate {

        @Binding var rows: [String]

        init(rows: Binding<[String]>) {
            self._rows = rows
        }

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

        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

            let tableViewCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! HostingCell

            let view = Text(rows[indexPath.row])
                    .background(Color.blue)
                    .lineLimit(nil)

            // create & setup hosting controller only once
            if tableViewCell.host == nil {
                let hostingController = UIHostingController(rootView: AnyView(view))
                tableViewCell.host = hostingController

                let tableCellViewContent = hostingController.view!
                tableCellViewContent.translatesAutoresizingMaskIntoConstraints = false
                tableViewCell.contentView.addSubview(tableCellViewContent)
                tableCellViewContent.topAnchor.constraint(equalTo: tableViewCell.contentView.topAnchor).isActive = true
                tableCellViewContent.leftAnchor.constraint(equalTo: tableViewCell.contentView.leftAnchor).isActive = true
                tableCellViewContent.bottomAnchor.constraint(equalTo: tableViewCell.contentView.bottomAnchor).isActive = true
                tableCellViewContent.rightAnchor.constraint(equalTo: tableViewCell.contentView.rightAnchor).isActive = true
            } else {
                // reused cell, so just set other SwiftUI root view
                tableViewCell.host?.rootView = AnyView(view)
            }
            tableViewCell.setNeedsLayout()
            return tableViewCell
        }
    }
}
4

2 回答 2

0

UIHostingControllers 自己的大小不是很好,我怀疑这是破坏你的自动布局的原因。在设置控制器的 rootView 后尝试添加:

hostingController.preferredContentSize = hostingController.sizeThatFits()

也就是说,您可能希望完全避免使用 UIHostingController……如果您遇到使用 UITableView 的麻烦,为什么不在 UIKit 中制作单元格呢?或者,如果您需要 SwiftUI 的行,为什么不使用 List 而不是托管 UITableView?

于 2020-07-09T16:16:14.080 回答
0

来自苹果:

感谢您的反馈,已注明。工程部门已确定目前没有解决此问题的计划。

我们建议使用 List,并针对 List 无法提供的任何需求单独提交增强功能。

于 2020-09-07T21:05:30.860 回答