将 SwiftUI 视图添加到 UITableViewCell contentView

Jos*_*ler 7 uitableview swift swiftui uihostingcontroller

我目前正在尝试在 UIViewControllerRepresentable 中实现 UITableViewController,其中单元格的内容再次是 SwiftUI 视图。我不能使用 SwiftUI 列表,因为我想稍后添加一个 UISearchController。
因为我希望能够将自定义 SwiftUI 视图作为每个单元格的内容,所以我不可能在单元格内没有 SwiftUI 视图的情况下做到这一点。
我当前不起作用的代码如下所示:

class SearchableListCell: UITableViewCell {
    let contentController: UIViewController

    init(withContent content: UIViewController, reuseIdentifier: String) {
        self.contentController = content

        super.init(style: .default, reuseIdentifier: reuseIdentifier)

        self.addSubview(self.contentController.view)
        // Tried also
        // self.contentView.addSubview(self.contentController.view)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

struct SearchableList: UIViewControllerRepresentable {
    let data: [String]

    var viewBuilder: (String) -> ContentView

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIViewController(context: Context) -> UITableViewController {
        return context.coordinator.tableViewController
    }

    func updateUIViewController(_ tableViewController: UITableViewController, context: Context) {
    }

    class Coordinator: NSObject, UITableViewDataSource, UITableViewDelegate {
        var parent: SearchableList

        let tableViewController = UITableViewController()

        init(_ searchableList: SearchableList) {
            self.parent = searchableList

            super.init()

            tableViewController.tableView.dataSource = self
            tableViewController.tableView.delegate = self
        }

        func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }

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

        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let string = self.parent.data[indexPath.row]

            let view = parent.viewBuilder(string)

            let hostingController = UIHostingController(rootView: view)

            let cell = SearchableListCell(withContent: hostingController, reuseIdentifier: "cell")

            // Tried it with and without this line:
            tableViewController.addChild(hostingController)

            return cell
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行它时,例如使用此预览设置:

#if DEBUG
struct SearchableList_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            SearchableList(data: ["Berlin", "Dresden", "Leipzig", "Hamburg"]) { string in
                NavigationLink(destination: Text(string)) { Text(string) }
            }
            .navigationBarTitle("Cities")
        }
    }
}
#endif
Run Code Online (Sandbox Code Playgroud)

我只看到一个带有 4 个明显空单元格的 TableView。不过,在视图层次结构调试器中,我可以看到,每个单元格确实具有 NavigationLink,其中包含 Text 作为子视图,只是不可见。因此,我认为,这与将 UIHostingController 添加为 UITableViewController 的子项有关,但我只是不知道应该在哪里添加它。
目前有没有办法做到这一点?

小智 3

要解决单元格可见性问题,请将 UIHostingController 将 AutoresizingMaskIntoConstraints 属性更改为 false
,然后将其视图框架设置为等于单元格 contentView 边界,或者您可以使用 NSLayoutConstraint,
请检查下面

class SearchableListCell: UITableViewCell {
    let contentController: UIViewController

    init(withContent content: UIViewController, reuseIdentifier: String) {
        self.contentController = content

        super.init(style: .default, reuseIdentifier: reuseIdentifier)


        contentController.view.translatesAutoresizingMaskIntoConstraints = false
        contentController.view.frame = self.contentView.bounds

        self.contentView.addSubview(self.contentController.view)

    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
Run Code Online (Sandbox Code Playgroud)