Wrapped UITableViewController sometimes doesn't select row correctly

Viewed 231

I'm embedding a UITableViewController in a swiftUI app, so I've made a class that conforms to UIViewControllerRepresentable. When I put the table into editing mode, a row will occasionally be completely unselectable in the simulator. Can someone provide any tips on how to debug / figure out what might be going wrong?

This is a screen capture of what I'm seeing: Screen recording of buggy behavior

Here's the wrapped table:

import SwiftUI

final class CommentsTableViewWrapper: UIViewControllerRepresentable {
    // MARK: Properties and initializer
    let post: String
    var comments: [String]
    @Binding var isEditing: Bool

    var vc: UITableViewController?

    init(_ comments: [String], post: String, isEditing: Binding<Bool>) {
        self.comments = comments
        self.post = post
        self._isEditing = isEditing
    }

    // MARK: UIViewControllerRepresentable
    typealias UIViewControllerType = UITableViewController

    func makeUIViewController(context: Context) -> UITableViewController {
        let tvc = UITableViewController()
        tvc.tableView.delegate = context.coordinator
        tvc.tableView.dataSource = context.coordinator

        tvc.tableView.rowHeight = UITableView.automaticDimension
        tvc.tableView.estimatedRowHeight = UITableView.automaticDimension
        tvc.tableView.separatorStyle = .none
        tvc.tableView.allowsSelection = false
        tvc.tableView.allowsSelectionDuringEditing = true
        tvc.tableView.allowsMultipleSelectionDuringEditing = true

        self.vc = tvc
        return tvc
    }

    func updateUIViewController(_ uiViewController: UITableViewController, context: Context) {
        uiViewController.tableView.reloadData()
        uiViewController.setEditing(isEditing, animated: true)
    }

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

    // MARK: - Coordinator
    class Coordinator: NSObject, UITableViewDataSource, UITableViewDelegate {

        // MARK: Properties and initializer
        private let parent: CommentsTableViewWrapper

        init(_ parent: CommentsTableViewWrapper) {
            self.parent = parent
        }

        // MARK: UITableViewDelegate and DataSource methods
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return parent.comments.count
        }

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

            return createCommentCell(indexPath, tableView)
        }

        func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
            UITableView.automaticDimension
        }

        var cellHeights = [IndexPath: CGFloat]()

        func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
            cellHeights[indexPath] = cell.frame.size.height
        }

        func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
            return cellHeights[indexPath] ?? UITableView.automaticDimension
        }

        // MARK: - Private helpers
        fileprivate func createCommentCell(_ indexPath: IndexPath, _ tableView: UITableView) -> UITableViewCell {
            let comment = parent.comments[indexPath.row]
            let cell = tableView.dequeueReusableCell(withIdentifier: "DebugCell") ?? UITableViewCell(style: .subtitle, reuseIdentifier: "DebugCell")

            cell.textLabel!.numberOfLines = 0
            cell.textLabel!.lineBreakMode = .byCharWrapping
            cell.textLabel!.text = comment
            return cell
        }
    }
}

This is the swiftUI view that embeds it:

struct ContentView: View {
    @State var isEditing = false

    var body: some View {
        NavigationView {
        CommentsTableViewWrapper(["Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1", "Test2", "Test3","Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1", "Test2", "Test3","Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1", "Test2", "Test3","Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1", "Test2", "Test3","Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1Test1", "Test2", "Test3"], post: "This is the post text!", isEditing: self.$isEditing)
            .navigationBarTitle("Nav title", displayMode: .inline)
            .navigationBarItems(trailing: Button("Edit") {
                self.isEditing = true
            })
        }
    }
}
0 Answers
Related