Search code examples
iosuitableviewswiftuinavigationbaruiviewcontrollerrepresentable

Compatibility between SwiftUI's large title navigation bar and UIViewControllerRepresentable UITableViewController


In order to implement swipe to right in SwiftUI List, I am trying to make UIViewControllerRepresentable UITableViewController.
However, it is not compatible with the navigation bar when the displayMode is .large.

I guess, when the scroll moves, it should

  1. Resize the navigation bar.
  2. Adjust the frame of Scrollview or List.

The #2 is not work with my table view, so something needs to be done. And I need your help.

[Images]

enter image description here

  1. First rendering works well.
  2. After scrolling, there is the extra space above the table view
  3. After scroll-to-top with tapping the top of the display, the position is broken.
  4. View Hierarchy after scrolling (fixed after the first rendering)

[Code] to reproduce (After creating a swiftui project from xcode, replace the contents of the ContentView.swift with the code below.)

import SwiftUI

final class TableViewWrapper: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UITableViewController {
        let viewController = UITableViewController()
        viewController.tableView.delegate = context.coordinator
        viewController.tableView.dataSource = context.coordinator

        return viewController
    }

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

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

    class Coordinator: NSObject, UITableViewDataSource, UITableViewDelegate {
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 100
        }

        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
            cell.backgroundColor = .black
            cell.textLabel!.textColor = .white
            cell.textLabel!.text = "Test"

            return cell
        }
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            TableViewWrapper()
                .navigationBarTitle("Nav title", displayMode: .large)
        }
    }
}

Solution

  • I got a solution.

        TableViewWrapper()
            .edgesIgnoringSafeArea(.top)