Map over UITableViewController

I have a standard UITableViewController and I have added an MKMapKit map neatly on the top half of the screen (and the table in the bottom half).

During runtime, if we scroll through the table records, the map scrolls up as well.

What I wanted to do was have the map static, not scrolling, while I scroll the table.

Any ideas on how to accomplish this, please?

Answered by Scott in 712591022

Indeed UITableViewController isn’t the best choice for the layout you want. Here are some better options:

  1. Keep your existing UITableViewController but make it a child view controller embedded in a top-level container view controller, which will contain both it and the map.
  2. Change your view controller class to plain old UIViewController which will allow you to position both the map and the table view exactly where you want them. You still implement the table data source and delegate as before and there’s a bit more work (setting up an outlet and implementing a few behaviors you may need) but it’s not bad.

I’d suggest trying option 1 first. It’s a cleaner architecture as it separates table-specific logic from map-specific logic. You may find it useful to put the map inside an embedded child view controller too. Then the container view controller is just responsible for coordinating between them rather than having unnecessarily deep knowledge of how they are implemented.

How did you define constraints ?

You should set constraints:

  • mapKit top to safeArea top
  • set mapKit height to half the screen height
  • tableView top to the Mapkit bottom (set vertical spacing).
  • tableView bottom to safeArea bottom

It does not allow me to add constraints (it is greyed out) because the map is now "part" of the UITableViewController

Accepted Answer

Indeed UITableViewController isn’t the best choice for the layout you want. Here are some better options:

  1. Keep your existing UITableViewController but make it a child view controller embedded in a top-level container view controller, which will contain both it and the map.
  2. Change your view controller class to plain old UIViewController which will allow you to position both the map and the table view exactly where you want them. You still implement the table data source and delegate as before and there’s a bit more work (setting up an outlet and implementing a few behaviors you may need) but it’s not bad.

I’d suggest trying option 1 first. It’s a cleaner architecture as it separates table-specific logic from map-specific logic. You may find it useful to put the map inside an embedded child view controller too. Then the container view controller is just responsible for coordinating between them rather than having unnecessarily deep knowledge of how they are implemented.

OK, I did not take care it was a UITableViewController. UITableViewControllers are not really flexible for this.

But you could include the mapKit in the header of the tableView.

Create headerView with:

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let headerView = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 200)) // define the width (probably full screen or tableView.frame.width) and height you need
        // add mapKit inside
}
Map over UITableViewController
 
 
Q