繁体   English   中英

UITableView 与 UIViewRepresentable 在 SwiftUI

[英]UITableView with UIViewRepresentable in SwiftUI

我正在尝试在 SwiftUI 应用程序中使用UITableView

struct UIList: UIViewRepresentable {

    var rows: [String]

    func makeUIView(context: Context) -> UITableView {
        let collectionView = UITableView(frame: .zero, style: .plain)
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        collectionView.dataSource = context.coordinator
        collectionView.delegate = context.coordinator
        collectionView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
        return collectionView
    }

    func updateUIView(_ uiView: UITableView, context: Context) {
    }

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

    class Coordinator: NSObject, UITableViewDataSource, UITableViewDelegate {

        var rows: [String]

        init(rows: [String]) {
            self.rows = rows
        }

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

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

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

            let view = Text(rows[indexPath.row]).frame(height: 50).background(Color.blue)// UIFactory(appComponent:

            let controller = UIHostingController(rootView: view)

            let tableCellViewContent = controller.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


            return tableViewCell
        }
    }
}

当我快速滚动表格时,单元格内容会在每个单元格的顶部和底部随机填充,知道为什么会发生这种情况吗?

在此处输入图像描述 PS:我知道我可以使用List ,我尝试使用UITableView因为我必须添加多个滑动操作,但List只允许一个滑动操作(删除)

我认为这是由于损坏的重用表视图单元格......(并且可能丢失了主机控制器,因为那里是在堆栈上创建的而不是存储在任何地方)

请在下面找到使用提到的修复程序更正了您的代码。 测试并使用 Xcode 11.2 / iOS 13.2。

这是代码(内联一些注释):

class HostingCell: UITableViewCell { // just to hold hosting controller
    var host: UIHostingController<AnyView>?
}

struct UIList: UIViewRepresentable {

    var rows: [String]

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

    func updateUIView(_ uiView: UITableView, context: Context) {
    }

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

    class Coordinator: NSObject, UITableViewDataSource, UITableViewDelegate {

        var rows: [String]

        init(rows: [String]) {
            self.rows = rows
        }

        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            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])
                    .frame(height: 50).background(Color.blue)

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

                let tableCellViewContent = controller.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
        }
    }
}

UIList本身添加了演示代码 - 也适用于专业模型。

演示

struct TestUIList: View {
    var body: some View {
        UIList(rows: generateRows())
    }

    func generateRows() -> [String] {
        (0..<100).reduce([]) { $0 + ["Row \($1)"] }
    }
}

我运行更新的代码,我在单元格上出现填充损坏,使用 Xcode 13.4.1 和 iOS 15.5 模拟器,知道会发生什么吗?

@Asperi 任何关于如何解决它的建议,将不胜感激,谢谢

在此处打印屏幕

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM