Некоторые ячейки UITableView с UIViewRepresantable расположены неправильно - PullRequest
0 голосов
/ 09 июля 2020

Я пытаюсь использовать UITableView с UIViewRepresantable, это вроде работает, но не совсем. Некоторые строки размещаются не в том месте, либо перекрывают другие строки, либо добавляются дополнительные отступы. Кроме того, похоже, не удается адаптировать высоту строки к ее содержимому, даже если я установил automaticDimension.

Вот демонстрация:

введите описание изображения здесь

Вот код:

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
        }
    }
}

1 Ответ

0 голосов
/ 09 июля 2020

UIHostingControllers не очень хороши по размеру, и я подозреваю, что именно это и разрушает вашу автопластинку. Попробуйте добавить это после того, как вы установили rootView контроллера:

hostingController.preferredContentSize = hostingController.sizeThatFits ()

Тем не менее, вы можете полностью отказаться от UIHostingController ... если вы собираетесь проблема с использованием UITableView, почему бы не сделать ячейку тоже в UIKit? Или, если вам нужен SwiftUI для строк, почему бы не использовать List вместо размещения UITableView?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...